@cimplify/sdk 0.66.0 → 0.68.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.
Files changed (55) hide show
  1. package/dist/advanced.d.mts +1 -1
  2. package/dist/advanced.d.ts +1 -1
  3. package/dist/advanced.js +20 -20
  4. package/dist/advanced.mjs +1 -1
  5. package/dist/{chunk-J3MGY6AU.js → chunk-5HAUJBOK.js} +36 -82
  6. package/dist/chunk-E6T5VJMG.mjs +156 -0
  7. package/dist/{chunk-3G4QCENX.mjs → chunk-FVGVJ4TC.mjs} +12 -50
  8. package/dist/chunk-IQLJJW2H.js +168 -0
  9. package/dist/{chunk-227XTAEB.mjs → chunk-KNPE4WCQ.mjs} +2 -48
  10. package/dist/{chunk-H6DBPHMZ.js → chunk-NGQCWFKF.js} +4 -4
  11. package/dist/{chunk-R6363CC7.mjs → chunk-SOV4H6PQ.mjs} +509 -79
  12. package/dist/{chunk-HCZTBWU4.js → chunk-SXGFJEME.js} +12 -50
  13. package/dist/{chunk-MWI5GAUF.mjs → chunk-TAKORJP4.mjs} +2 -2
  14. package/dist/{chunk-AVQL3TSJ.js → chunk-WCSAZRNC.js} +519 -78
  15. package/dist/{client-CUrA1uQ0.d.mts → client-CBE7ksYC.d.mts} +1 -1
  16. package/dist/{client-Bo5rujc2.d.ts → client-CfeQRwhl.d.ts} +55 -21
  17. package/dist/{client-DasPHOJh.d.ts → client-DlXfZy7N.d.ts} +1 -1
  18. package/dist/{client-Dka2cGhu.d.mts → client-Dyo3dvNy.d.mts} +55 -21
  19. package/dist/index.d.mts +2 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +104 -88
  22. package/dist/index.mjs +16 -12
  23. package/dist/mock/cli.mjs +12 -50
  24. package/dist/mock/library.js +12 -50
  25. package/dist/mock/library.mjs +12 -50
  26. package/dist/mock/msw.js +12 -50
  27. package/dist/mock/msw.mjs +12 -50
  28. package/dist/react.d.mts +44 -44
  29. package/dist/react.d.ts +44 -44
  30. package/dist/react.js +298 -175
  31. package/dist/react.mjs +240 -117
  32. package/dist/server.d.mts +2 -2
  33. package/dist/server.d.ts +2 -2
  34. package/dist/server.js +16 -9
  35. package/dist/server.mjs +11 -4
  36. package/dist/{sign-in-dr7m09nm.d.ts → sign-in-DQlIdqsi.d.mts} +14 -1
  37. package/dist/{sign-in-dr7m09nm.d.mts → sign-in-DQlIdqsi.d.ts} +14 -1
  38. package/dist/styles.css +1 -1
  39. package/dist/testing/msw.js +2 -2
  40. package/dist/testing/msw.mjs +1 -1
  41. package/dist/testing/suite.d.mts +2 -2
  42. package/dist/testing/suite.d.ts +2 -2
  43. package/dist/testing/suite.js +23 -23
  44. package/dist/testing/suite.mjs +4 -4
  45. package/dist/testing.d.mts +17 -17
  46. package/dist/testing.d.ts +17 -17
  47. package/dist/testing.js +79 -79
  48. package/dist/testing.mjs +5 -5
  49. package/package.json +1 -1
  50. package/registry/index.json +0 -9
  51. package/dist/chunk-3Z3FQH7X.mjs +0 -323
  52. package/dist/chunk-7BKKBJQM.mjs +0 -52
  53. package/dist/chunk-GDAGM26J.js +0 -338
  54. package/dist/chunk-KWYI2TTA.js +0 -60
  55. package/registry/account.json +0 -15
@@ -1,338 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkKWYI2TTA_js = require('./chunk-KWYI2TTA.js');
4
-
5
- // src/gallery.ts
6
- function dedupe(urls) {
7
- const seen = /* @__PURE__ */ new Set();
8
- const out = [];
9
- for (const url of urls) {
10
- if (url && !seen.has(url)) {
11
- seen.add(url);
12
- out.push(url);
13
- }
14
- }
15
- return out;
16
- }
17
- function resolveGallery(product, selectedVariantId) {
18
- const variant = selectedVariantId ? product.variants?.find((v) => v.id === selectedVariantId) : void 0;
19
- if (variant?.images?.length) return dedupe(variant.images);
20
- if (product.images?.length) return dedupe(product.images);
21
- const firstWithImages = product.variants?.find((v) => v.images?.length);
22
- if (firstWithImages?.images?.length) return dedupe(firstWithImages.images);
23
- return product.image_url ? [product.image_url] : [];
24
- }
25
- function allGalleryImages(product) {
26
- const seen = /* @__PURE__ */ new Set();
27
- const out = [];
28
- const push = (url, variantId) => {
29
- if (url && !seen.has(url)) {
30
- seen.add(url);
31
- out.push({ url, variantId });
32
- }
33
- };
34
- push(product.image_url, null);
35
- for (const url of product.images ?? []) push(url, null);
36
- for (const variant of product.variants ?? []) {
37
- for (const url of variant.images ?? []) push(url, variant.id);
38
- }
39
- return out;
40
- }
41
-
42
- // src/utils/variant.ts
43
- function stripProductPrefix(variantName, productName) {
44
- if (!variantName || !productName) return variantName || productName;
45
- const lower = variantName.toLowerCase().trim();
46
- if (lower === "default" || lower === "standard") return productName;
47
- if (lower.endsWith("-default") || lower.endsWith("-standard")) return productName;
48
- if (variantName.startsWith(productName)) {
49
- const rest = variantName.slice(productName.length);
50
- const match = rest.match(/^\s*[-–—]\s*(.*)/);
51
- if (match && match[1].length > 0) return match[1];
52
- }
53
- const lowerProduct = productName.toLowerCase().trim();
54
- if (lower.startsWith(lowerProduct)) {
55
- const rest = variantName.slice(productName.length);
56
- const match = rest.match(/^\s*[-–—]\s*(.*)/);
57
- if (match && match[1].length > 0) return match[1];
58
- }
59
- const lastDash = variantName.lastIndexOf("-");
60
- if (lastDash > 0 && lastDash < variantName.length - 1) {
61
- const prefix = variantName.slice(0, lastDash).trim();
62
- const suffix = variantName.slice(lastDash + 1).trim();
63
- if (suffix.length > 0 && prefix.length > suffix.length * 2) {
64
- return suffix;
65
- }
66
- }
67
- return variantName;
68
- }
69
- function getVariantDisplayName(variant, productName) {
70
- if (variant.display_attributes?.length) {
71
- return variant.display_attributes.map((a) => a.value_name).join(" / ");
72
- }
73
- if (variant.name) {
74
- return productName ? stripProductPrefix(variant.name, productName) : variant.name;
75
- }
76
- return productName || (variant.is_default ? "Default" : "Option");
77
- }
78
-
79
- // src/types/product.ts
80
- var PRODUCT_TYPE = {
81
- Product: "product",
82
- Service: "service",
83
- Digital: "digital",
84
- Bundle: "bundle",
85
- Composite: "composite"
86
- };
87
- var RENDER_HINT = {
88
- Food: "food",
89
- Physical: "physical",
90
- General: "general"
91
- };
92
- var DURATION_UNIT = {
93
- Minutes: "minutes",
94
- Hours: "hours",
95
- Days: "days",
96
- Nights: "nights",
97
- Weeks: "weeks",
98
- Months: "months",
99
- Years: "years"
100
- };
101
- var INPUT_FIELD_TYPE = {
102
- Text: "text",
103
- Textarea: "textarea",
104
- Number: "number",
105
- Select: "select",
106
- Radio: "radio",
107
- Checkbox: "checkbox",
108
- Color: "color",
109
- Date: "date",
110
- File: "file",
111
- Image: "image",
112
- Url: "url",
113
- Address: "address",
114
- Phone: "phone",
115
- Email: "email",
116
- DateTime: "date_time",
117
- Time: "time",
118
- Signature: "signature",
119
- MultiSelect: "multi_select",
120
- DateRange: "date_range",
121
- Location: "location"
122
- };
123
-
124
- // src/internal/pkce.ts
125
- var VERIFIER_BYTES = 64;
126
- async function generatePkce() {
127
- const random = new Uint8Array(VERIFIER_BYTES);
128
- crypto.getRandomValues(random);
129
- const verifier = base64UrlEncode(random);
130
- const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
131
- const challenge = base64UrlEncode(new Uint8Array(digest));
132
- return { verifier, challenge, method: "S256" };
133
- }
134
- function generateState(byteLength = 16) {
135
- const buf = new Uint8Array(byteLength);
136
- crypto.getRandomValues(buf);
137
- return base64UrlEncode(buf);
138
- }
139
- function base64UrlEncode(bytes) {
140
- let str = "";
141
- for (const byte of bytes) str += String.fromCharCode(byte);
142
- return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
143
- }
144
-
145
- // src/internal/modal-iframe.ts
146
- function openModalIframe(opts) {
147
- const overlay = document.createElement("div");
148
- overlay.dataset.cimplifyModal = "1";
149
- Object.assign(overlay.style, {
150
- position: "fixed",
151
- inset: "0",
152
- background: "rgba(15, 18, 24, 0.55)",
153
- zIndex: "2147483647",
154
- display: "grid",
155
- placeItems: "center",
156
- backdropFilter: "blur(2px)"
157
- });
158
- const card = document.createElement("div");
159
- Object.assign(card.style, {
160
- width: `${opts.width ?? 480}px`,
161
- maxWidth: "calc(100vw - 24px)",
162
- height: `${opts.height ?? 720}px`,
163
- maxHeight: "calc(100vh - 32px)"
164
- });
165
- const iframe = document.createElement("iframe");
166
- iframe.src = opts.src;
167
- iframe.style.width = "100%";
168
- iframe.style.height = "100%";
169
- iframe.style.border = "none";
170
- iframe.style.background = "transparent";
171
- iframe.setAttribute(
172
- "sandbox",
173
- opts.sandbox ?? "allow-scripts allow-same-origin allow-forms allow-popups"
174
- );
175
- iframe.setAttribute("allow", "publickey-credentials-get; publickey-credentials-create");
176
- card.appendChild(iframe);
177
- overlay.appendChild(card);
178
- document.body.appendChild(overlay);
179
- const close = () => {
180
- overlay.remove();
181
- document.removeEventListener("keydown", onKey);
182
- opts.onClose?.();
183
- };
184
- const onKey = (e) => {
185
- if (e.key === "Escape") close();
186
- };
187
- overlay.addEventListener("click", (e) => {
188
- if (e.target === overlay) close();
189
- });
190
- document.addEventListener("keydown", onKey);
191
- return { iframe, close };
192
- }
193
-
194
- // src/sign-in.ts
195
- var DEFAULT_SCOPE = "openid email phone profile";
196
- function resolveAuthorizeEndpoint(opts) {
197
- if (opts.authUrl) {
198
- return Promise.resolve(`${opts.authUrl.replace(/\/$/, "")}/oauth/authorize`);
199
- }
200
- return chunkKWYI2TTA_js.getAuthorizationEndpoint(opts.issuer ?? chunkKWYI2TTA_js.DEFAULT_ISSUER);
201
- }
202
- async function startSignIn(opts) {
203
- const callbackUri = opts.callbackUri ?? "/auth/callback";
204
- const pkce = await generatePkce();
205
- const state = generateState();
206
- const authorizeEndpoint = await resolveAuthorizeEndpoint(opts);
207
- if ((opts.mode ?? "redirect") === "redirect") {
208
- startRedirectSignIn(opts, authorizeEndpoint, pkce, state);
209
- return;
210
- }
211
- const params = new URLSearchParams({
212
- response_type: "code",
213
- response_mode: "web_message",
214
- client_id: opts.clientId,
215
- redirect_uri: opts.redirectUri,
216
- scope: opts.scope ?? DEFAULT_SCOPE,
217
- state,
218
- code_challenge: pkce.challenge,
219
- code_challenge_method: pkce.method
220
- });
221
- if (opts.loginHint) params.set("login_hint", opts.loginHint);
222
- if (opts.prompt) params.set("prompt", opts.prompt);
223
- const src = `${authorizeEndpoint}?${params.toString()}`;
224
- const expectedOrigin = new URL(authorizeEndpoint).origin;
225
- const modal = openModalIframe({
226
- src,
227
- onClose: () => {
228
- window.removeEventListener("message", handler);
229
- }
230
- });
231
- const handler = async (event) => {
232
- if (event.origin !== expectedOrigin) return;
233
- const data = event.data;
234
- if (!data || typeof data !== "object" || data.type !== "authorization_response") return;
235
- const response = data.response;
236
- if (response.error) {
237
- modal.close();
238
- opts.onError?.({ error: response.error, description: response.error_description });
239
- return;
240
- }
241
- if (!response.code) return;
242
- if (response.state !== state) {
243
- modal.close();
244
- opts.onError?.({ error: "state_mismatch" });
245
- return;
246
- }
247
- try {
248
- const res = await fetch(callbackUri, {
249
- method: "POST",
250
- credentials: "include",
251
- headers: { "Content-Type": "application/json" },
252
- body: JSON.stringify({ code: response.code, codeVerifier: pkce.verifier, state })
253
- });
254
- if (!res.ok) {
255
- const body = await res.text().catch(() => "");
256
- opts.onError?.({ error: "callback_failed", description: body });
257
- modal.close();
258
- return;
259
- }
260
- modal.close();
261
- opts.onSuccess?.();
262
- } catch (e) {
263
- opts.onError?.({ error: "callback_exception", description: String(e) });
264
- modal.close();
265
- }
266
- };
267
- window.addEventListener("message", handler);
268
- }
269
- function startRedirectSignIn(opts, authorizeEndpoint, pkce, state) {
270
- const returnTo = opts.returnTo ?? window.location.pathname + window.location.search;
271
- const cookieValue = chunkKWYI2TTA_js.encodePkceState({ verifier: pkce.verifier, state, returnTo });
272
- const secure = window.location.protocol === "https:" ? "; Secure" : "";
273
- document.cookie = `${chunkKWYI2TTA_js.PKCE_COOKIE}=${cookieValue}; Path=${chunkKWYI2TTA_js.PKCE_COOKIE_PATH}; Max-Age=${chunkKWYI2TTA_js.PKCE_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secure}`;
274
- const params = new URLSearchParams({
275
- response_type: "code",
276
- response_mode: "query",
277
- client_id: opts.clientId,
278
- redirect_uri: opts.redirectUri,
279
- scope: opts.scope ?? DEFAULT_SCOPE,
280
- state,
281
- code_challenge: pkce.challenge,
282
- code_challenge_method: pkce.method
283
- });
284
- if (opts.loginHint) params.set("login_hint", opts.loginHint);
285
- if (opts.prompt) params.set("prompt", opts.prompt);
286
- window.location.assign(`${authorizeEndpoint}?${params.toString()}`);
287
- }
288
-
289
- // src/assets/url.ts
290
- var DEFAULT_CDN_BASE_URL = "https://storefrontassetscdn.cimplify.io";
291
- var CIMPLIFY_CDN_HOSTS = [
292
- "storefrontassetscdn.cimplify.io",
293
- "cdn.cimplify.io",
294
- "static-tmp.cimplify.io"
295
- ];
296
- var ABSOLUTE_URL_RE = /^https?:\/\//i;
297
- var MOCK_PASSTHROUGH_RE = /^\/(img|elements|_mock)\//;
298
- function assetUrl(path, opts = {}) {
299
- if (!path) return path;
300
- if (ABSOLUTE_URL_RE.test(path)) return appendTransform(path, opts);
301
- if (MOCK_PASSTHROUGH_RE.test(path)) return appendTransform(path, opts);
302
- const base = (opts.base ?? DEFAULT_CDN_BASE_URL).replace(/\/+$/, "");
303
- const normalized = path.replace(/^\/+/, "");
304
- return appendTransform(`${base}/${normalized}`, opts);
305
- }
306
- function isCimplifyAsset(src, base) {
307
- if (!src) return false;
308
- if (!ABSOLUTE_URL_RE.test(src)) return true;
309
- if (MOCK_PASSTHROUGH_RE.test(src)) return true;
310
- const resolvedBase = (base ?? DEFAULT_CDN_BASE_URL).replace(/\/+$/, "");
311
- if (resolvedBase && src.startsWith(resolvedBase)) return true;
312
- return CIMPLIFY_CDN_HOSTS.some((host) => src.startsWith(`https://${host}/`));
313
- }
314
- function appendTransform(url, t) {
315
- const params = new URLSearchParams();
316
- if (t.w != null) params.set("w", String(t.w));
317
- if (t.h != null) params.set("h", String(t.h));
318
- if (t.quality != null) params.set("quality", String(t.quality));
319
- if (t.format != null) params.set("format", t.format);
320
- const query = params.toString();
321
- if (!query) return url;
322
- return `${url}${url.includes("?") ? "&" : "?"}${query}`;
323
- }
324
-
325
- exports.CIMPLIFY_CDN_HOSTS = CIMPLIFY_CDN_HOSTS;
326
- exports.DEFAULT_CDN_BASE_URL = DEFAULT_CDN_BASE_URL;
327
- exports.DURATION_UNIT = DURATION_UNIT;
328
- exports.INPUT_FIELD_TYPE = INPUT_FIELD_TYPE;
329
- exports.PRODUCT_TYPE = PRODUCT_TYPE;
330
- exports.RENDER_HINT = RENDER_HINT;
331
- exports.allGalleryImages = allGalleryImages;
332
- exports.assetUrl = assetUrl;
333
- exports.generatePkce = generatePkce;
334
- exports.generateState = generateState;
335
- exports.getVariantDisplayName = getVariantDisplayName;
336
- exports.isCimplifyAsset = isCimplifyAsset;
337
- exports.resolveGallery = resolveGallery;
338
- exports.startSignIn = startSignIn;
@@ -1,60 +0,0 @@
1
- 'use strict';
2
-
3
- // src/internal/pkce-cookie.ts
4
- var PKCE_COOKIE = "cimplify_pkce";
5
- var PKCE_COOKIE_PATH = "/auth";
6
- var PKCE_COOKIE_MAX_AGE_SECONDS = 600;
7
- function encodePkceState(state) {
8
- return encodeURIComponent(JSON.stringify(state));
9
- }
10
- function decodePkceState(raw) {
11
- try {
12
- const parsed = JSON.parse(decodeURIComponent(raw));
13
- if (typeof parsed?.verifier === "string" && typeof parsed.state === "string" && typeof parsed.returnTo === "string") {
14
- return { verifier: parsed.verifier, state: parsed.state, returnTo: parsed.returnTo };
15
- }
16
- } catch {
17
- }
18
- return null;
19
- }
20
-
21
- // src/internal/discovery.ts
22
- var DEFAULT_ISSUER = "https://api.cimplify.io";
23
- var DEFAULT_AUTHORIZATION_ENDPOINT = "https://auth.cimplify.io/oauth/authorize";
24
- function fallbackAuthorizationEndpoint(issuerBase) {
25
- if (issuerBase === DEFAULT_ISSUER) return DEFAULT_AUTHORIZATION_ENDPOINT;
26
- throw new Error(
27
- `OIDC discovery for "${issuerBase}" is unreachable and no fallback authorize endpoint is known for it. Make discovery reachable (enable CORS) or pass authUrl.`
28
- );
29
- }
30
- var cache = /* @__PURE__ */ new Map();
31
- function fetchDiscovery(issuer) {
32
- const base = issuer.replace(/\/$/, "");
33
- let pending = cache.get(base);
34
- if (!pending) {
35
- pending = fetch(`${base}/.well-known/openid-configuration`).then((res) => {
36
- if (!res.ok) throw new Error(`oidc discovery failed: ${res.status}`);
37
- return res.json();
38
- });
39
- pending.catch(() => cache.delete(base));
40
- cache.set(base, pending);
41
- }
42
- return pending;
43
- }
44
- async function getAuthorizationEndpoint(issuer) {
45
- const base = issuer.replace(/\/$/, "");
46
- try {
47
- const doc = await fetchDiscovery(base);
48
- if (doc.authorization_endpoint) return doc.authorization_endpoint;
49
- } catch {
50
- }
51
- return fallbackAuthorizationEndpoint(base);
52
- }
53
-
54
- exports.DEFAULT_ISSUER = DEFAULT_ISSUER;
55
- exports.PKCE_COOKIE = PKCE_COOKIE;
56
- exports.PKCE_COOKIE_MAX_AGE_SECONDS = PKCE_COOKIE_MAX_AGE_SECONDS;
57
- exports.PKCE_COOKIE_PATH = PKCE_COOKIE_PATH;
58
- exports.decodePkceState = decodePkceState;
59
- exports.encodePkceState = encodePkceState;
60
- exports.getAuthorizationEndpoint = getAuthorizationEndpoint;
@@ -1,15 +0,0 @@
1
- {
2
- "name": "account",
3
- "title": "CimplifyAccount",
4
- "description": "Iframe wrapper for the Cimplify account portal — sign-in, orders, addresses, settings.",
5
- "type": "component",
6
- "registryDependencies": [
7
- "cn"
8
- ],
9
- "files": [
10
- {
11
- "path": "account.tsx",
12
- "content": "\"use client\";\n\nimport React, { useEffect, useRef, useState, useMemo } from \"react\";\nimport type { CimplifyClient } from \"../client\";\nimport { useOptionalCimplify } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface CimplifyAccountProps {\n /** CimplifyClient instance. Falls back to provider context. */\n client?: CimplifyClient;\n /** Override the Link base URL. */\n linkUrl?: string;\n /** Initial section to show: \"dashboard\" | \"orders\" | \"addresses\" | \"payment-methods\" | \"sessions\" | \"settings\". */\n section?: string;\n /**\n * Per-merchant scope for the embedded account widget. When set, the\n * widget filters orders/subs/sessions to this business and hides\n * cross-merchant surfaces. Defaults to the client's configured\n * business ID so storefronts get scoping for free.\n */\n businessId?: string;\n /**\n * Display name of the embedding merchant — shown in the widget's\n * scoping footer (\"Showing your account with Acme Threads only.\").\n * Optional but recommended for trust signal.\n */\n merchantName?: string;\n /** Appearance variables — passed to Link for theming. */\n appearance?: {\n theme?: \"light\" | \"dark\";\n variables?: {\n primaryColor?: string;\n fontFamily?: string;\n borderRadius?: string;\n };\n };\n /** Called when the user logs out from the account portal. */\n onLogout?: () => void;\n /** Additional CSS class for the container. */\n className?: string;\n}\n\nconst DEFAULT_LINK_URL = \"https://link.cimplify.io\";\n\nexport function CimplifyAccount({\n client: clientProp,\n linkUrl,\n section,\n businessId: businessIdProp,\n merchantName,\n appearance,\n onLogout,\n className,\n}: CimplifyAccountProps): React.ReactElement {\n const context = useOptionalCimplify();\n const client = clientProp ?? context?.client;\n const resolvedLinkUrl = linkUrl || DEFAULT_LINK_URL;\n const resolvedBusinessId = businessIdProp || client?.getBusinessId?.() || \"\";\n\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const [height, setHeight] = useState(400);\n const [isReady, setIsReady] = useState(false);\n\n const iframeSrc = useMemo(() => {\n const path = section ? `/elements/account/${section}` : \"/elements/account\";\n const url = new URL(path, resolvedLinkUrl);\n if (resolvedBusinessId) url.searchParams.set(\"businessId\", resolvedBusinessId);\n return url.toString();\n }, [resolvedLinkUrl, section, resolvedBusinessId]);\n\n // Listen for messages from the iframe\n useEffect(() => {\n function handleMessage(event: MessageEvent) {\n if (!event.data || typeof event.data !== \"object\") return;\n\n // Only accept messages from our iframe\n if (iframeRef.current?.contentWindow && event.source !== iframeRef.current.contentWindow) {\n return;\n }\n\n switch (event.data.type) {\n case \"ready\":\n setIsReady(true);\n if (typeof event.data.height === \"number\") {\n setHeight(event.data.height);\n }\n // Send init with token + appearance\n sendInit();\n break;\n\n case \"height_change\":\n if (typeof event.data.height === \"number\") {\n setHeight(event.data.height);\n }\n break;\n\n case \"logout_complete\":\n onLogout?.();\n break;\n }\n }\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [appearance, client, onLogout]);\n\n function sendInit() {\n const contentWindow = iframeRef.current?.contentWindow;\n if (!contentWindow) return;\n\n const token = client?.getAccessToken?.();\n contentWindow.postMessage(\n {\n type: \"init\",\n token: token ?? undefined,\n appearance: appearance ?? undefined,\n businessId: resolvedBusinessId || undefined,\n merchantName: merchantName ?? undefined,\n },\n resolvedLinkUrl,\n );\n }\n\n return (\n <div\n data-cimplify-account\n className={cn(\"relative overflow-hidden\", className)}\n >\n {!isReady && (\n <div className=\"flex items-center justify-center py-16\">\n <div className=\"w-6 h-6 border-2 border-border border-t-foreground rounded-full animate-spin\" />\n </div>\n )}\n <iframe\n ref={iframeRef}\n src={iframeSrc}\n style={{\n border: \"none\",\n width: \"100%\",\n height: `${height}px`,\n display: isReady ? \"block\" : \"none\",\n overflow: \"hidden\",\n background: \"transparent\",\n }}\n allow=\"geolocation\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox\"\n />\n </div>\n );\n}\n"
13
- }
14
- ]
15
- }