@salla.sa/embedded-sdk 0.2.5 → 0.2.7
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 +1 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +416 -270
- package/dist/esm/index.js.map +1 -1
- package/dist/system/index.js +2 -2
- package/dist/system/index.js.map +1 -1
- package/dist/types/index.d.ts +83 -22
- package/dist/umd/index.js +2 -2
- package/dist/umd/index.js.map +1 -1
- package/package.json +1 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -66,6 +66,14 @@ declare interface BreadcrumbsSubModule {
|
|
|
66
66
|
show(): void;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Open a checkout that was created server-side (via the public API).
|
|
71
|
+
*/
|
|
72
|
+
export declare interface CheckoutByIdInput {
|
|
73
|
+
/** Server-created checkout ID (max 64 chars, `A-Za-z0-9_-`) */
|
|
74
|
+
checkout_id: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
69
77
|
/**
|
|
70
78
|
* Optional configuration for checkout creation.
|
|
71
79
|
*/
|
|
@@ -75,6 +83,13 @@ export declare interface CheckoutCreateConfig {
|
|
|
75
83
|
context?: unknown;
|
|
76
84
|
}
|
|
77
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Error thrown by checkout.create() when the input is malformed.
|
|
88
|
+
*/
|
|
89
|
+
export declare type CheckoutInputError = Error & {
|
|
90
|
+
code: "INVALID_CHECKOUT_INPUT";
|
|
91
|
+
};
|
|
92
|
+
|
|
78
93
|
/**
|
|
79
94
|
* @fileoverview Type definitions for the checkout module.
|
|
80
95
|
*/
|
|
@@ -99,7 +114,10 @@ export declare interface CheckoutModule {
|
|
|
99
114
|
*
|
|
100
115
|
* Accepts a single item or an array of items for multi-item checkout.
|
|
101
116
|
*
|
|
102
|
-
*
|
|
117
|
+
* Also accepts `{ checkout_id }` to open a checkout created server-side.
|
|
118
|
+
* Results arrive through `onResult` (with `checkout_id` echoed).
|
|
119
|
+
*
|
|
120
|
+
* @param input - Single checkout item, array of items, or `{ checkout_id }`
|
|
103
121
|
* @param config - Optional configuration
|
|
104
122
|
*
|
|
105
123
|
* @example
|
|
@@ -115,9 +133,15 @@ export declare interface CheckoutModule {
|
|
|
115
133
|
* { type: "addon", slug: "premium-analytics", quantity: 2 },
|
|
116
134
|
* { type: "addon", slug: "extra-storage" },
|
|
117
135
|
* ]);
|
|
136
|
+
*
|
|
137
|
+
* // Server-created checkout
|
|
138
|
+
* embedded.checkout.create(
|
|
139
|
+
* { checkout_id: "1078799918" },
|
|
140
|
+
* { context: { route: "/billing" } },
|
|
141
|
+
* );
|
|
118
142
|
* ```
|
|
119
143
|
*/
|
|
120
|
-
create(input: CheckoutItem | CheckoutItem[], config?: CheckoutCreateConfig): void;
|
|
144
|
+
create(input: CheckoutItem | CheckoutItem[] | CheckoutByIdInput, config?: CheckoutCreateConfig): void;
|
|
121
145
|
/**
|
|
122
146
|
* Subscribe to checkout results.
|
|
123
147
|
* Context from create() is returned here after 3DS redirect.
|
|
@@ -177,13 +201,15 @@ export declare interface CheckoutResult {
|
|
|
177
201
|
order_id?: string;
|
|
178
202
|
/** Payment status */
|
|
179
203
|
status: "paid" | "pending" | "failed" | "cancelled" | "success";
|
|
180
|
-
/** Error details if failed */
|
|
204
|
+
/** Error details if failed. Known codes include `CHECKOUT_NOT_FOUND`. */
|
|
181
205
|
error?: {
|
|
182
|
-
code: string;
|
|
206
|
+
code: "CHECKOUT_NOT_FOUND" | (string & {});
|
|
183
207
|
message: string;
|
|
184
208
|
};
|
|
185
209
|
/** Developer context passed to create(), restored after 3DS redirect */
|
|
186
210
|
context?: unknown;
|
|
211
|
+
/** Checkout ID echoed by the host (when opened by `checkout_id`) */
|
|
212
|
+
checkout_id?: string;
|
|
187
213
|
}
|
|
188
214
|
|
|
189
215
|
/**
|
|
@@ -381,6 +407,9 @@ declare interface IntrospectResponseData {
|
|
|
381
407
|
exp: string;
|
|
382
408
|
}
|
|
383
409
|
|
|
410
|
+
/** Error code thrown for malformed create() input */
|
|
411
|
+
export declare const INVALID_CHECKOUT_INPUT = "INVALID_CHECKOUT_INPUT";
|
|
412
|
+
|
|
384
413
|
/**
|
|
385
414
|
* Layout information from the host.
|
|
386
415
|
*/
|
|
@@ -425,34 +454,65 @@ declare interface LoadingSubModule {
|
|
|
425
454
|
|
|
426
455
|
/** Result of addItem promise */
|
|
427
456
|
declare interface NavItemAddResult {
|
|
457
|
+
value: string;
|
|
458
|
+
/**
|
|
459
|
+
* @deprecated Same string as `value`. Prefer `value` for update/remove/click handling.
|
|
460
|
+
*/
|
|
428
461
|
id: string;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* One submenu row; must not include nested `children`.
|
|
466
|
+
*/
|
|
467
|
+
export declare interface NavItemChildInput {
|
|
468
|
+
title: string;
|
|
429
469
|
value: string;
|
|
470
|
+
url: string;
|
|
471
|
+
disabled?: boolean;
|
|
472
|
+
active?: boolean;
|
|
430
473
|
}
|
|
431
474
|
|
|
432
475
|
/** Callback when injected nav item is clicked */
|
|
433
476
|
declare type NavItemClickCallback = (payload: {
|
|
434
|
-
id: string;
|
|
435
477
|
value: string;
|
|
436
478
|
url: string;
|
|
479
|
+
/**
|
|
480
|
+
* @deprecated Same string as `value`.
|
|
481
|
+
*/
|
|
482
|
+
id: string;
|
|
437
483
|
}) => void;
|
|
438
484
|
|
|
439
|
-
/**
|
|
440
|
-
declare
|
|
485
|
+
/** @alias NavItemNodeInput — root add payload */
|
|
486
|
+
export declare type NavItemInput = NavItemNodeInput;
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Sub-navigation node injected into the host sub-nav.
|
|
490
|
+
* Optional `children` renders as a single hover/click dropdown level (host UI).
|
|
491
|
+
* Nested children under a child are not supported.
|
|
492
|
+
*/
|
|
493
|
+
export declare interface NavItemNodeInput {
|
|
441
494
|
title: string;
|
|
442
495
|
value: string;
|
|
443
496
|
url: string;
|
|
444
497
|
disabled?: boolean;
|
|
445
498
|
active?: boolean;
|
|
499
|
+
/** One level of submenu items only; must not contain further `children`. */
|
|
500
|
+
children?: NavItemChildInput[];
|
|
446
501
|
}
|
|
447
502
|
|
|
448
|
-
/**
|
|
503
|
+
/**
|
|
504
|
+
* Patch for an injected parent or child row.
|
|
505
|
+
* Identified by `value` (immutable). Optional `children` replaces the full
|
|
506
|
+
* dropdown list when patching a parent; ignored for child rows.
|
|
507
|
+
*/
|
|
449
508
|
declare interface NavItemPatchInput {
|
|
450
|
-
|
|
509
|
+
value: string;
|
|
451
510
|
title?: string;
|
|
452
|
-
value?: string;
|
|
453
511
|
url?: string;
|
|
454
512
|
disabled?: boolean;
|
|
455
513
|
active?: boolean;
|
|
514
|
+
/** Parent only: replaces entire children list when set. */
|
|
515
|
+
children?: NavItemChildInput[];
|
|
456
516
|
}
|
|
457
517
|
|
|
458
518
|
/**
|
|
@@ -513,9 +573,9 @@ export declare interface NavModule {
|
|
|
513
573
|
*/
|
|
514
574
|
onActionClick(callback: ActionClickCallback): Unsubscribe;
|
|
515
575
|
/**
|
|
516
|
-
* Inject one sub-navigation item beside API-driven items. Resolves with
|
|
517
|
-
*
|
|
518
|
-
*
|
|
576
|
+
* Inject one sub-navigation item beside API-driven items. Resolves with the
|
|
577
|
+
* item's `value` (and deprecated `id` equal to `value`). Rejects after 2s if
|
|
578
|
+
* the host does not acknowledge.
|
|
519
579
|
*
|
|
520
580
|
* @example
|
|
521
581
|
* ```typescript
|
|
@@ -524,36 +584,37 @@ export declare interface NavModule {
|
|
|
524
584
|
* value: 'reports',
|
|
525
585
|
* url: '/apps/installed/my-app/reports',
|
|
526
586
|
* });
|
|
527
|
-
* console.log(tab.
|
|
587
|
+
* console.log(tab.value); // use for update/remove
|
|
528
588
|
* ```
|
|
529
589
|
*/
|
|
530
590
|
addNavItem(item: NavItemInput): Promise<NavItemAddResult>;
|
|
531
591
|
/**
|
|
532
|
-
* Patch a previously injected
|
|
533
|
-
*
|
|
592
|
+
* Patch a previously injected parent or child by `value` (unknown values are
|
|
593
|
+
* ignored by the host). Optional `children` on a parent replaces the full list.
|
|
534
594
|
*
|
|
535
595
|
* @example
|
|
536
596
|
* ```typescript
|
|
537
|
-
* embedded.nav.updateNavItem({
|
|
538
|
-
* embedded.nav.updateNavItem({
|
|
597
|
+
* embedded.nav.updateNavItem({ value: 'reports', disabled: true });
|
|
598
|
+
* embedded.nav.updateNavItem({ value: 'reports', title: 'Updated title' });
|
|
539
599
|
* ```
|
|
540
600
|
*/
|
|
541
601
|
updateNavItem(item: NavItemPatchInput): void;
|
|
542
602
|
/**
|
|
543
|
-
* Remove an injected
|
|
603
|
+
* Remove an injected parent or child by its `value` (unknown values are ignored).
|
|
604
|
+
* Removing a parent removes its children.
|
|
544
605
|
*
|
|
545
606
|
* @example
|
|
546
607
|
* ```typescript
|
|
547
|
-
* embedded.nav.removeNavItem(
|
|
608
|
+
* embedded.nav.removeNavItem('reports');
|
|
548
609
|
* ```
|
|
549
610
|
*/
|
|
550
|
-
removeNavItem(
|
|
611
|
+
removeNavItem(value: string): void;
|
|
551
612
|
/**
|
|
552
613
|
* Subscribe to clicks on injected sub-nav items from the merchant dashboard chrome.
|
|
553
614
|
*
|
|
554
615
|
* @example
|
|
555
616
|
* ```typescript
|
|
556
|
-
* const unsubscribe = embedded.nav.onNavItemClick(({
|
|
617
|
+
* const unsubscribe = embedded.nav.onNavItemClick(({ value, url }) => {
|
|
557
618
|
* console.log('clicked tab', value, '->', url);
|
|
558
619
|
* });
|
|
559
620
|
* ```
|
package/dist/umd/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(f,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(f=typeof globalThis<"u"?globalThis:f||self,a(f.SallaEmbeddedSDK={}))})(this,(function(f){"use strict";const a="embedded::",C={INIT:`${a}iframe.ready`,READY:`${a}ready`,DESTROY:`${a}destroy`},x={PROVIDE:`${a}context.provide`,THEME_CHANGE:`${a}theme.change`},p={LOADING:`${a}ui.loading`,BREADCRUMBS:`${a}ui.breadcrumbs`,TOAST:`${a}ui.toast`,CONFIRM:`${a}ui.confirm`,CONFIRM_RESPONSE:`${a}ui.confirm.response`},B={},k={REFRESH:`${a}auth.refresh`},v={NAVIGATE:`${a}page.navigate`,REDIRECT:`${a}page.redirect`,SET_TITLE:`${a}page.setTitle`},c={SET_ACTION:`${a}nav.setAction`,CLEAR_ACTION:`${a}nav.clearAction`,ACTION_CLICK:`${a}nav.actionClick`,ADD_ITEM:`${a}nav.addItem`,ADD_ITEM_RESPONSE:`${a}nav.addItem.response`,UPDATE_ITEM:`${a}nav.updateItem`,REMOVE_ITEM:`${a}nav.removeItem`,ITEM_CLICK:`${a}nav.itemClick`},b={CREATE:`${a}checkout.create`,RESPONSE:`${a}checkout.response`,GET_ADDONS:`${a}checkout.getAddons`,GET_ADDONS_RESPONSE:`${a}checkout.getAddons.response`,RESET_CACHE:`${a}checkout.resetCache`},I=B.version||"",X=1e4,W=["localhost","merchants.workers.dev","s.salla.sa",".salla.group",".salla.sa"],Y=new Set(["ar","he","fa","ur","ps","sd","yi"]);function Q(t){const e=(t??"ar").toLowerCase().split(/[-_]/)[0];return Y.has(e)?"rtl":"ltr"}let A={showVersion:!0,debug:!1};function J(t){A={...A,...t}}function q(t){return`%c${t}`}function P(t,e="#fff"){return`background-color: ${t}; color: ${e}; padding: 2px 6px; border-radius: 3px; font-weight: 500; font-size: 11px;`}function T(t,...e){if(t==="debug"&&!A.debug)return;const r=[],i=[];r.push(q("EmbeddedSDK")),i.push(P("#10b981","#fff")),A.showVersion&&(r.push(q(`v${I}`)),i.push(P("#6b7280","#fff")));const n=r.join("").trim();(console[t]||console.log)(n,...i,...e)}const o={log:(...t)=>{T("log",...t)},warn:(...t)=>{T("warn",...t)},error:(...t)=>{T("error",...t)},info:(...t)=>{T("info",...t)},debug:(...t)=>{T("debug",...t)}};function Z(t){try{const r=new URL(t).hostname;return W.some(i=>i.startsWith(".")?r.endsWith(i)||r===i.slice(1):r===i||r.startsWith(`${i}:`))}catch{return!1}}function ee(){return typeof window>"u"||window.parent===window?null:window.parent}function u(t,e,r="*",i,n){const s=ee();if(!s){o.warn("Not running in an iframe, cannot post to host");return}const d={event:t,payload:e||{},timestamp:Date.now(),source:"embedded-app",...i&&{requestId:i},metadata:{version:I}};s.postMessage(d,r)}const m=new Map;let R=!1;function z(t){if(process.env.NODE_ENV==="production"&&!Z(t.origin))return;const e=t.data;if(!e||typeof e.event!="string"||!e.payload||typeof e.timestamp!="number"||!e.source){o.warn("Invalid message structure received:",e);return}const r=m.get(e.event);r&&r.forEach(n=>{try{n(e)}catch(s){o.error("Error in message handler:",s)}});const i=m.get("*");i&&i.forEach(n=>{try{n(e)}catch(s){o.error("Error in wildcard handler:",s)}})}function te(){R||typeof window>"u"||(window.addEventListener("message",z),R=!0)}function g(t,e){te(),m.has(t)||m.set(t,new Set);const r=m.get(t);return r.add(e),()=>{r.delete(e),r.size===0&&m.delete(t)}}function re(t,e=X){return new Promise((r,i)=>{const n=setTimeout(()=>{s(),i(new Error(`[EmbeddedSDK] Timeout waiting for "${t}" message`))},e),s=g(t,d=>{clearTimeout(n),s(),r(d)})})}function ie(){m.clear(),R&&typeof window<"u"&&(window.removeEventListener("message",z),R=!1)}function ne(){return typeof window>"u"?!1:window.parent!==window}function se(t,e,r){const i={event:t,payload:e,timestamp:Date.now(),source:"merchant-dashboard",...r,metadata:{version:I,synthetic:!0}};m.get(t)?.forEach(s=>{try{s(i)}catch(d){o.error("Error in message handler:",d)}})}const E=new Map,ae=3e4;function U(){const t=Date.now(),e=Math.random().toString(36).slice(2,9);return`req_${t}_${e}`}function _(t,e={},r=ae){const i=U();return new Promise((n,s)=>{const d=setTimeout(()=>{E.get(i)&&(E.delete(i),s(new Error(`[EmbeddedSDK] Request "${t}" timed out after ${r}ms`)))},r);E.set(i,{resolve:n,reject:s,timeout:d,event:t}),u(t,e,"*",i)})}function $(t,e,r){const i=E.get(t);if(!i){o.warn(`Received response for unknown request: ${t}`);return}clearTimeout(i.timeout),E.delete(t),i.resolve(e)}function oe(t="SDK cleanup"){E.forEach((e,r)=>{clearTimeout(e.timeout),e.reject(new Error(`[EmbeddedSDK] Request ${r} cancelled: ${t}`))}),E.clear()}function w(){const t=new Set;return{subscribe(e){return t.add(e),()=>{t.delete(e)}},notify(...e){t.forEach(r=>{try{r(...e)}catch(i){o.error("Error in subscription callback:",i)}})},clear(){t.clear()},size(){return t.size}}}const ue="https://api.salla.dev";class S extends Error{constructor(e,r,i){super(e),this.status=r,this.response=i,this.name="ApiError"}}async function de(t,e={}){const{method:r="GET",headers:i={},body:n,timeout:s=3e4}=e,d=`${ue}${t}`,L=new AbortController,K=setTimeout(()=>{L.abort()},s);try{const l=await fetch(d,{method:r,headers:{"Content-Type":"application/json",...i},body:n?JSON.stringify(n):void 0,signal:L.signal});clearTimeout(K);let N;if(l.headers.get("content-type")?.includes("application/json")?N=await l.json():N=await l.text(),!l.ok)throw new S(`API request failed: ${l.statusText}`,l.status,N);return N}catch(l){throw clearTimeout(K),l instanceof S?l:l instanceof Error?l.name==="AbortError"?new S(`Request timeout after ${s}ms`):new S(`Request failed: ${l.message}`):new S("Unknown error occurred")}}function D(t){return{isVerified:!1,isError:!0,error:t,data:null}}async function ce(t){const{token:e,appId:r,refreshOnError:i=!0}=t;if(!e){const n="Token is required. Provide it as a parameter or in URL as ?token=XXX";return o.error("Error in introspect:",n),D(n)}if(!r){const n="App ID is required. Provide it as a parameter or in URL as ?app_id=XXX";return o.error("Error in introspect:",n),D(n)}try{const n=await de("/exchange-authority/v1/introspect",{method:"POST",headers:{"S-Source":r,"Content-Type":"application/json"},body:{env:"prod",token:e,iss:"merchant-dashboard",subject:"embedded-page"}}),s=n.success;return{isVerified:s,isError:!s,error:s?void 0:"API request failed",data:s?n.data:null}}catch(n){i&&(M().ui.toast.error(n?.toString()??"Introspect error"),u(k.REFRESH,{})),o.error("Error in introspect:",n);const s=n instanceof Error?n.message:n;return D(s)}}function le(t){return{getToken(){return new URLSearchParams(window.location.search).get("token")},getAppId(){return new URLSearchParams(window.location.search).get("app_id")},refresh(){u(k.REFRESH,{})},async introspect(e={}){const r=e.token??this.getToken()??"",i=e.appId??this.getAppId()??"";return ce({token:r,appId:i,refreshOnError:e.refreshOnError})}}}const V=["success","error","warning","info"];function fe(t){const e=[];return t.type===void 0||t.type===null?e.push("Toast type is required"):(typeof t.type!="string"||!V.includes(t.type))&&e.push(`Invalid toast type "${t.type}". Expected: ${V.join(" | ")}`),t.message===void 0||t.message===null?e.push("Toast message is required"):typeof t.message!="string"?e.push("Toast message must be a string"):t.message.trim()===""&&e.push("Toast message cannot be empty"),t.duration!==void 0&&t.duration!==null&&(typeof t.duration!="number"?e.push("Toast duration must be a number"):t.duration<0&&e.push("Toast duration cannot be negative")),{valid:e.length===0,errors:e}}function j(t,e){const r=[];return typeof t!="object"||t===null?(r.push(`${e} must be an object`),r):((typeof t.type!="string"||t.type.trim()==="")&&r.push(`${e} must have a valid type`),(typeof t.slug!="string"||t.slug.trim()==="")&&r.push(`${e} must have a valid slug`),t.quantity!==void 0&&(typeof t.quantity!="number"||t.quantity<1)&&r.push(`${e} must have a quantity >= 1`),r)}function he(t){const e=[];if(typeof t!="object"||t===null)return e.push("Checkout options must be an object"),{valid:!1,errors:e};const r="item"in t,i="items"in t;if(!r&&!i)return e.push("Checkout requires either 'item' or 'items'"),{valid:!1,errors:e};if(r){const n=j(t.item,"Item");return e.push(...n),{valid:e.length===0,errors:e}}return Array.isArray(t.items)?t.items.length===0?(e.push("At least one item is required"),{valid:!1,errors:e}):(t.items.forEach((n,s)=>{const d=j(n,`Item at index ${s}`);e.push(...d)}),{valid:e.length===0,errors:e}):(e.push("Checkout items must be an array"),{valid:!1,errors:e})}function pe(t){const e=[];return t.path===void 0||t.path===null?e.push("Navigation path is required"):typeof t.path!="string"?e.push("Navigation path must be a string"):t.path.trim()===""&&e.push("Navigation path cannot be empty"),t.replace!==void 0&&typeof t.replace!="boolean"&&e.push("Navigation replace option must be a boolean"),{valid:e.length===0,errors:e}}function me(t){const e=[];if(t.url===void 0||t.url===null)e.push("Redirect URL is required");else if(typeof t.url!="string")e.push("Redirect URL must be a string");else if(t.url.trim()==="")e.push("Redirect URL cannot be empty");else try{new URL(t.url)}catch{e.push(`Invalid redirect URL: "${t.url}"`)}return{valid:e.length===0,errors:e}}function ge(t){const e=[];return t.title?typeof t.title!="string"&&e.push("Nav action title must be a string"):e.push("Nav action title is required"),t.value?typeof t.value!="string"&&e.push("Nav action value must be a string"):e.push("Nav action value is required"),t.subTitle!==void 0&&t.subTitle!==null&&typeof t.subTitle!="string"&&e.push("Nav action subTitle must be a string"),t.icon!==void 0&&t.icon!==null&&typeof t.icon!="string"&&e.push("Nav action icon must be a string"),t.disabled!==void 0&&t.disabled!==null&&typeof t.disabled!="boolean"&&e.push("Nav action disabled must be a boolean"),t.extendedActions!==void 0&&t.extendedActions!==null&&(Array.isArray(t.extendedActions)?t.extendedActions.forEach((r,i)=>{if(typeof r!="object"||r===null){e.push(`Extended action at index ${i} must be an object`);return}const n=r;(!n.title||typeof n.title!="string")&&e.push(`Extended action at index ${i} is missing required "title" property`),(!n.value||typeof n.value!="string")&&e.push(`Extended action at index ${i} is missing required "value" property`),n.subTitle!==void 0&&typeof n.subTitle!="string"&&e.push(`Extended action at index ${i} subTitle must be a string`),n.icon!==void 0&&typeof n.icon!="string"&&e.push(`Extended action at index ${i} icon must be a string`),n.disabled!==void 0&&typeof n.disabled!="boolean"&&e.push(`Extended action at index ${i} disabled must be a boolean`)}):e.push("Nav action extendedActions must be an array")),{valid:e.length===0,errors:e}}function be(t){const e=[];if(typeof t!="object"||t===null)return e.push("Nav addItem expects an object item"),{valid:!1,errors:e};const r=t;return["title","value","url"].forEach(i=>{(typeof r[i]!="string"||!String(r[i]).trim())&&e.push(`Sub-nav addItem "${i}" must be non-empty string`)}),r.disabled!==void 0&&typeof r.disabled!="boolean"&&e.push('Sub-nav addItem "disabled" must be boolean'),r.active!==void 0&&typeof r.active!="boolean"&&e.push('Sub-nav addItem "active" must be boolean'),{valid:e.length===0,errors:e}}function Ee(t){const e=[];if(typeof t!="object"||t===null)return e.push("Nav updateItem expects an object item"),{valid:!1,errors:e};const r=t;if(typeof r.id!="string"||!r.id.trim())return e.push('Sub-nav updateItem requires string "id"'),{valid:!1,errors:e};let i=0;return r.title!==void 0&&i++,r.value!==void 0&&i++,r.url!==void 0&&i++,r.disabled!==void 0&&i++,r.active!==void 0&&i++,i===0?(e.push("Sub-nav updateItem must include at least one of title, value, url, disabled, active"),{valid:!1,errors:e}):(["title","value","url"].forEach(n=>{r[n]!==void 0&&(typeof r[n]!="string"||!r[n].trim())&&e.push(`Sub-nav updateItem "${n}" must be non-empty`)}),r.disabled!==void 0&&typeof r.disabled!="boolean"&&e.push('Sub-nav updateItem "disabled" must be boolean'),r.active!==void 0&&typeof r.active!="boolean"&&e.push('Sub-nav updateItem "active" must be boolean'),{valid:e.length===0,errors:e})}function ve(t){const e=[];return(typeof t!="string"||!t.trim())&&e.push("Nav removeItem id must be non-empty string"),{valid:e.length===0,errors:e}}const F=["danger","warning","info"];function ye(t){const e=[];return t.title===void 0||t.title===null?e.push("Confirm dialog title is required"):typeof t.title!="string"?e.push("Confirm dialog title must be a string"):t.title.trim()===""&&e.push("Confirm dialog title cannot be empty"),t.message===void 0||t.message===null?e.push("Confirm dialog message is required"):typeof t.message!="string"?e.push("Confirm dialog message must be a string"):t.message.trim()===""&&e.push("Confirm dialog message cannot be empty"),t.confirmText!==void 0&&t.confirmText!==null&&typeof t.confirmText!="string"&&e.push("Confirm dialog confirmText must be a string"),t.cancelText!==void 0&&t.cancelText!==null&&typeof t.cancelText!="string"&&e.push("Confirm dialog cancelText must be a string"),t.variant!==void 0&&t.variant!==null&&(typeof t.variant!="string"||!F.includes(t.variant))&&e.push(`Invalid confirm variant "${t.variant}". Expected: ${F.join(" | ")}`),{valid:e.length===0,errors:e}}function h(t,e){o.error(`Validation failed for ${t}:
|
|
1
|
+
(function(m,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(m=typeof globalThis<"u"?globalThis:m||self,o(m.SallaEmbeddedSDK={}))})(this,(function(m){"use strict";const o="embedded::",L={INIT:`${o}iframe.ready`,READY:`${o}ready`,DESTROY:`${o}destroy`},K={PROVIDE:`${o}context.provide`,THEME_CHANGE:`${o}theme.change`},v={LOADING:`${o}ui.loading`,BREADCRUMBS:`${o}ui.breadcrumbs`,TOAST:`${o}ui.toast`,CONFIRM:`${o}ui.confirm`,CONFIRM_RESPONSE:`${o}ui.confirm.response`},oe={},F={REFRESH:`${o}auth.refresh`},I={NAVIGATE:`${o}page.navigate`,REDIRECT:`${o}page.redirect`,SET_TITLE:`${o}page.setTitle`},h={SET_ACTION:`${o}nav.setAction`,CLEAR_ACTION:`${o}nav.clearAction`,ACTION_CLICK:`${o}nav.actionClick`,ADD_ITEM:`${o}nav.addItem`,ADD_ITEM_RESPONSE:`${o}nav.addItem.response`,UPDATE_ITEM:`${o}nav.updateItem`,REMOVE_ITEM:`${o}nav.removeItem`,ITEM_CLICK:`${o}nav.itemClick`},b={CREATE:`${o}checkout.create`,RESPONSE:`${o}checkout.response`,GET_ADDONS:`${o}checkout.getAddons`,GET_ADDONS_RESPONSE:`${o}checkout.getAddons.response`,RESET_CACHE:`${o}checkout.resetCache`},N=oe.version||"",ue=1e4,de=["localhost","merchants.workers.dev","s.salla.sa",".salla.group",".salla.sa"],ce=new Set(["ar","he","fa","ur","ps","sd","yi"]);function le(t){const e=(t??"ar").toLowerCase().split(/[-_]/)[0];return ce.has(e)?"rtl":"ltr"}let C={showVersion:!0,debug:!1};function fe(t){C={...C,...t}}function G(t){return`%c${t}`}function B(t,e="#fff"){return`background-color: ${t}; color: ${e}; padding: 2px 6px; border-radius: 3px; font-weight: 500; font-size: 11px;`}function A(t,...e){if(t==="debug"&&!C.debug)return;const r=[],i=[];r.push(G("EmbeddedSDK")),i.push(B("#10b981","#fff")),C.showVersion&&(r.push(G(`v${N}`)),i.push(B("#6b7280","#fff")));const n=r.join("").trim();(console[t]||console.log)(n,...i,...e)}const u={log:(...t)=>{A("log",...t)},warn:(...t)=>{A("warn",...t)},error:(...t)=>{A("error",...t)},info:(...t)=>{A("info",...t)},debug:(...t)=>{A("debug",...t)}};function he(t){try{const r=new URL(t).hostname;return de.some(i=>i.startsWith(".")?r.endsWith(i)||r===i.slice(1):r===i||r.startsWith(`${i}:`))}catch{return!1}}function me(){return typeof window>"u"||window.parent===window?null:window.parent}function c(t,e,r="*",i,n){const s=me();if(!s){u.warn("Not running in an iframe, cannot post to host");return}const a={event:t,payload:e||{},timestamp:Date.now(),source:"embedded-app",...i&&{requestId:i},metadata:{version:N}};s.postMessage(a,r)}const y=new Map;let $=!1;function X(t){if(process.env.NODE_ENV==="production"&&!he(t.origin))return;const e=t.data;if(!e||typeof e.event!="string"||!e.payload||typeof e.timestamp!="number"||!e.source){u.warn("Invalid message structure received:",e);return}const r=y.get(e.event);r&&r.forEach(n=>{try{n(e)}catch(s){u.error("Error in message handler:",s)}});const i=y.get("*");i&&i.forEach(n=>{try{n(e)}catch(s){u.error("Error in wildcard handler:",s)}})}function pe(){$||typeof window>"u"||(window.addEventListener("message",X),$=!0)}function E(t,e){pe(),y.has(t)||y.set(t,new Set);const r=y.get(t);return r.add(e),()=>{r.delete(e),r.size===0&&y.delete(t)}}function ge(t,e=ue){return new Promise((r,i)=>{const n=setTimeout(()=>{s(),i(new Error(`[EmbeddedSDK] Timeout waiting for "${t}" message`))},e),s=E(t,a=>{clearTimeout(n),s(),r(a)})})}function ve(){y.clear(),$&&typeof window<"u"&&(window.removeEventListener("message",X),$=!1)}function be(){return typeof window>"u"?!1:window.parent!==window}function ye(t,e,r){const i={event:t,payload:e,timestamp:Date.now(),source:"merchant-dashboard",...r,metadata:{version:N,synthetic:!0}};y.get(t)?.forEach(s=>{try{s(i)}catch(a){u.error("Error in message handler:",a)}})}const T=new Map,Ee=3e4;function W(){const t=Date.now(),e=Math.random().toString(36).slice(2,9);return`req_${t}_${e}`}function k(t,e={},r=Ee){const i=W();return new Promise((n,s)=>{const a=setTimeout(()=>{T.get(i)&&(T.delete(i),s(new Error(`[EmbeddedSDK] Request "${t}" timed out after ${r}ms`)))},r);T.set(i,{resolve:n,reject:s,timeout:a,event:t}),c(t,e,"*",i)})}function D(t,e,r){const i=T.get(t);if(!i){u.warn(`Received response for unknown request: ${t}`);return}clearTimeout(i.timeout),T.delete(t),r?i.reject(new Error(r)):i.resolve(e)}function Te(t="SDK cleanup"){T.forEach((e,r)=>{clearTimeout(e.timeout),e.reject(new Error(`[EmbeddedSDK] Request ${r} cancelled: ${t}`))}),T.clear()}function w(){const t=new Set;return{subscribe(e){return t.add(e),()=>{t.delete(e)}},notify(...e){t.forEach(r=>{try{r(...e)}catch(i){u.error("Error in subscription callback:",i)}})},clear(){t.clear()},size(){return t.size}}}const Ie="https://api.salla.dev";class R extends Error{constructor(e,r,i){super(e),this.status=r,this.response=i,this.name="ApiError"}}async function Se(t,e={}){const{method:r="GET",headers:i={},body:n,timeout:s=3e4}=e,a=`${Ie}${t}`,l=new AbortController,f=setTimeout(()=>{l.abort()},s);try{const d=await fetch(a,{method:r,headers:{"Content-Type":"application/json",...i},body:n?JSON.stringify(n):void 0,signal:l.signal});clearTimeout(f);let g;if(d.headers.get("content-type")?.includes("application/json")?g=await d.json():g=await d.text(),!d.ok)throw new R(`API request failed: ${d.statusText}`,d.status,g);return g}catch(d){throw clearTimeout(f),d instanceof R?d:d instanceof Error?d.name==="AbortError"?new R(`Request timeout after ${s}ms`):new R(`Request failed: ${d.message}`):new R("Unknown error occurred")}}function q(t){return{isVerified:!1,isError:!0,error:t,data:null}}async function Ae(t){const{token:e,appId:r,refreshOnError:i=!0}=t;if(!e){const n="Token is required. Provide it as a parameter or in URL as ?token=XXX";return u.error("Error in introspect:",n),q(n)}if(!r){const n="App ID is required. Provide it as a parameter or in URL as ?app_id=XXX";return u.error("Error in introspect:",n),q(n)}try{const n=await Se("/exchange-authority/v1/introspect",{method:"POST",headers:{"S-Source":r,"Content-Type":"application/json"},body:{env:"prod",token:e,iss:"merchant-dashboard",subject:"embedded-page"}}),s=n.success;return{isVerified:s,isError:!s,error:s?void 0:"API request failed",data:s?n.data:null}}catch(n){i&&(x().ui.toast.error(n?.toString()??"Introspect error"),c(F.REFRESH,{})),u.error("Error in introspect:",n);const s=n instanceof Error?n.message:n;return q(s)}}function we(t){return{getToken(){return new URLSearchParams(window.location.search).get("token")},getAppId(){return new URLSearchParams(window.location.search).get("app_id")},refresh(){c(F.REFRESH,{})},async introspect(e={}){const r=e.token??this.getToken()??"",i=e.appId??this.getAppId()??"";return Ae({token:r,appId:i,refreshOnError:e.refreshOnError})}}}const Y=["success","error","warning","info"];function Re(t){const e=[];return t.type===void 0||t.type===null?e.push("Toast type is required"):(typeof t.type!="string"||!Y.includes(t.type))&&e.push(`Invalid toast type "${t.type}". Expected: ${Y.join(" | ")}`),t.message===void 0||t.message===null?e.push("Toast message is required"):typeof t.message!="string"?e.push("Toast message must be a string"):t.message.trim()===""&&e.push("Toast message cannot be empty"),t.duration!==void 0&&t.duration!==null&&(typeof t.duration!="number"?e.push("Toast duration must be a number"):t.duration<0&&e.push("Toast duration cannot be negative")),{valid:e.length===0,errors:e}}function Q(t,e){const r=[];return typeof t!="object"||t===null?(r.push(`${e} must be an object`),r):((typeof t.type!="string"||t.type.trim()==="")&&r.push(`${e} must have a valid type`),(typeof t.slug!="string"||t.slug.trim()==="")&&r.push(`${e} must have a valid slug`),t.quantity!==void 0&&(typeof t.quantity!="number"||t.quantity<1)&&r.push(`${e} must have a quantity >= 1`),r)}const _e=/^[A-Za-z0-9_-]+$/,J=64,U="checkout_id cannot be combined with item or items";function Ne(t){return typeof t!="string"||t===""?["checkout_id must be a non-empty string"]:t.length>J?[`checkout_id must be at most ${J} characters`]:_e.test(t)?[]:["checkout_id may only contain letters, numbers, '_' and '-'"]}function Z(t){const e=[];if(typeof t!="object"||t===null)return e.push("Checkout options must be an object"),{valid:!1,errors:e};const r="item"in t,i="items"in t;if("checkout_id"in t)return r||i?(e.push(U),{valid:!1,errors:e}):(e.push(...Ne(t.checkout_id)),{valid:e.length===0,errors:e});if(!r&&!i)return e.push("Checkout requires either 'item' or 'items'"),{valid:!1,errors:e};if(r){const n=Q(t.item,"Item");return e.push(...n),{valid:e.length===0,errors:e}}return Array.isArray(t.items)?t.items.length===0?(e.push("At least one item is required"),{valid:!1,errors:e}):(t.items.forEach((n,s)=>{const a=Q(n,`Item at index ${s}`);e.push(...a)}),{valid:e.length===0,errors:e}):(e.push("Checkout items must be an array"),{valid:!1,errors:e})}function Ce(t){const e=[];return t.path===void 0||t.path===null?e.push("Navigation path is required"):typeof t.path!="string"?e.push("Navigation path must be a string"):t.path.trim()===""&&e.push("Navigation path cannot be empty"),t.replace!==void 0&&typeof t.replace!="boolean"&&e.push("Navigation replace option must be a boolean"),{valid:e.length===0,errors:e}}function $e(t){const e=[];if(t.url===void 0||t.url===null)e.push("Redirect URL is required");else if(typeof t.url!="string")e.push("Redirect URL must be a string");else if(t.url.trim()==="")e.push("Redirect URL cannot be empty");else try{new URL(t.url)}catch{e.push(`Invalid redirect URL: "${t.url}"`)}return{valid:e.length===0,errors:e}}function De(t){const e=[];return t.title?typeof t.title!="string"&&e.push("Nav action title must be a string"):e.push("Nav action title is required"),t.value?typeof t.value!="string"&&e.push("Nav action value must be a string"):e.push("Nav action value is required"),t.subTitle!==void 0&&t.subTitle!==null&&typeof t.subTitle!="string"&&e.push("Nav action subTitle must be a string"),t.icon!==void 0&&t.icon!==null&&typeof t.icon!="string"&&e.push("Nav action icon must be a string"),t.disabled!==void 0&&t.disabled!==null&&typeof t.disabled!="boolean"&&e.push("Nav action disabled must be a boolean"),t.extendedActions!==void 0&&t.extendedActions!==null&&(Array.isArray(t.extendedActions)?t.extendedActions.forEach((r,i)=>{if(typeof r!="object"||r===null){e.push(`Extended action at index ${i} must be an object`);return}const n=r;(!n.title||typeof n.title!="string")&&e.push(`Extended action at index ${i} is missing required "title" property`),(!n.value||typeof n.value!="string")&&e.push(`Extended action at index ${i} is missing required "value" property`),n.subTitle!==void 0&&typeof n.subTitle!="string"&&e.push(`Extended action at index ${i} subTitle must be a string`),n.icon!==void 0&&typeof n.icon!="string"&&e.push(`Extended action at index ${i} icon must be a string`),n.disabled!==void 0&&typeof n.disabled!="boolean"&&e.push(`Extended action at index ${i} disabled must be a boolean`)}):e.push("Nav action extendedActions must be an array")),{valid:e.length===0,errors:e}}const M=50;function O(t,e){return t?`${t}.${e}`:e}function Me(t,e){const r=[];["title","value","url"].forEach(s=>{(typeof t[s]!="string"||!String(t[s]).trim())&&r.push(`Sub-nav addItem "${O(e,s)}" must be non-empty string`)});const i=O(e,"disabled"),n=O(e,"active");return t.disabled!==void 0&&typeof t.disabled!="boolean"&&r.push(`Sub-nav addItem "${i}" must be boolean`),t.active!==void 0&&typeof t.active!="boolean"&&r.push(`Sub-nav addItem "${n}" must be boolean`),r}function V(t,e,r){if(typeof t!="object"||t===null)return[`Sub-nav addItem "${e||"item"}" must be an object`];const i=t,n=Me(i,e),s=O(e,"children");return i.children===void 0?n:r?Array.isArray(i.children)?i.children.length>M?(n.push(`Sub-nav addItem "${s}" must have at most ${M} items`),n):(i.children.forEach((a,l)=>{const f=e?`${e}.children[${l}]`:`children[${l}]`;n.push(...V(a,f,!1))}),n):(n.push(`Sub-nav addItem "${s}" must be an array`),n):(Array.isArray(i.children)&&i.children.length===0||n.push(`Sub-nav addItem "${s}" is not supported on submenu rows (only one dropdown level)`),n)}function ee(t,e,r,i){if(typeof t!="object"||t===null)return i;const n=t;return typeof n.value=="string"&&n.value.trim()&&i.push(n.value.trim()),!r||!Array.isArray(n.children)||n.children.forEach((s,a)=>{const l=e?`${e}.children[${a}]`:`children[${a}]`;ee(s,l,!1,i)}),i}function Oe(t){const e=ee(t,"",!0,[]),r=new Set,i=[];for(const n of e)r.has(n)&&i.push(n),r.add(n);return i.length===0?[]:[`Sub-nav addItem "value" must be globally unique within the item tree (duplicate: ${[...new Set(i)].join(", ")})`]}function Le(t){if(typeof t!="object"||t===null)return{valid:!1,errors:["Nav addItem expects an object item"]};const e=[...V(t,"",!0),...Oe(t)];return{valid:e.length===0,errors:e}}function ke(t){const e=[];if(typeof t!="object"||t===null)return e.push("Nav updateItem expects an object item"),{valid:!1,errors:e};const r=t,i=typeof r.value=="string"&&String(r.value).trim().length>0,n=typeof r.id=="string"&&String(r.id).trim().length>0,s=i?String(r.value).trim():"",a=n?String(r.id).trim():"";if(!i&&!n)return e.push('Sub-nav updateItem requires non-empty string "value"'),{valid:!1,errors:e};if(i&&n&&s!==a)return e.push('Sub-nav updateItem must not specify different "id" and "value"; "value" is the immutable row key and cannot be renamed via patch'),{valid:!1,errors:e};const l=s||a;let f=0;if(r.title!==void 0&&f++,r.url!==void 0&&f++,r.disabled!==void 0&&f++,r.active!==void 0&&f++,r.children!==void 0&&f++,f===0)return e.push("Sub-nav updateItem must include at least one of title, url, disabled, active, children"),{valid:!1,errors:e};if(["title","url"].forEach(d=>{r[d]!==void 0&&(typeof r[d]!="string"||!r[d].trim())&&e.push(`Sub-nav updateItem "${d}" must be non-empty`)}),r.disabled!==void 0&&typeof r.disabled!="boolean"&&e.push('Sub-nav updateItem "disabled" must be boolean'),r.active!==void 0&&typeof r.active!="boolean"&&e.push('Sub-nav updateItem "active" must be boolean'),r.children!==void 0)if(!Array.isArray(r.children))e.push('Sub-nav updateItem "children" must be an array');else if(r.children.length>M)e.push(`Sub-nav updateItem "children" must have at most ${M} items`);else{const d=new Set;r.children.forEach((g,ae)=>{const P=`children[${ae}]`;if(e.push(...V(g,P,!1)),typeof g=="object"&&g!==null){const j=g.value;if(typeof j=="string"&&j.trim()){const H=j.trim();H===l&&e.push(`Sub-nav updateItem "${P}.value" must not equal the parent row identifier`),d.has(H)&&e.push(`Sub-nav updateItem "${P}.value" must be unique within children`),d.add(H)}}})}return{valid:e.length===0,errors:e}}function qe(t){const e=[];return(typeof t!="string"||!t.trim())&&e.push("Nav removeItem value must be non-empty string"),{valid:e.length===0,errors:e}}const te=["danger","warning","info"];function Ue(t){const e=[];return t.title===void 0||t.title===null?e.push("Confirm dialog title is required"):typeof t.title!="string"?e.push("Confirm dialog title must be a string"):t.title.trim()===""&&e.push("Confirm dialog title cannot be empty"),t.message===void 0||t.message===null?e.push("Confirm dialog message is required"):typeof t.message!="string"?e.push("Confirm dialog message must be a string"):t.message.trim()===""&&e.push("Confirm dialog message cannot be empty"),t.confirmText!==void 0&&t.confirmText!==null&&typeof t.confirmText!="string"&&e.push("Confirm dialog confirmText must be a string"),t.cancelText!==void 0&&t.cancelText!==null&&typeof t.cancelText!="string"&&e.push("Confirm dialog cancelText must be a string"),t.variant!==void 0&&t.variant!==null&&(typeof t.variant!="string"||!te.includes(t.variant))&&e.push(`Invalid confirm variant "${t.variant}". Expected: ${te.join(" | ")}`),{valid:e.length===0,errors:e}}function p(t,e){u.error(`Validation failed for ${t}:
|
|
2
2
|
`+e.map(r=>` • ${r}`).join(`
|
|
3
|
-
`))}function
|
|
3
|
+
`))}function Ve(){return{resize:i=>{},autoResize:()=>{},stopAutoResize:()=>{}}}function xe(){const{resize:t,autoResize:e,stopAutoResize:r}=Ve();return{navigate(i,n){const s=Ce({path:i,...n});if(!s.valid){p(I.NAVIGATE,s.errors);return}c(I.NAVIGATE,{path:i,state:n?.state,replace:n?.replace})},redirect(i){const n=$e({url:i});if(!n.valid){p(I.REDIRECT,n.errors);return}c(I.REDIRECT,{url:i})},navTo(i,n){if(i.startsWith("http://")||i.startsWith("https://")){this.redirect(i);return}this.navigate(i,n)},setTitle(i){if(typeof i!="string"||!i.trim()){p(I.SET_TITLE,["Title must be a non-empty string"]);return}c(I.SET_TITLE,{title:i})},resize:t,autoResize:e,stopAutoResize:r}}function ze(){const t=w(),e=w(),r=[];return r.push(E(h.ACTION_CLICK,i=>{t.notify(i.payload.value)})),r.push(E(h.ADD_ITEM_RESPONSE,i=>{if(!i.requestId)return;const n=i.payload;if(typeof n.error=="string"&&n.error.trim()){const a=n.error.trim();u.warn(`embedded::nav.addItem failed: ${a}`),D(i.requestId,{},a);return}const s=n.item;if(s&&typeof s.value=="string"&&s.value.trim()){const a=s.value.trim(),l={value:a,id:a};D(i.requestId,l)}})),r.push(E(h.ITEM_CLICK,i=>{const n=i.payload,s=typeof n.value=="string"&&n.value.trim()?n.value.trim():typeof n.id=="string"&&n.id.trim()?n.id.trim():"";if(!s){e.notify(n);return}e.notify({...n,value:s,id:s})})),{setAction(i){const n=De(i);if(!n.valid){p(h.SET_ACTION,n.errors);return}c(h.SET_ACTION,{title:i.title,value:i.value,subTitle:i.subTitle,icon:i.icon,disabled:i.disabled,extendedActions:i.extendedActions?.map(s=>({title:s.title,value:s.value,subTitle:s.subTitle,icon:s.icon,disabled:s.disabled}))})},clearAction(){c(h.CLEAR_ACTION,{})},onActionClick(i){return t.subscribe(i)},addNavItem(i){const n=Le(i);return n.valid?k(h.ADD_ITEM,{item:i},2e3):(p(h.ADD_ITEM,n.errors),Promise.reject(new Error(n.errors[0])))},updateNavItem(i){const n=ke(i);if(!n.valid){p(h.UPDATE_ITEM,n.errors);return}const s=i,a=typeof s.value=="string"?s.value.trim():"",l=typeof s.id=="string"?s.id.trim():"",f=a||l,{id:d,...g}=s;c(h.UPDATE_ITEM,{item:{...g,value:f}})},removeNavItem(i){const n=qe(i);if(!n.valid){p(h.REMOVE_ITEM,n.errors);return}c(h.REMOVE_ITEM,{value:i})},onNavItemClick(i){return e.subscribe(i)},destroy(){r.forEach(i=>i()),r.length=0,t.clear(),e.clear()}}}function Pe(){return{show(){c(v.LOADING,{action:"show"})},hide(){c(v.LOADING,{action:"hide"})}}}function je(){return{hide(){c(v.BREADCRUMBS,{action:"hide"})},show(){c(v.BREADCRUMBS,{action:"show"})}}}function He(){const t=e=>{const r=Re(e);if(!r.valid){p(v.TOAST,r.errors);return}c(v.TOAST,{type:e.type,message:e.message,duration:e.duration})};return{show:t,success(e,r){t({type:"success",message:e,duration:r})},error(e,r){t({type:"error",message:e,duration:r})},warning(e,r){t({type:"warning",message:e,duration:r})},info(e,r){t({type:"info",message:e,duration:r})}}}function Ke(){return async t=>{const e=Ue(t);return e.valid?k(v.CONFIRM,{title:t.title,message:t.message,confirmText:t.confirmText??"Confirm",cancelText:t.cancelText??"Cancel",variant:t.variant??"info"}):(p(v.CONFIRM,e.errors),Promise.reject(new Error(e.errors.join(", "))))}}function Fe(){return{loading:Pe(),breadcrumbs:je(),toast:He(),confirm:Ke()}}const re="INVALID_CHECKOUT_INPUT";function _(t){const e=new Error(t);return e.code=re,e}const Ge=["type","slug","quantity"];function ie(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&"checkout_id"in t&&t.checkout_id!==void 0}function Be(){const t=w(),e=[];return e.push(E(b.RESPONSE,r=>{t.notify({success:r.payload.success,order_id:r.payload.order_id,checkout_id:r.payload.checkout_id,status:r.payload.status,error:r.payload.error,context:r.payload.context})})),e.push(E(b.GET_ADDONS_RESPONSE,r=>{r.requestId&&D(r.requestId,{success:r.payload.success,addons:r.payload.addons,error:r.payload.error})})),{create(r,i){if(Array.isArray(r)&&r.some(s=>ie(s)))throw _(U);let n;if(ie(r)){if("context"in r)throw _("context must be passed as the second argument (config.context)");if(Ge.some(a=>a in r))throw _(U);const s=Z(r);if(!s.valid)throw p(b.CREATE,s.errors),_(s.errors[0]);n={checkout_id:r.checkout_id}}else{const s=Array.isArray(r)?r:[r],a=Z({items:s});if(!a.valid)throw p(b.CREATE,a.errors),_(a.errors[0]);n={items:s.map(l=>({type:l.type,slug:l.slug,quantity:l.quantity??1}))}}c(b.CREATE,{...n,...i?.context!==void 0&&{context:i.context}},"*",W())},onResult(r){return t.subscribe(r)},async getAddons(){try{return await k(b.GET_ADDONS,{},3e4)}catch(r){return{success:!1,error:{code:"REQUEST_FAILED",message:r instanceof Error?r.message:"Unknown error"}}}},resetCache(){c(b.RESET_CACHE,{},"*")},destroy(){e.forEach(r=>r()),e.length=0,t.clear()}}}const ne={theme:"light",dir:"rtl",width:0,locale:"ar",currency:"SAR"};class se{constructor(){this.initialized=!1,this.initializing=!1,this.debugMode=!1,this.appReady=!1,this.layout={...ne},this.postInitHooks=[],this.themeSubscription=w(),this.initSubscription=w(),this.auth=we(),this.page=xe(),this.nav=ze(),this.ui=Fe(),this.checkout=Be(),this.registerPostInitHook(e=>{const r=e.payload.pendingCheckoutResult;r&&(u.debug("Dispatching pending checkout result:",r),queueMicrotask(()=>{ye(b.RESPONSE,{success:r.success,status:r.status,checkout_id:r.checkout_id,error:r.error,context:r.context})}))}),this.setupListeners()}registerPostInitHook(e){this.postInitHooks.push(e)}setupListeners(){E(K.THEME_CHANGE,e=>{this.layout.theme=e.payload.theme,u.debug("Theme changed:",e.payload.theme),this.themeSubscription.notify(e.payload.theme)}),E(v.CONFIRM_RESPONSE,e=>{u.debug("Received confirm response:",e),e.requestId&&D(e.requestId,{confirmed:e.payload.confirmed})})}getState(){return{ready:this.initialized,initializing:this.initializing,layout:{...this.layout}}}isReady(){return this.initialized}onThemeChange(e){return this.themeSubscription.subscribe(e)}onInit(e){if(this.initialized)try{e(this.getState())}catch(r){u.error("Error in init callback:",r)}return this.initSubscription.subscribe(e)}ready(){if(this.appReady){u.debug("App already signaled as ready");return}if(!this.initialized){u.warn("Cannot signal ready before init() is called");return}this.appReady=!0,c(L.READY,{}),u.debug("Sent ready signal to host")}async init(e={}){if(this.initialized)return u.debug("Already initialized, returning current layout"),{layout:{...this.layout}};if(this.initializing)return u.warn("Initialization already in progress"),new Promise(r=>{const i=this.onInit(n=>{i(),r({layout:{...n.layout}})})});this.initializing=!0,this.debugMode=e.debug??!1,fe({debug:this.debugMode}),be()||u.warn("Not running in an iframe. Some features may not work."),u.debug("Initializing SDK...");try{c(L.INIT,{height:document.documentElement.scrollHeight}),u.debug("Sent iframe.ready message, waiting for context...");const r=await ge(K.PROVIDE);u.debug("Received context from host:",r);const{layout:i}=r.payload;return this.layout={theme:i?.theme??"light",dir:i?.dir??le(i?.locale),width:i?.width??0,locale:i?.locale??"ar",currency:i?.currency??"SAR"},this.postInitHooks.forEach(n=>{try{n(r)}catch(s){u.error("Error in post-init hook:",s)}}),this.initialized=!0,this.initializing=!1,u.debug("Initialization complete. Layout:",this.layout),this.initSubscription.notify(this.getState()),{layout:{...this.layout}}}catch(r){throw this.initializing=!1,r}}destroy(){u.debug("Destroying SDK instance"),this.initialized&&(c(L.DESTROY,{}),u.debug("Sent destroy event to host")),this.checkout.destroy(),this.nav.destroy(),Te("SDK destroyed"),ve(),this.themeSubscription.clear(),this.initSubscription.clear(),this.postInitHooks=[],this.initialized=!1,this.initializing=!1,this.appReady=!1,this.layout={...ne}}}let S=null;function x(){return S||(S=new se),S}function Xe(){S&&(S.destroy(),S=null)}const z=x(),We=N;typeof window<"u"&&(window.salla=window.salla||window.Salla||{},window.Salla=window.salla,window.salla.embedded||(window.salla.embedded=z),window.Salla.embedded||(window.Salla.embedded=z)),m.EmbeddedApp=se,m.INVALID_CHECKOUT_INPUT=re,m.embedded=z,m.getEmbeddedApp=x,m.resetEmbeddedApp=Xe,m.version=We,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
|
|
4
4
|
//# sourceMappingURL=index.js.map
|