@yuno-payments/dashboard-embed-sdk 0.4.0 → 1.1.1
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 +105 -10
- package/dist/index.d.ts +18 -7
- package/dist/index.js +39 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,9 +11,9 @@ npm install @yuno-payments/dashboard-embed-sdk
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
import {
|
|
14
|
+
import { initDashboard } from "@yuno-payments/dashboard-embed-sdk";
|
|
15
15
|
|
|
16
|
-
const sdk =
|
|
16
|
+
const sdk = initDashboard({
|
|
17
17
|
baseUrl: "https://dashboard.y.uno",
|
|
18
18
|
container: document.getElementById("dashboard")!,
|
|
19
19
|
token: "your-jwt-token",
|
|
@@ -46,22 +46,22 @@ The recommended way to manage the SDK instance:
|
|
|
46
46
|
|
|
47
47
|
```ts
|
|
48
48
|
import {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
initDashboard,
|
|
50
|
+
getDashboard,
|
|
51
|
+
destroyDashboard,
|
|
52
52
|
} from "@yuno-payments/dashboard-embed-sdk";
|
|
53
53
|
|
|
54
54
|
// Create (destroys any previous instance automatically)
|
|
55
|
-
const sdk =
|
|
55
|
+
const sdk = initDashboard(config);
|
|
56
56
|
|
|
57
57
|
// Retrieve the current instance from anywhere
|
|
58
|
-
const sdk =
|
|
58
|
+
const sdk = getDashboard();
|
|
59
59
|
|
|
60
60
|
// Destroy the instance and clean up
|
|
61
|
-
|
|
61
|
+
destroyDashboard();
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
### `
|
|
64
|
+
### `initDashboard(config)`
|
|
65
65
|
|
|
66
66
|
| Option | Type | Required | Description |
|
|
67
67
|
|---|---|---|---|
|
|
@@ -73,7 +73,9 @@ destroyYunoDashboard();
|
|
|
73
73
|
| `path` | `string` | No | Initial navigation path (default: `"/"`) |
|
|
74
74
|
| `onReady` | `() => void` | No | Callback invoked when the dashboard is fully loaded and authenticated |
|
|
75
75
|
| `onSessionExpired` | `() => void` | No | Callback invoked when the embedded session has expired. The host should re-authenticate and call `setToken(newToken)` to resume. |
|
|
76
|
+
| `onCheckoutPublished` | `(event: CheckoutPublishedEvent) => void \| Promise<void>` | No | Callback invoked when the user publishes the checkout configuration or styling. `event.source` is `"checkout"` or `"styling"`, `event.status` reports the publish call state (`"loading"` → `"success"` or `"error"`), and `event.payload` contains the configuration object that was published. |
|
|
76
77
|
| `loading` | `HTMLElement` | No | Custom loading overlay element. If omitted, a default spinner is shown |
|
|
78
|
+
| `autoHeight` | `boolean` | No | When `true`, the iframe is resized to match the dashboard content height (no inner scroll). Default `false` (iframe fills its container at `100%`). See [Auto height](#auto-height) |
|
|
77
79
|
|
|
78
80
|
### Methods
|
|
79
81
|
|
|
@@ -128,6 +130,16 @@ interface DashboardTheme {
|
|
|
128
130
|
mode?: "light" | "dark";
|
|
129
131
|
styles?: string; // Custom CSS injected into the dashboard
|
|
130
132
|
}
|
|
133
|
+
|
|
134
|
+
type CheckoutPublishedSource = "checkout" | "styling";
|
|
135
|
+
|
|
136
|
+
type CheckoutPublishedStatus = "loading" | "success" | "error";
|
|
137
|
+
|
|
138
|
+
interface CheckoutPublishedEvent {
|
|
139
|
+
source: CheckoutPublishedSource;
|
|
140
|
+
status: CheckoutPublishedStatus;
|
|
141
|
+
payload?: unknown; // The configuration object that was published
|
|
142
|
+
}
|
|
131
143
|
```
|
|
132
144
|
|
|
133
145
|
## Session timeouts
|
|
@@ -146,7 +158,7 @@ When the embedded session expires, the iframe paints a "Session expired" overlay
|
|
|
146
158
|
and emits a message to the host. Subscribe via `onSessionExpired`:
|
|
147
159
|
|
|
148
160
|
```ts
|
|
149
|
-
const sdk =
|
|
161
|
+
const sdk = initDashboard({
|
|
150
162
|
baseUrl: "https://dashboard.y.uno",
|
|
151
163
|
container: document.getElementById("dashboard")!,
|
|
152
164
|
token: initialToken,
|
|
@@ -157,10 +169,93 @@ const sdk = initYunoDashboard({
|
|
|
157
169
|
})
|
|
158
170
|
```
|
|
159
171
|
|
|
172
|
+
## Checkout published events
|
|
173
|
+
|
|
174
|
+
Whenever the user publishes from the embedded Checkout Builder (payment method
|
|
175
|
+
configuration) or the Styling editor, the iframe emits a message to the host.
|
|
176
|
+
Subscribe via `onCheckoutPublished`:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const sdk = initDashboard({
|
|
180
|
+
baseUrl: "https://dashboard.y.uno",
|
|
181
|
+
container: document.getElementById("dashboard")!,
|
|
182
|
+
token: initialToken,
|
|
183
|
+
onCheckoutPublished: (event) => {
|
|
184
|
+
// event.source is "checkout" | "styling"
|
|
185
|
+
// event.status is "loading" | "success" | "error"
|
|
186
|
+
// event.payload is the configuration object that was published
|
|
187
|
+
switch (event.status) {
|
|
188
|
+
case "loading":
|
|
189
|
+
console.log(`Publish loading from ${event.source}`)
|
|
190
|
+
break
|
|
191
|
+
case "success":
|
|
192
|
+
console.log(`Checkout published from ${event.source}`, event.payload)
|
|
193
|
+
break
|
|
194
|
+
case "error":
|
|
195
|
+
console.log("Publish failed — please try again")
|
|
196
|
+
break
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The callback fires once per state transition of the publish call: first with
|
|
203
|
+
`status: "loading"` when the user triggers the publish, then a second time with
|
|
204
|
+
either `"success"` or `"error"` once the dashboard's publish endpoint responds.
|
|
205
|
+
`event.payload` is only meaningful on the `"success"` event.
|
|
206
|
+
|
|
160
207
|
## Loading overlay
|
|
161
208
|
|
|
162
209
|
A loading overlay covers the iframe while initialization completes. You can provide a custom element via the `loading` config option, or the SDK renders a default spinner. The overlay fades out automatically (300ms transition) once the dashboard is authenticated and ready.
|
|
163
210
|
|
|
211
|
+
## Auto height
|
|
212
|
+
|
|
213
|
+
By default the iframe fills its container (`height: 100%`) and the dashboard content
|
|
214
|
+
scrolls inside it. Pass `autoHeight: true` to size the iframe to the dashboard's content
|
|
215
|
+
height instead, so the whole host page scrolls naturally with no inner scrollbar:
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
initDashboard({
|
|
219
|
+
baseUrl: "https://dashboard.y.uno",
|
|
220
|
+
container: document.getElementById("dashboard")!,
|
|
221
|
+
token,
|
|
222
|
+
autoHeight: true,
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Host/iframe contract:** when `autoHeight` is enabled, the embedded dashboard reports its
|
|
227
|
+
content height to the host via `postMessage({ action: "resize", height })` whenever the
|
|
228
|
+
content resizes; the SDK applies that height to the iframe and its wrapper. Messages are
|
|
229
|
+
accepted only from the configured `baseUrl` origin. Your container must allow vertical growth
|
|
230
|
+
(avoid a fixed `height` / `overflow: hidden`) for the effect to be visible.
|
|
231
|
+
|
|
232
|
+
## Migrating from 0.x to 1.0
|
|
233
|
+
|
|
234
|
+
`1.0.0` drops the `Yuno` brand prefix from the public API so the SDK reads cleanly
|
|
235
|
+
in white-labelled integrations. The old names were **removed** — there is no
|
|
236
|
+
compatibility shim, so update every import and call site:
|
|
237
|
+
|
|
238
|
+
| 0.x (removed) | 1.0 (new) |
|
|
239
|
+
|---|---|
|
|
240
|
+
| `initYunoDashboard(config)` | `initDashboard(config)` |
|
|
241
|
+
| `getYunoDashboard()` | `getDashboard()` |
|
|
242
|
+
| `destroyYunoDashboard()` | `destroyDashboard()` |
|
|
243
|
+
| `YunoDashboard` (class) | `Dashboard` |
|
|
244
|
+
| `YunoDashboardConfig` (type) | `DashboardConfig` |
|
|
245
|
+
|
|
246
|
+
```diff
|
|
247
|
+
- import { initYunoDashboard, getYunoDashboard, destroyYunoDashboard } from "@yuno-payments/dashboard-embed-sdk";
|
|
248
|
+
- import type { YunoDashboardConfig } from "@yuno-payments/dashboard-embed-sdk";
|
|
249
|
+
+ import { initDashboard, getDashboard, destroyDashboard } from "@yuno-payments/dashboard-embed-sdk";
|
|
250
|
+
+ import type { DashboardConfig } from "@yuno-payments/dashboard-embed-sdk";
|
|
251
|
+
|
|
252
|
+
- const sdk = initYunoDashboard(config);
|
|
253
|
+
+ const sdk = initDashboard(config);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Behavior, config options, methods, callbacks, and the PostMessage host/iframe
|
|
257
|
+
contract are unchanged — this release renames the API surface only.
|
|
258
|
+
|
|
164
259
|
## Development
|
|
165
260
|
|
|
166
261
|
```bash
|
package/dist/index.d.ts
CHANGED
|
@@ -37,7 +37,14 @@ interface DashboardTheme {
|
|
|
37
37
|
mode?: "light" | "dark";
|
|
38
38
|
styles?: string;
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
type CheckoutPublishedSource = "checkout" | "styling";
|
|
41
|
+
type CheckoutPublishedStatus = "loading" | "success" | "error";
|
|
42
|
+
interface CheckoutPublishedEvent {
|
|
43
|
+
source: CheckoutPublishedSource;
|
|
44
|
+
status: CheckoutPublishedStatus;
|
|
45
|
+
payload?: unknown;
|
|
46
|
+
}
|
|
47
|
+
interface DashboardConfig {
|
|
41
48
|
baseUrl: string;
|
|
42
49
|
container: HTMLElement;
|
|
43
50
|
token?: string;
|
|
@@ -46,10 +53,12 @@ interface YunoDashboardConfig {
|
|
|
46
53
|
path?: string;
|
|
47
54
|
onReady?: () => void;
|
|
48
55
|
onSessionExpired?: () => void | Promise<void>;
|
|
56
|
+
onCheckoutPublished?: (event: CheckoutPublishedEvent) => void | Promise<void>;
|
|
49
57
|
loading?: HTMLElement;
|
|
58
|
+
autoHeight?: boolean;
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
declare class
|
|
61
|
+
declare class Dashboard {
|
|
53
62
|
private iframe;
|
|
54
63
|
private wrapper;
|
|
55
64
|
private overlay;
|
|
@@ -63,7 +72,9 @@ declare class YunoDashboard {
|
|
|
63
72
|
private token?;
|
|
64
73
|
private onReadyCallback?;
|
|
65
74
|
private onSessionExpiredCallback?;
|
|
66
|
-
|
|
75
|
+
private onCheckoutPublishedCallback?;
|
|
76
|
+
private autoHeight;
|
|
77
|
+
constructor(config: DashboardConfig);
|
|
67
78
|
setTheme(theme: DashboardTheme): void;
|
|
68
79
|
setLang(lang: string): void;
|
|
69
80
|
setToken(token: string): void;
|
|
@@ -78,8 +89,8 @@ declare class YunoDashboard {
|
|
|
78
89
|
private buildSrc;
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
declare function
|
|
82
|
-
declare function
|
|
83
|
-
declare function
|
|
92
|
+
declare function initDashboard(config: DashboardConfig): Dashboard;
|
|
93
|
+
declare function getDashboard(): Dashboard | null;
|
|
94
|
+
declare function destroyDashboard(): void;
|
|
84
95
|
|
|
85
|
-
export { type
|
|
96
|
+
export { type CheckoutPublishedEvent, type CheckoutPublishedSource, type CheckoutPublishedStatus, Dashboard, type DashboardConfig, type DashboardTheme, type ModeTokens, type ThemeColors, type ThemeTypography, destroyDashboard, getDashboard, initDashboard };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var
|
|
1
|
+
// src/dashboard.ts
|
|
2
|
+
var Dashboard = class {
|
|
3
3
|
constructor(config) {
|
|
4
4
|
this.overlay = null;
|
|
5
5
|
this.ready = false;
|
|
@@ -11,6 +11,8 @@ var YunoDashboard = class {
|
|
|
11
11
|
this.token = config.token;
|
|
12
12
|
this.onReadyCallback = config.onReady;
|
|
13
13
|
this.onSessionExpiredCallback = config.onSessionExpired;
|
|
14
|
+
this.onCheckoutPublishedCallback = config.onCheckoutPublished;
|
|
15
|
+
this.autoHeight = config.autoHeight ?? false;
|
|
14
16
|
this.wrapper = document.createElement("div");
|
|
15
17
|
this.wrapper.style.position = "relative";
|
|
16
18
|
this.wrapper.style.width = "100%";
|
|
@@ -29,6 +31,11 @@ var YunoDashboard = class {
|
|
|
29
31
|
this.wrapper.appendChild(this.overlay);
|
|
30
32
|
this.messageHandler = (e) => {
|
|
31
33
|
if (e.origin !== this.baseUrl) return;
|
|
34
|
+
if (this.autoHeight && e.data?.action === "resize" && typeof e.data?.height === "number") {
|
|
35
|
+
this.iframe.style.height = `${e.data.height}px`;
|
|
36
|
+
this.wrapper.style.height = `${e.data.height}px`;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
32
39
|
if (e.data?.type === "yuno-dashboard:session-expired") {
|
|
33
40
|
try {
|
|
34
41
|
const result = this.onSessionExpiredCallback?.();
|
|
@@ -45,6 +52,26 @@ var YunoDashboard = class {
|
|
|
45
52
|
}
|
|
46
53
|
return;
|
|
47
54
|
}
|
|
55
|
+
if (e.data?.type === "yuno-dashboard:checkout-published") {
|
|
56
|
+
try {
|
|
57
|
+
const result = this.onCheckoutPublishedCallback?.({
|
|
58
|
+
source: e.data?.source,
|
|
59
|
+
status: e.data?.status,
|
|
60
|
+
payload: e.data?.payload
|
|
61
|
+
});
|
|
62
|
+
if (result && typeof result.catch === "function") {
|
|
63
|
+
result.catch(
|
|
64
|
+
(err) => (
|
|
65
|
+
// eslint-disable-next-line no-console
|
|
66
|
+
console.warn("[yuno-dashboard-sdk] onCheckoutPublished async callback rejected", err)
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.warn("[yuno-dashboard-sdk] onCheckoutPublished callback threw", err);
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
48
75
|
if (e.data?.action === "ready") {
|
|
49
76
|
this.onReady();
|
|
50
77
|
}
|
|
@@ -115,9 +142,6 @@ var YunoDashboard = class {
|
|
|
115
142
|
}
|
|
116
143
|
onTokenApplied() {
|
|
117
144
|
setTimeout(() => {
|
|
118
|
-
if (this.initialPath !== "/") {
|
|
119
|
-
this.post({ action: "navigate", path: this.initialPath });
|
|
120
|
-
}
|
|
121
145
|
this.hideOverlay();
|
|
122
146
|
this.onReadyCallback?.();
|
|
123
147
|
}, 1e3);
|
|
@@ -153,32 +177,33 @@ var YunoDashboard = class {
|
|
|
153
177
|
theme: this.initialTheme?.mode ?? "light",
|
|
154
178
|
lang: this.initialLang ?? "en"
|
|
155
179
|
});
|
|
156
|
-
|
|
180
|
+
const path = !this.initialPath || this.initialPath === "/" ? "/" : this.initialPath;
|
|
181
|
+
return `${this.baseUrl}${path}?${params.toString()}`;
|
|
157
182
|
}
|
|
158
183
|
};
|
|
159
184
|
|
|
160
185
|
// src/singleton.ts
|
|
161
186
|
var instance = null;
|
|
162
|
-
function
|
|
187
|
+
function initDashboard(config) {
|
|
163
188
|
if (instance) {
|
|
164
189
|
instance.destroy();
|
|
165
190
|
}
|
|
166
|
-
instance = new
|
|
191
|
+
instance = new Dashboard(config);
|
|
167
192
|
return instance;
|
|
168
193
|
}
|
|
169
|
-
function
|
|
194
|
+
function getDashboard() {
|
|
170
195
|
return instance;
|
|
171
196
|
}
|
|
172
|
-
function
|
|
197
|
+
function destroyDashboard() {
|
|
173
198
|
if (instance) {
|
|
174
199
|
instance.destroy();
|
|
175
200
|
instance = null;
|
|
176
201
|
}
|
|
177
202
|
}
|
|
178
203
|
export {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
204
|
+
Dashboard,
|
|
205
|
+
destroyDashboard,
|
|
206
|
+
getDashboard,
|
|
207
|
+
initDashboard
|
|
183
208
|
};
|
|
184
209
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/yuno-dashboard.ts","../src/singleton.ts"],"sourcesContent":["import type { DashboardTheme, YunoDashboardConfig } from \"./types\";\n\nexport class YunoDashboard {\n private iframe: HTMLIFrameElement;\n private wrapper: HTMLDivElement;\n private overlay: HTMLElement | null = null;\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 private initialPath: string;\n private token?: string;\n private onReadyCallback?: () => void;\n private onSessionExpiredCallback?: () => void | Promise<void>;\n\n constructor(config: YunoDashboardConfig) {\n this.baseUrl = config.baseUrl;\n this.initialTheme = config.theme;\n this.initialLang = config.lang;\n this.initialPath = config.path ?? \"/\";\n this.token = config.token;\n this.onReadyCallback = config.onReady;\n this.onSessionExpiredCallback = config.onSessionExpired;\n\n this.wrapper = document.createElement(\"div\");\n this.wrapper.style.position = \"relative\";\n this.wrapper.style.width = \"100%\";\n this.wrapper.style.height = \"100%\";\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();\n\n this.wrapper.appendChild(this.iframe);\n\n this.overlay = config.loading instanceof HTMLElement\n ? config.loading\n : this.createDefaultOverlay();\n this.overlay.style.position = \"absolute\";\n this.overlay.style.inset = \"0\";\n this.overlay.style.zIndex = \"1\";\n this.wrapper.appendChild(this.overlay);\n\n this.messageHandler = (e: MessageEvent) => {\n if (e.origin !== this.baseUrl) return;\n if (e.data?.type === \"yuno-dashboard:session-expired\") {\n try {\n const result = this.onSessionExpiredCallback?.();\n if (result && typeof (result as Promise<unknown>).catch === \"function\") {\n (result as Promise<unknown>).catch((err) =>\n // eslint-disable-next-line no-console\n console.warn(\"[yuno-dashboard-sdk] onSessionExpired async callback rejected\", err),\n );\n }\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\"[yuno-dashboard-sdk] onSessionExpired callback threw\", err);\n }\n return;\n }\n if (e.data?.action === \"ready\") {\n this.onReady();\n }\n if (e.data?.action === \"tokenApplied\") {\n this.onTokenApplied();\n }\n };\n window.addEventListener(\"message\", this.messageHandler);\n\n config.container.appendChild(this.wrapper);\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: \"setExternalStyles\", 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.token = token;\n this.post({ action: \"setToken\", 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.wrapper.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.token) {\n this.post({ action: \"setToken\", token: this.token });\n }\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 onTokenApplied(): void {\n setTimeout(() => {\n if (this.initialPath !== \"/\") {\n this.post({ action: \"navigate\", path: this.initialPath });\n }\n this.hideOverlay();\n this.onReadyCallback?.();\n }, 1000);\n }\n\n private hideOverlay(): void {\n if (!this.overlay) return;\n this.overlay.style.transition = \"opacity 0.3s\";\n this.overlay.style.opacity = \"0\";\n setTimeout(() => this.overlay?.remove(), 300);\n }\n\n private createDefaultOverlay(): HTMLElement {\n const overlay = document.createElement(\"div\");\n overlay.style.background = \"#ffffff\";\n overlay.style.display = \"flex\";\n overlay.style.alignItems = \"center\";\n overlay.style.justifyContent = \"center\";\n\n const spinner = document.createElement(\"div\");\n spinner.style.width = \"32px\";\n spinner.style.height = \"32px\";\n spinner.style.border = \"3px solid #e0e0e0\";\n spinner.style.borderTopColor = \"#666\";\n spinner.style.borderRadius = \"50%\";\n spinner.style.animation = \"yuno-spin 0.8s linear infinite\";\n\n const style = document.createElement(\"style\");\n style.textContent = \"@keyframes yuno-spin { to { transform: rotate(360deg); } }\";\n\n overlay.appendChild(style);\n overlay.appendChild(spinner);\n return overlay;\n }\n\n private buildSrc(): string {\n const params = new URLSearchParams({\n embed: \"true\",\n theme: this.initialTheme?.mode ?? \"light\",\n lang: this.initialLang ?? \"en\",\n });\n return `${this.baseUrl}/?${params.toString()}`;\n }\n}\n","import { YunoDashboard } from \"./yuno-dashboard\";\nimport type { YunoDashboardConfig } from \"./types\";\n\nlet instance: YunoDashboard | null = null;\n\nexport function initYunoDashboard(config: YunoDashboardConfig): YunoDashboard {\n if (instance) {\n instance.destroy();\n }\n instance = new YunoDashboard(config);\n return instance;\n}\n\nexport function getYunoDashboard(): YunoDashboard | null {\n return instance;\n}\n\nexport function destroyYunoDashboard(): void {\n if (instance) {\n instance.destroy();\n instance = null;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/dashboard.ts","../src/singleton.ts"],"sourcesContent":["import type { DashboardTheme, DashboardConfig, CheckoutPublishedEvent } from \"./types\";\n\nexport class Dashboard {\n private iframe: HTMLIFrameElement;\n private wrapper: HTMLDivElement;\n private overlay: HTMLElement | null = null;\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 private initialPath: string;\n private token?: string;\n private onReadyCallback?: () => void;\n private onSessionExpiredCallback?: () => void | Promise<void>;\n private onCheckoutPublishedCallback?: (event: CheckoutPublishedEvent) => void | Promise<void>;\n private autoHeight: boolean;\n\n constructor(config: DashboardConfig) {\n this.baseUrl = config.baseUrl;\n this.initialTheme = config.theme;\n this.initialLang = config.lang;\n this.initialPath = config.path ?? \"/\";\n this.token = config.token;\n this.onReadyCallback = config.onReady;\n this.onSessionExpiredCallback = config.onSessionExpired;\n this.onCheckoutPublishedCallback = config.onCheckoutPublished;\n this.autoHeight = config.autoHeight ?? false;\n\n this.wrapper = document.createElement(\"div\");\n this.wrapper.style.position = \"relative\";\n this.wrapper.style.width = \"100%\";\n this.wrapper.style.height = \"100%\";\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();\n\n this.wrapper.appendChild(this.iframe);\n\n this.overlay = config.loading instanceof HTMLElement\n ? config.loading\n : this.createDefaultOverlay();\n this.overlay.style.position = \"absolute\";\n this.overlay.style.inset = \"0\";\n this.overlay.style.zIndex = \"1\";\n this.wrapper.appendChild(this.overlay);\n\n this.messageHandler = (e: MessageEvent) => {\n if (e.origin !== this.baseUrl) return;\n if (\n this.autoHeight &&\n e.data?.action === \"resize\" &&\n typeof e.data?.height === \"number\"\n ) {\n this.iframe.style.height = `${e.data.height}px`;\n this.wrapper.style.height = `${e.data.height}px`;\n return;\n }\n if (e.data?.type === \"yuno-dashboard:session-expired\") {\n try {\n const result = this.onSessionExpiredCallback?.();\n if (result && typeof (result as Promise<unknown>).catch === \"function\") {\n (result as Promise<unknown>).catch((err) =>\n // eslint-disable-next-line no-console\n console.warn(\"[yuno-dashboard-sdk] onSessionExpired async callback rejected\", err),\n );\n }\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\"[yuno-dashboard-sdk] onSessionExpired callback threw\", err);\n }\n return;\n }\n if (e.data?.type === \"yuno-dashboard:checkout-published\") {\n try {\n const result = this.onCheckoutPublishedCallback?.({\n source: e.data?.source,\n status: e.data?.status,\n payload: e.data?.payload,\n });\n if (result && typeof (result as Promise<unknown>).catch === \"function\") {\n (result as Promise<unknown>).catch((err) =>\n // eslint-disable-next-line no-console\n console.warn(\"[yuno-dashboard-sdk] onCheckoutPublished async callback rejected\", err),\n );\n }\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\"[yuno-dashboard-sdk] onCheckoutPublished callback threw\", err);\n }\n return;\n }\n if (e.data?.action === \"ready\") {\n this.onReady();\n }\n if (e.data?.action === \"tokenApplied\") {\n this.onTokenApplied();\n }\n };\n window.addEventListener(\"message\", this.messageHandler);\n\n config.container.appendChild(this.wrapper);\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: \"setExternalStyles\", 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.token = token;\n this.post({ action: \"setToken\", 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.wrapper.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.token) {\n this.post({ action: \"setToken\", token: this.token });\n }\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 onTokenApplied(): void {\n setTimeout(() => {\n this.hideOverlay();\n this.onReadyCallback?.();\n }, 1000);\n }\n\n private hideOverlay(): void {\n if (!this.overlay) return;\n this.overlay.style.transition = \"opacity 0.3s\";\n this.overlay.style.opacity = \"0\";\n setTimeout(() => this.overlay?.remove(), 300);\n }\n\n private createDefaultOverlay(): HTMLElement {\n const overlay = document.createElement(\"div\");\n overlay.style.background = \"#ffffff\";\n overlay.style.display = \"flex\";\n overlay.style.alignItems = \"center\";\n overlay.style.justifyContent = \"center\";\n\n const spinner = document.createElement(\"div\");\n spinner.style.width = \"32px\";\n spinner.style.height = \"32px\";\n spinner.style.border = \"3px solid #e0e0e0\";\n spinner.style.borderTopColor = \"#666\";\n spinner.style.borderRadius = \"50%\";\n spinner.style.animation = \"yuno-spin 0.8s linear infinite\";\n\n const style = document.createElement(\"style\");\n style.textContent = \"@keyframes yuno-spin { to { transform: rotate(360deg); } }\";\n\n overlay.appendChild(style);\n overlay.appendChild(spinner);\n return overlay;\n }\n\n private buildSrc(): string {\n const params = new URLSearchParams({\n embed: \"true\",\n theme: this.initialTheme?.mode ?? \"light\",\n lang: this.initialLang ?? \"en\",\n });\n const path = !this.initialPath || this.initialPath === \"/\" ? \"/\" : this.initialPath;\n return `${this.baseUrl}${path}?${params.toString()}`;\n }\n}\n","import { Dashboard } from \"./dashboard\";\nimport type { DashboardConfig } from \"./types\";\n\nlet instance: Dashboard | null = null;\n\nexport function initDashboard(config: DashboardConfig): Dashboard {\n if (instance) {\n instance.destroy();\n }\n instance = new Dashboard(config);\n return instance;\n}\n\nexport function getDashboard(): Dashboard | null {\n return instance;\n}\n\nexport function destroyDashboard(): void {\n if (instance) {\n instance.destroy();\n instance = null;\n }\n}\n"],"mappings":"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","names":[]}
|