@yuno-payments/dashboard-embed-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/package.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# @yuno-payments/dashboard-embed-sdk
|
|
2
|
+
|
|
3
|
+
Lightweight SDK for embedding the Yuno Dashboard via iframe. Zero dependencies — uses only DOM APIs.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @yuno-payments/dashboard-embed-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { YunoDashboard } from "@yuno-payments/dashboard-embed-sdk";
|
|
15
|
+
|
|
16
|
+
const sdk = new YunoDashboard({
|
|
17
|
+
baseUrl: "https://dashboard.y.uno",
|
|
18
|
+
container: document.getElementById("dashboard")!,
|
|
19
|
+
token: "your-jwt-token",
|
|
20
|
+
theme: {
|
|
21
|
+
tokens: { primary: "#134AC3" },
|
|
22
|
+
typography: { fontFamily: "'Inter', sans-serif", fontUrl: "https://fonts.googleapis.com/css2?family=Inter" },
|
|
23
|
+
mode: "light",
|
|
24
|
+
styles: ".yuno-card { border-radius: 8px; }",
|
|
25
|
+
},
|
|
26
|
+
lang: "en",
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Navigate
|
|
30
|
+
sdk.navigate("/connections");
|
|
31
|
+
|
|
32
|
+
// Update theme
|
|
33
|
+
sdk.setTheme({ tokens: { primary: "#FF0000" } });
|
|
34
|
+
|
|
35
|
+
// Change language
|
|
36
|
+
sdk.setLang("es");
|
|
37
|
+
|
|
38
|
+
// Set auth token (reloads iframe)
|
|
39
|
+
sdk.setToken("new-jwt-token");
|
|
40
|
+
|
|
41
|
+
// Cleanup
|
|
42
|
+
sdk.destroy();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
### `new YunoDashboard(config)`
|
|
48
|
+
|
|
49
|
+
| Option | Type | Required | Description |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| `baseUrl` | `string` | Yes | Dashboard base URL |
|
|
52
|
+
| `container` | `HTMLElement` | Yes | Element to mount the iframe |
|
|
53
|
+
| `token` | `string` | No | JWT auth token |
|
|
54
|
+
| `theme` | `DashboardTheme` | No | Initial theme configuration |
|
|
55
|
+
| `lang` | `string` | No | Language code (default: `"en"`) |
|
|
56
|
+
|
|
57
|
+
### Methods
|
|
58
|
+
|
|
59
|
+
- **`setTheme(theme)`** — Update colors, typography, mode, or component styles
|
|
60
|
+
- **`setLang(lang)`** — Change display language
|
|
61
|
+
- **`setToken(token)`** — Set auth token (reloads iframe)
|
|
62
|
+
- **`navigate(path)`** — Navigate to a dashboard route
|
|
63
|
+
- **`destroy()`** — Remove iframe and clean up event listeners
|
|
64
|
+
|
|
65
|
+
## Development
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install
|
|
69
|
+
npm run build # Build with tsup
|
|
70
|
+
npm run dev # Watch mode
|
|
71
|
+
npm run type-check # TypeScript check
|
|
72
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
interface ThemeColors {
|
|
2
|
+
primary: string;
|
|
3
|
+
primaryForeground: string;
|
|
4
|
+
secondary: string;
|
|
5
|
+
secondaryForeground: string;
|
|
6
|
+
background: string;
|
|
7
|
+
foreground: string;
|
|
8
|
+
muted: string;
|
|
9
|
+
mutedForeground: string;
|
|
10
|
+
accent: string;
|
|
11
|
+
accentForeground: string;
|
|
12
|
+
destructive: string;
|
|
13
|
+
destructiveForeground: string;
|
|
14
|
+
border: string;
|
|
15
|
+
input: string;
|
|
16
|
+
ring: string;
|
|
17
|
+
surface: string;
|
|
18
|
+
card: string;
|
|
19
|
+
cardForeground: string;
|
|
20
|
+
popover: string;
|
|
21
|
+
popoverForeground: string;
|
|
22
|
+
success: string;
|
|
23
|
+
warning: string;
|
|
24
|
+
info: string;
|
|
25
|
+
}
|
|
26
|
+
interface ThemeTypography {
|
|
27
|
+
fontFamily: string;
|
|
28
|
+
fontUrl: string;
|
|
29
|
+
}
|
|
30
|
+
interface DashboardTheme {
|
|
31
|
+
tokens?: Partial<ThemeColors>;
|
|
32
|
+
typography?: Partial<ThemeTypography>;
|
|
33
|
+
mode?: "light" | "dark";
|
|
34
|
+
styles?: string;
|
|
35
|
+
}
|
|
36
|
+
interface YunoDashboardConfig {
|
|
37
|
+
baseUrl: string;
|
|
38
|
+
container: HTMLElement;
|
|
39
|
+
token?: string;
|
|
40
|
+
theme?: DashboardTheme;
|
|
41
|
+
lang?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
declare class YunoDashboard {
|
|
45
|
+
private iframe;
|
|
46
|
+
private baseUrl;
|
|
47
|
+
private ready;
|
|
48
|
+
private queue;
|
|
49
|
+
private messageHandler;
|
|
50
|
+
private initialTheme?;
|
|
51
|
+
private initialLang?;
|
|
52
|
+
constructor(config: YunoDashboardConfig);
|
|
53
|
+
setTheme(theme: DashboardTheme): void;
|
|
54
|
+
setLang(lang: string): void;
|
|
55
|
+
setToken(token: string): void;
|
|
56
|
+
navigate(path: string): void;
|
|
57
|
+
destroy(): void;
|
|
58
|
+
private post;
|
|
59
|
+
private flush;
|
|
60
|
+
private onReady;
|
|
61
|
+
private buildSrc;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { type DashboardTheme, type ThemeColors, type ThemeTypography, YunoDashboard, type YunoDashboardConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// src/yuno-dashboard.ts
|
|
2
|
+
var YunoDashboard = class {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.ready = false;
|
|
5
|
+
this.queue = [];
|
|
6
|
+
this.baseUrl = config.baseUrl;
|
|
7
|
+
this.initialTheme = config.theme;
|
|
8
|
+
this.initialLang = config.lang;
|
|
9
|
+
this.iframe = document.createElement("iframe");
|
|
10
|
+
this.iframe.style.width = "100%";
|
|
11
|
+
this.iframe.style.height = "100%";
|
|
12
|
+
this.iframe.style.border = "none";
|
|
13
|
+
this.iframe.title = "Yuno Dashboard";
|
|
14
|
+
this.iframe.src = this.buildSrc(config.token);
|
|
15
|
+
this.messageHandler = (e) => {
|
|
16
|
+
if (e.data?.action === "ready" && e.origin === this.baseUrl) {
|
|
17
|
+
this.onReady();
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
window.addEventListener("message", this.messageHandler);
|
|
21
|
+
config.container.appendChild(this.iframe);
|
|
22
|
+
}
|
|
23
|
+
setTheme(theme) {
|
|
24
|
+
if (theme.tokens || theme.typography) {
|
|
25
|
+
const themePayload = {};
|
|
26
|
+
if (theme.tokens) themePayload.colors = theme.tokens;
|
|
27
|
+
if (theme.typography) themePayload.typography = theme.typography;
|
|
28
|
+
this.post({ action: "setTheme", theme: themePayload });
|
|
29
|
+
}
|
|
30
|
+
if (theme.mode) {
|
|
31
|
+
this.post({ action: "setMode", mode: theme.mode });
|
|
32
|
+
}
|
|
33
|
+
if (theme.styles !== void 0) {
|
|
34
|
+
this.post({ action: "setComponentStyles", css: theme.styles });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
setLang(lang) {
|
|
38
|
+
this.post({ action: "setLang", lang });
|
|
39
|
+
}
|
|
40
|
+
setToken(token) {
|
|
41
|
+
this.ready = false;
|
|
42
|
+
this.iframe.src = this.buildSrc(token);
|
|
43
|
+
}
|
|
44
|
+
navigate(path) {
|
|
45
|
+
this.post({ action: "navigate", path });
|
|
46
|
+
}
|
|
47
|
+
destroy() {
|
|
48
|
+
window.removeEventListener("message", this.messageHandler);
|
|
49
|
+
this.iframe.remove();
|
|
50
|
+
this.queue = [];
|
|
51
|
+
this.ready = false;
|
|
52
|
+
}
|
|
53
|
+
post(message) {
|
|
54
|
+
if (this.ready && this.iframe.contentWindow) {
|
|
55
|
+
this.iframe.contentWindow.postMessage(message, this.baseUrl);
|
|
56
|
+
} else {
|
|
57
|
+
this.queue.push(message);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
flush() {
|
|
61
|
+
const pending = this.queue.splice(0);
|
|
62
|
+
for (const message of pending) {
|
|
63
|
+
if (this.iframe.contentWindow) {
|
|
64
|
+
this.iframe.contentWindow.postMessage(message, this.baseUrl);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
onReady() {
|
|
69
|
+
this.ready = true;
|
|
70
|
+
if (this.initialTheme) {
|
|
71
|
+
this.setTheme(this.initialTheme);
|
|
72
|
+
}
|
|
73
|
+
if (this.initialLang) {
|
|
74
|
+
this.setLang(this.initialLang);
|
|
75
|
+
}
|
|
76
|
+
this.flush();
|
|
77
|
+
}
|
|
78
|
+
buildSrc(token) {
|
|
79
|
+
const params = new URLSearchParams({
|
|
80
|
+
embed: "true",
|
|
81
|
+
theme: "light",
|
|
82
|
+
lang: this.initialLang ?? "en"
|
|
83
|
+
});
|
|
84
|
+
if (token) params.set("token", token);
|
|
85
|
+
return `${this.baseUrl}/connections?${params.toString()}`;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
export {
|
|
89
|
+
YunoDashboard
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/yuno-dashboard.ts"],"sourcesContent":["import type { DashboardTheme, YunoDashboardConfig } from \"./types\";\n\nexport class YunoDashboard {\n private iframe: HTMLIFrameElement;\n private baseUrl: string;\n private ready = false;\n private queue: Record<string, unknown>[] = [];\n private messageHandler: (e: MessageEvent) => void;\n private initialTheme?: DashboardTheme;\n private initialLang?: string;\n\n constructor(config: YunoDashboardConfig) {\n this.baseUrl = config.baseUrl;\n this.initialTheme = config.theme;\n this.initialLang = config.lang;\n\n this.iframe = document.createElement(\"iframe\");\n this.iframe.style.width = \"100%\";\n this.iframe.style.height = \"100%\";\n this.iframe.style.border = \"none\";\n this.iframe.title = \"Yuno Dashboard\";\n this.iframe.src = this.buildSrc(config.token);\n\n this.messageHandler = (e: MessageEvent) => {\n if (e.data?.action === \"ready\" && e.origin === this.baseUrl) {\n this.onReady();\n }\n };\n window.addEventListener(\"message\", this.messageHandler);\n\n config.container.appendChild(this.iframe);\n }\n\n setTheme(theme: DashboardTheme): void {\n if (theme.tokens || theme.typography) {\n const themePayload: Record<string, unknown> = {};\n if (theme.tokens) themePayload.colors = theme.tokens;\n if (theme.typography) themePayload.typography = theme.typography;\n this.post({ action: \"setTheme\", theme: themePayload });\n }\n if (theme.mode) {\n this.post({ action: \"setMode\", mode: theme.mode });\n }\n if (theme.styles !== undefined) {\n this.post({ action: \"setComponentStyles\", css: theme.styles });\n }\n }\n\n setLang(lang: string): void {\n this.post({ action: \"setLang\", lang });\n }\n\n setToken(token: string): void {\n this.ready = false;\n this.iframe.src = this.buildSrc(token);\n }\n\n navigate(path: string): void {\n this.post({ action: \"navigate\", path });\n }\n\n destroy(): void {\n window.removeEventListener(\"message\", this.messageHandler);\n this.iframe.remove();\n this.queue = [];\n this.ready = false;\n }\n\n private post(message: Record<string, unknown>): void {\n if (this.ready && this.iframe.contentWindow) {\n this.iframe.contentWindow.postMessage(message, this.baseUrl);\n } else {\n this.queue.push(message);\n }\n }\n\n private flush(): void {\n const pending = this.queue.splice(0);\n for (const message of pending) {\n if (this.iframe.contentWindow) {\n this.iframe.contentWindow.postMessage(message, this.baseUrl);\n }\n }\n }\n\n private onReady(): void {\n this.ready = true;\n if (this.initialTheme) {\n this.setTheme(this.initialTheme);\n }\n if (this.initialLang) {\n this.setLang(this.initialLang);\n }\n this.flush();\n }\n\n private buildSrc(token?: string): string {\n const params = new URLSearchParams({\n embed: \"true\",\n theme: \"light\",\n lang: this.initialLang ?? \"en\",\n });\n if (token) params.set(\"token\", token);\n return `${this.baseUrl}/connections?${params.toString()}`;\n }\n}\n"],"mappings":";AAEO,IAAM,gBAAN,MAAoB;AAAA,EASzB,YAAY,QAA6B;AANzC,SAAQ,QAAQ;AAChB,SAAQ,QAAmC,CAAC;AAM1C,SAAK,UAAU,OAAO;AACtB,SAAK,eAAe,OAAO;AAC3B,SAAK,cAAc,OAAO;AAE1B,SAAK,SAAS,SAAS,cAAc,QAAQ;AAC7C,SAAK,OAAO,MAAM,QAAQ;AAC1B,SAAK,OAAO,MAAM,SAAS;AAC3B,SAAK,OAAO,MAAM,SAAS;AAC3B,SAAK,OAAO,QAAQ;AACpB,SAAK,OAAO,MAAM,KAAK,SAAS,OAAO,KAAK;AAE5C,SAAK,iBAAiB,CAAC,MAAoB;AACzC,UAAI,EAAE,MAAM,WAAW,WAAW,EAAE,WAAW,KAAK,SAAS;AAC3D,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,KAAK,cAAc;AAEtD,WAAO,UAAU,YAAY,KAAK,MAAM;AAAA,EAC1C;AAAA,EAEA,SAAS,OAA6B;AACpC,QAAI,MAAM,UAAU,MAAM,YAAY;AACpC,YAAM,eAAwC,CAAC;AAC/C,UAAI,MAAM,OAAQ,cAAa,SAAS,MAAM;AAC9C,UAAI,MAAM,WAAY,cAAa,aAAa,MAAM;AACtD,WAAK,KAAK,EAAE,QAAQ,YAAY,OAAO,aAAa,CAAC;AAAA,IACvD;AACA,QAAI,MAAM,MAAM;AACd,WAAK,KAAK,EAAE,QAAQ,WAAW,MAAM,MAAM,KAAK,CAAC;AAAA,IACnD;AACA,QAAI,MAAM,WAAW,QAAW;AAC9B,WAAK,KAAK,EAAE,QAAQ,sBAAsB,KAAK,MAAM,OAAO,CAAC;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,QAAQ,MAAoB;AAC1B,SAAK,KAAK,EAAE,QAAQ,WAAW,KAAK,CAAC;AAAA,EACvC;AAAA,EAEA,SAAS,OAAqB;AAC5B,SAAK,QAAQ;AACb,SAAK,OAAO,MAAM,KAAK,SAAS,KAAK;AAAA,EACvC;AAAA,EAEA,SAAS,MAAoB;AAC3B,SAAK,KAAK,EAAE,QAAQ,YAAY,KAAK,CAAC;AAAA,EACxC;AAAA,EAEA,UAAgB;AACd,WAAO,oBAAoB,WAAW,KAAK,cAAc;AACzD,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,CAAC;AACd,SAAK,QAAQ;AAAA,EACf;AAAA,EAEQ,KAAK,SAAwC;AACnD,QAAI,KAAK,SAAS,KAAK,OAAO,eAAe;AAC3C,WAAK,OAAO,cAAc,YAAY,SAAS,KAAK,OAAO;AAAA,IAC7D,OAAO;AACL,WAAK,MAAM,KAAK,OAAO;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,QAAc;AACpB,UAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,eAAW,WAAW,SAAS;AAC7B,UAAI,KAAK,OAAO,eAAe;AAC7B,aAAK,OAAO,cAAc,YAAY,SAAS,KAAK,OAAO;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAgB;AACtB,SAAK,QAAQ;AACb,QAAI,KAAK,cAAc;AACrB,WAAK,SAAS,KAAK,YAAY;AAAA,IACjC;AACA,QAAI,KAAK,aAAa;AACpB,WAAK,QAAQ,KAAK,WAAW;AAAA,IAC/B;AACA,SAAK,MAAM;AAAA,EACb;AAAA,EAEQ,SAAS,OAAwB;AACvC,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM,KAAK,eAAe;AAAA,IAC5B,CAAC;AACD,QAAI,MAAO,QAAO,IAAI,SAAS,KAAK;AACpC,WAAO,GAAG,KAAK,OAAO,gBAAgB,OAAO,SAAS,CAAC;AAAA,EACzD;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yuno-payments/dashboard-embed-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight SDK for embedding the Yuno Dashboard via iframe",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" }
|
|
11
|
+
},
|
|
12
|
+
"files": ["dist", "README.md"],
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"scripts": {
|
|
15
|
+
"dev": "tsup --watch",
|
|
16
|
+
"build": "tsup",
|
|
17
|
+
"type-check": "tsc --noEmit",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"tsup": "^8.0.1",
|
|
22
|
+
"typescript": "~5.8.3"
|
|
23
|
+
},
|
|
24
|
+
"repository": { "type": "git", "url": "https://github.com/yuno-payments/dashboard-embed-sdk.git" },
|
|
25
|
+
"license": "UNLICENSED",
|
|
26
|
+
"publishConfig": { "access": "public", "registry": "https://registry.npmjs.org" }
|
|
27
|
+
}
|