@salla.sa/embedded-sdk 0.2.4 → 0.2.5

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/dist/esm/index.js CHANGED
@@ -1,42 +1,52 @@
1
- const o = "embedded::", $ = {
1
+ const o = "embedded::", C = {
2
2
  /** Initialize handshake - iframe signals it's ready to receive context */
3
3
  INIT: `${o}iframe.ready`,
4
4
  /** App signals it's fully loaded and ready */
5
5
  READY: `${o}ready`,
6
6
  /** App requests to be destroyed and navigate away */
7
7
  DESTROY: `${o}destroy`
8
- }, x = {
8
+ }, O = {
9
9
  /** Context data provision */
10
10
  PROVIDE: `${o}context.provide`,
11
11
  /** Theme change notification */
12
12
  THEME_CHANGE: `${o}theme.change`
13
- }, g = {
13
+ }, h = {
14
14
  /** Set loading state */
15
15
  LOADING: `${o}ui.loading`,
16
+ /** Set breadcrumbs visibility state */
17
+ BREADCRUMBS: `${o}ui.breadcrumbs`,
16
18
  /** Show toast notification */
17
19
  TOAST: `${o}ui.toast`,
18
20
  /** Show confirm dialog (async request) */
19
21
  CONFIRM: `${o}ui.confirm`,
20
22
  /** Confirm dialog response (from host) */
21
23
  CONFIRM_RESPONSE: `${o}ui.confirm.response`
22
- }, K = {}, U = {
24
+ }, G = {}, V = {
23
25
  /** Request token refresh (re-renders iframe with new token) */
24
26
  REFRESH: `${o}auth.refresh`
25
- }, p = {
27
+ }, b = {
26
28
  /** Navigate using React Router (SPA navigation) */
27
29
  NAVIGATE: `${o}page.navigate`,
28
30
  /** Redirect using window.location (full page reload) */
29
31
  REDIRECT: `${o}page.redirect`,
30
32
  /** Set page title */
31
33
  SET_TITLE: `${o}page.setTitle`
32
- }, w = {
34
+ }, l = {
33
35
  /** Set primary action button in navbar */
34
36
  SET_ACTION: `${o}nav.setAction`,
35
37
  /** Clear the primary action button */
36
38
  CLEAR_ACTION: `${o}nav.clearAction`,
37
39
  /** Notification when action button is clicked (host → iframe) */
38
- ACTION_CLICK: `${o}nav.actionClick`
39
- }, m = {
40
+ ACTION_CLICK: `${o}nav.actionClick`,
41
+ /** Add one sub-navigation item (iframe → host) */
42
+ ADD_ITEM: `${o}nav.addItem`,
43
+ /** Ack with generated opaque id (host → iframe; request response) */
44
+ ADD_ITEM_RESPONSE: `${o}nav.addItem.response`,
45
+ UPDATE_ITEM: `${o}nav.updateItem`,
46
+ REMOVE_ITEM: `${o}nav.removeItem`,
47
+ /** Injected sub-nav item clicked (host → iframe) */
48
+ ITEM_CLICK: `${o}nav.itemClick`
49
+ }, g = {
40
50
  /** Create checkout flow */
41
51
  CREATE: `${o}checkout.create`,
42
52
  /** Checkout response from host */
@@ -44,14 +54,35 @@ const o = "embedded::", $ = {
44
54
  /** Get available addons for the app */
45
55
  GET_ADDONS: `${o}checkout.getAddons`,
46
56
  /** Get addons response from host */
47
- GET_ADDONS_RESPONSE: `${o}checkout.getAddons.response`
48
- }, I = K.version || "", X = 1e4, W = [
57
+ GET_ADDONS_RESPONSE: `${o}checkout.getAddons.response`,
58
+ /** Reset checkout cache on host */
59
+ RESET_CACHE: `${o}checkout.resetCache`
60
+ }, R = G.version || "", K = 1e4, B = [
49
61
  "localhost",
50
62
  "merchants.workers.dev",
51
63
  "s.salla.sa",
52
64
  ".salla.group",
53
65
  ".salla.sa"
54
- ];
66
+ ], X = /* @__PURE__ */ new Set([
67
+ "ar",
68
+ // Arabic
69
+ "he",
70
+ // Hebrew
71
+ "fa",
72
+ // Persian / Farsi
73
+ "ur",
74
+ // Urdu
75
+ "ps",
76
+ // Pashto
77
+ "sd",
78
+ // Sindhi
79
+ "yi"
80
+ // Yiddish
81
+ ]);
82
+ function W(t) {
83
+ const e = (t ?? "ar").toLowerCase().split(/[-_]/)[0];
84
+ return X.has(e) ? "rtl" : "ltr";
85
+ }
55
86
  let S = {
56
87
  showVersion: !0,
57
88
  debug: !1
@@ -59,77 +90,77 @@ let S = {
59
90
  function Y(t) {
60
91
  S = { ...S, ...t };
61
92
  }
62
- function D(t) {
93
+ function L(t) {
63
94
  return `%c${t}`;
64
95
  }
65
- function L(t, e = "#fff") {
96
+ function x(t, e = "#fff") {
66
97
  return `background-color: ${t}; color: ${e}; padding: 2px 6px; border-radius: 3px; font-weight: 500; font-size: 11px;`;
67
98
  }
68
- function b(t, ...e) {
99
+ function y(t, ...e) {
69
100
  if (t === "debug" && !S.debug)
70
101
  return;
71
102
  const r = [], i = [];
72
- r.push(D("EmbeddedSDK")), i.push(L("#10b981", "#fff")), S.showVersion && (r.push(D(`v${I}`)), i.push(L("#6b7280", "#fff")));
103
+ r.push(L("EmbeddedSDK")), i.push(x("#10b981", "#fff")), S.showVersion && (r.push(L(`v${R}`)), i.push(x("#6b7280", "#fff")));
73
104
  const n = r.join("").trim();
74
105
  (console[t] || console.log)(n, ...i, ...e);
75
106
  }
76
107
  const a = {
77
108
  log: (...t) => {
78
- b("log", ...t);
109
+ y("log", ...t);
79
110
  },
80
111
  warn: (...t) => {
81
- b("warn", ...t);
112
+ y("warn", ...t);
82
113
  },
83
114
  error: (...t) => {
84
- b("error", ...t);
115
+ y("error", ...t);
85
116
  },
86
117
  info: (...t) => {
87
- b("info", ...t);
118
+ y("info", ...t);
88
119
  },
89
120
  debug: (...t) => {
90
- b("debug", ...t);
121
+ y("debug", ...t);
91
122
  }
92
123
  };
93
- function B(t) {
124
+ function Q(t) {
94
125
  try {
95
126
  const r = new URL(t).hostname;
96
- return W.some((i) => i.startsWith(".") ? r.endsWith(i) || r === i.slice(1) : r === i || r.startsWith(`${i}:`));
127
+ return B.some((i) => i.startsWith(".") ? r.endsWith(i) || r === i.slice(1) : r === i || r.startsWith(`${i}:`));
97
128
  } catch {
98
129
  return !1;
99
130
  }
100
131
  }
101
- function Q() {
132
+ function J() {
102
133
  return typeof window > "u" || window.parent === window ? null : window.parent;
103
134
  }
104
- function c(t, e, r = "*", i, n) {
105
- const s = Q();
135
+ function u(t, e, r = "*", i, n) {
136
+ const s = J();
106
137
  if (!s) {
107
138
  a.warn("Not running in an iframe, cannot post to host");
108
139
  return;
109
140
  }
110
- const u = {
141
+ const d = {
111
142
  event: t,
112
143
  payload: e || {},
113
144
  timestamp: Date.now(),
114
145
  source: "embedded-app",
115
146
  ...i && { requestId: i },
116
147
  metadata: {
117
- version: I
148
+ version: R
118
149
  }
119
150
  };
120
- s.postMessage(u, r);
151
+ s.postMessage(d, r);
121
152
  }
122
- const l = /* @__PURE__ */ new Map();
153
+ const p = /* @__PURE__ */ new Map();
123
154
  let A = !1;
124
- function V(t) {
125
- if (process.env.NODE_ENV === "production" && !B(t.origin))
155
+ function j(t) {
156
+ if (process.env.NODE_ENV === "production" && !Q(t.origin))
126
157
  return;
127
158
  const e = t.data;
128
159
  if (!e || typeof e.event != "string" || !e.payload || typeof e.timestamp != "number" || !e.source) {
129
160
  a.warn("Invalid message structure received:", e);
130
161
  return;
131
162
  }
132
- const r = l.get(e.event);
163
+ const r = p.get(e.event);
133
164
  r && r.forEach((n) => {
134
165
  try {
135
166
  n(e);
@@ -137,7 +168,7 @@ function V(t) {
137
168
  a.error("Error in message handler:", s);
138
169
  }
139
170
  });
140
- const i = l.get("*");
171
+ const i = p.get("*");
141
172
  i && i.forEach((n) => {
142
173
  try {
143
174
  n(e);
@@ -146,87 +177,87 @@ function V(t) {
146
177
  }
147
178
  });
148
179
  }
149
- function J() {
150
- A || typeof window > "u" || (window.addEventListener("message", V), A = !0);
180
+ function Z() {
181
+ A || typeof window > "u" || (window.addEventListener("message", j), A = !0);
151
182
  }
152
- function y(t, e) {
153
- J(), l.has(t) || l.set(t, /* @__PURE__ */ new Set());
154
- const r = l.get(t);
183
+ function m(t, e) {
184
+ Z(), p.has(t) || p.set(t, /* @__PURE__ */ new Set());
185
+ const r = p.get(t);
155
186
  return r.add(e), () => {
156
- r.delete(e), r.size === 0 && l.delete(t);
187
+ r.delete(e), r.size === 0 && p.delete(t);
157
188
  };
158
189
  }
159
- function Z(t, e = X) {
190
+ function ee(t, e = K) {
160
191
  return new Promise((r, i) => {
161
192
  const n = setTimeout(() => {
162
193
  s(), i(new Error(`[EmbeddedSDK] Timeout waiting for "${t}" message`));
163
- }, e), s = y(t, (u) => {
164
- clearTimeout(n), s(), r(u);
194
+ }, e), s = m(t, (d) => {
195
+ clearTimeout(n), s(), r(d);
165
196
  });
166
197
  });
167
198
  }
168
- function ee() {
169
- l.clear(), A && typeof window < "u" && (window.removeEventListener("message", V), A = !1);
170
- }
171
199
  function te() {
200
+ p.clear(), A && typeof window < "u" && (window.removeEventListener("message", j), A = !1);
201
+ }
202
+ function re() {
172
203
  return typeof window > "u" ? !1 : window.parent !== window;
173
204
  }
174
- function re(t, e, r) {
205
+ function ie(t, e, r) {
175
206
  const i = {
176
207
  event: t,
177
208
  payload: e,
178
209
  timestamp: Date.now(),
179
210
  source: "merchant-dashboard",
180
211
  ...r,
181
- metadata: { version: I, synthetic: !0 }
182
- }, n = l.get(t);
183
- n == null || n.forEach((s) => {
212
+ metadata: { version: R, synthetic: !0 }
213
+ };
214
+ p.get(t)?.forEach((s) => {
184
215
  try {
185
216
  s(i);
186
- } catch (u) {
187
- a.error("Error in message handler:", u);
217
+ } catch (d) {
218
+ a.error("Error in message handler:", d);
188
219
  }
189
220
  });
190
221
  }
191
- const f = /* @__PURE__ */ new Map(), ie = 3e4;
222
+ const E = /* @__PURE__ */ new Map(), ne = 3e4;
192
223
  function F() {
193
224
  const t = Date.now(), e = Math.random().toString(36).slice(2, 9);
194
225
  return `req_${t}_${e}`;
195
226
  }
196
- function j(t, e = {}, r = ie) {
227
+ function $(t, e = {}, r = ne) {
197
228
  const i = F();
198
229
  return new Promise((n, s) => {
199
- const u = setTimeout(() => {
200
- f.get(i) && (f.delete(i), s(
230
+ const d = setTimeout(() => {
231
+ E.get(i) && (E.delete(i), s(
201
232
  new Error(
202
233
  `[EmbeddedSDK] Request "${t}" timed out after ${r}ms`
203
234
  )
204
235
  ));
205
236
  }, r);
206
- f.set(i, {
237
+ E.set(i, {
207
238
  resolve: n,
208
239
  reject: s,
209
- timeout: u,
240
+ timeout: d,
210
241
  event: t
211
- }), c(t, e, "*", i);
242
+ }), u(t, e, "*", i);
212
243
  });
213
244
  }
214
- function H(t, e, r) {
215
- const i = f.get(t);
245
+ function D(t, e, r) {
246
+ const i = E.get(t);
216
247
  if (!i) {
217
248
  a.warn(`Received response for unknown request: ${t}`);
218
249
  return;
219
250
  }
220
- clearTimeout(i.timeout), f.delete(t), i.resolve(e);
251
+ clearTimeout(i.timeout), E.delete(t), i.resolve(e);
221
252
  }
222
- function ne(t = "SDK cleanup") {
223
- f.forEach((e, r) => {
253
+ function se(t = "SDK cleanup") {
254
+ E.forEach((e, r) => {
224
255
  clearTimeout(e.timeout), e.reject(
225
256
  new Error(`[EmbeddedSDK] Request ${r} cancelled: ${t}`)
226
257
  );
227
- }), f.clear();
258
+ }), E.clear();
228
259
  }
229
- function R() {
260
+ function w() {
230
261
  const t = /* @__PURE__ */ new Set();
231
262
  return {
232
263
  subscribe(e) {
@@ -251,18 +282,18 @@ function R() {
251
282
  }
252
283
  };
253
284
  }
254
- const se = "https://api.salla.dev";
285
+ const ae = "https://api.salla.dev";
255
286
  class T extends Error {
256
287
  constructor(e, r, i) {
257
288
  super(e), this.status = r, this.response = i, this.name = "ApiError";
258
289
  }
259
290
  }
260
- async function ae(t, e = {}) {
261
- const { method: r = "GET", headers: i = {}, body: n, timeout: s = 3e4 } = e, u = `${se}${t}`, N = new AbortController(), O = setTimeout(() => {
291
+ async function oe(t, e = {}) {
292
+ const { method: r = "GET", headers: i = {}, body: n, timeout: s = 3e4 } = e, d = `${ae}${t}`, N = new AbortController(), M = setTimeout(() => {
262
293
  N.abort();
263
294
  }, s);
264
295
  try {
265
- const d = await fetch(u, {
296
+ const c = await fetch(d, {
266
297
  method: r,
267
298
  headers: {
268
299
  "Content-Type": "application/json",
@@ -271,18 +302,17 @@ async function ae(t, e = {}) {
271
302
  body: n ? JSON.stringify(n) : void 0,
272
303
  signal: N.signal
273
304
  });
274
- clearTimeout(O);
275
- let v;
276
- const C = d.headers.get("content-type");
277
- if (C != null && C.includes("application/json") ? v = await d.json() : v = await d.text(), !d.ok)
305
+ clearTimeout(M);
306
+ let I;
307
+ if (c.headers.get("content-type")?.includes("application/json") ? I = await c.json() : I = await c.text(), !c.ok)
278
308
  throw new T(
279
- `API request failed: ${d.statusText}`,
280
- d.status,
281
- v
309
+ `API request failed: ${c.statusText}`,
310
+ c.status,
311
+ I
282
312
  );
283
- return v;
284
- } catch (d) {
285
- throw clearTimeout(O), d instanceof T ? d : d instanceof Error ? d.name === "AbortError" ? new T(`Request timeout after ${s}ms`) : new T(`Request failed: ${d.message}`) : new T("Unknown error occurred");
313
+ return I;
314
+ } catch (c) {
315
+ throw clearTimeout(M), c instanceof T ? c : c instanceof Error ? c.name === "AbortError" ? new T(`Request timeout after ${s}ms`) : new T(`Request failed: ${c.message}`) : new T("Unknown error occurred");
286
316
  }
287
317
  }
288
318
  function _(t) {
@@ -293,7 +323,7 @@ function _(t) {
293
323
  data: null
294
324
  };
295
325
  }
296
- async function oe(t) {
326
+ async function ue(t) {
297
327
  const { token: e, appId: r, refreshOnError: i = !0 } = t;
298
328
  if (!e) {
299
329
  const n = "Token is required. Provide it as a parameter or in URL as ?token=XXX";
@@ -304,7 +334,7 @@ async function oe(t) {
304
334
  return a.error("Error in introspect:", n), _(n);
305
335
  }
306
336
  try {
307
- const n = await ae(
337
+ const n = await oe(
308
338
  "/exchange-authority/v1/introspect",
309
339
  {
310
340
  method: "POST",
@@ -327,12 +357,12 @@ async function oe(t) {
327
357
  data: s ? n.data : null
328
358
  };
329
359
  } catch (n) {
330
- i && (G().ui.toast.error((n == null ? void 0 : n.toString()) ?? "Introspect error"), c(U.REFRESH, {})), a.error("Error in introspect:", n);
360
+ i && (H().ui.toast.error(n?.toString() ?? "Introspect error"), u(V.REFRESH, {})), a.error("Error in introspect:", n);
331
361
  const s = n instanceof Error ? n.message : n;
332
362
  return _(s);
333
363
  }
334
364
  }
335
- function ue(t) {
365
+ function de(t) {
336
366
  return {
337
367
  /**
338
368
  * Get the token from the URL query parameter.
@@ -367,7 +397,7 @@ function ue(t) {
367
397
  * ```
368
398
  */
369
399
  refresh() {
370
- c(U.REFRESH, {});
400
+ u(V.REFRESH, {});
371
401
  },
372
402
  /**
373
403
  * Introspect (verify) a short-lived token with Salla's API.
@@ -378,7 +408,7 @@ function ue(t) {
378
408
  */
379
409
  async introspect(e = {}) {
380
410
  const r = e.token ?? this.getToken() ?? "", i = e.appId ?? this.getAppId() ?? "";
381
- return oe({
411
+ return ue({
382
412
  token: r,
383
413
  appId: i,
384
414
  refreshOnError: e.refreshOnError
@@ -397,7 +427,7 @@ function q(t, e) {
397
427
  const r = [];
398
428
  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);
399
429
  }
400
- function de(t) {
430
+ function le(t) {
401
431
  const e = [];
402
432
  if (typeof t != "object" || t === null)
403
433
  return e.push("Checkout options must be an object"), { valid: !1, errors: e };
@@ -412,18 +442,18 @@ function de(t) {
412
442
  return e.push(...n), { valid: e.length === 0, errors: e };
413
443
  }
414
444
  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) => {
415
- const u = q(
445
+ const d = q(
416
446
  n,
417
447
  `Item at index ${s}`
418
448
  );
419
- e.push(...u);
449
+ e.push(...d);
420
450
  }), { valid: e.length === 0, errors: e }) : (e.push("Checkout items must be an array"), { valid: !1, errors: e });
421
451
  }
422
- function le(t) {
452
+ function fe(t) {
423
453
  const e = [];
424
454
  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 };
425
455
  }
426
- function fe(t) {
456
+ function he(t) {
427
457
  const e = [];
428
458
  if (t.url === void 0 || t.url === null)
429
459
  e.push("Redirect URL is required");
@@ -439,7 +469,7 @@ function fe(t) {
439
469
  }
440
470
  return { valid: e.length === 0, errors: e };
441
471
  }
442
- function he(t) {
472
+ function pe(t) {
443
473
  const e = [];
444
474
  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) => {
445
475
  if (typeof r != "object" || r === null) {
@@ -460,48 +490,75 @@ function he(t) {
460
490
  );
461
491
  }) : e.push("Nav action extendedActions must be an array")), { valid: e.length === 0, errors: e };
462
492
  }
463
- const z = ["danger", "warning", "info"];
493
+ function me(t) {
494
+ const e = [];
495
+ if (typeof t != "object" || t === null)
496
+ return e.push("Nav addItem expects an object item"), { valid: !1, errors: e };
497
+ const r = t;
498
+ return ["title", "value", "url"].forEach((i) => {
499
+ (typeof r[i] != "string" || !String(r[i]).trim()) && e.push(`Sub-nav addItem "${i}" must be non-empty string`);
500
+ }), 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 };
501
+ }
464
502
  function ge(t) {
503
+ const e = [];
504
+ if (typeof t != "object" || t === null)
505
+ return e.push("Nav updateItem expects an object item"), { valid: !1, errors: e };
506
+ const r = t;
507
+ if (typeof r.id != "string" || !r.id.trim())
508
+ return e.push('Sub-nav updateItem requires string "id"'), { valid: !1, errors: e };
509
+ let i = 0;
510
+ 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(
511
+ "Sub-nav updateItem must include at least one of title, value, url, disabled, active"
512
+ ), { valid: !1, errors: e }) : (["title", "value", "url"].forEach((n) => {
513
+ r[n] !== void 0 && (typeof r[n] != "string" || !r[n].trim()) && e.push(`Sub-nav updateItem "${n}" must be non-empty`);
514
+ }), 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 });
515
+ }
516
+ function Ee(t) {
517
+ const e = [];
518
+ return (typeof t != "string" || !t.trim()) && e.push("Nav removeItem id must be non-empty string"), { valid: e.length === 0, errors: e };
519
+ }
520
+ const z = ["danger", "warning", "info"];
521
+ function be(t) {
465
522
  const e = [];
466
523
  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" || !z.includes(t.variant)) && e.push(
467
524
  `Invalid confirm variant "${t.variant}". Expected: ${z.join(" | ")}`
468
525
  ), { valid: e.length === 0, errors: e };
469
526
  }
470
- function h(t, e) {
527
+ function f(t, e) {
471
528
  a.error(
472
529
  `Validation failed for ${t}:
473
530
  ` + e.map((r) => ` • ${r}`).join(`
474
531
  `)
475
532
  );
476
533
  }
477
- function pe() {
534
+ function ve() {
478
535
  return { resize: (i) => {
479
536
  }, autoResize: () => {
480
537
  }, stopAutoResize: () => {
481
538
  } };
482
539
  }
483
- function me() {
484
- const { resize: t, autoResize: e, stopAutoResize: r } = pe();
540
+ function ye() {
541
+ const { resize: t, autoResize: e, stopAutoResize: r } = ve();
485
542
  return {
486
543
  navigate(i, n) {
487
- const s = le({ path: i, ...n });
544
+ const s = fe({ path: i, ...n });
488
545
  if (!s.valid) {
489
- h(p.NAVIGATE, s.errors);
546
+ f(b.NAVIGATE, s.errors);
490
547
  return;
491
548
  }
492
- c(p.NAVIGATE, {
549
+ u(b.NAVIGATE, {
493
550
  path: i,
494
- state: n == null ? void 0 : n.state,
495
- replace: n == null ? void 0 : n.replace
551
+ state: n?.state,
552
+ replace: n?.replace
496
553
  });
497
554
  },
498
555
  redirect(i) {
499
- const n = fe({ url: i });
556
+ const n = he({ url: i });
500
557
  if (!n.valid) {
501
- h(p.REDIRECT, n.errors);
558
+ f(b.REDIRECT, n.errors);
502
559
  return;
503
560
  }
504
- c(p.REDIRECT, { url: i });
561
+ u(b.REDIRECT, { url: i });
505
562
  },
506
563
  navTo(i, n) {
507
564
  if (i.startsWith("http://") || i.startsWith("https://")) {
@@ -512,77 +569,123 @@ function me() {
512
569
  },
513
570
  setTitle(i) {
514
571
  if (typeof i != "string" || !i.trim()) {
515
- h(p.SET_TITLE, [
572
+ f(b.SET_TITLE, [
516
573
  "Title must be a non-empty string"
517
574
  ]);
518
575
  return;
519
576
  }
520
- c(p.SET_TITLE, { title: i });
577
+ u(b.SET_TITLE, { title: i });
521
578
  },
522
579
  resize: t,
523
580
  autoResize: e,
524
581
  stopAutoResize: r
525
582
  };
526
583
  }
527
- function Ee() {
528
- const t = R();
529
- return y(w.ACTION_CLICK, (e) => {
530
- t.notify(e.payload.value);
531
- }), {
532
- setAction(e) {
533
- var i;
534
- const r = he(e);
535
- if (!r.valid) {
536
- h(w.SET_ACTION, r.errors);
584
+ function Te() {
585
+ const t = w(), e = w(), r = [];
586
+ return r.push(
587
+ m(l.ACTION_CLICK, (i) => {
588
+ t.notify(i.payload.value);
589
+ })
590
+ ), r.push(
591
+ m(l.ADD_ITEM_RESPONSE, (i) => {
592
+ const n = i.payload.item;
593
+ i.requestId && n && typeof n.id == "string" && typeof n.value == "string" && D(i.requestId, n);
594
+ })
595
+ ), r.push(
596
+ m(l.ITEM_CLICK, (i) => {
597
+ e.notify(i.payload);
598
+ })
599
+ ), {
600
+ setAction(i) {
601
+ const n = pe(i);
602
+ if (!n.valid) {
603
+ f(l.SET_ACTION, n.errors);
537
604
  return;
538
605
  }
539
- c(w.SET_ACTION, {
540
- title: e.title,
541
- value: e.value,
542
- subTitle: e.subTitle,
543
- icon: e.icon,
544
- disabled: e.disabled,
545
- extendedActions: (i = e.extendedActions) == null ? void 0 : i.map((n) => ({
546
- title: n.title,
547
- value: n.value,
548
- subTitle: n.subTitle,
549
- icon: n.icon,
550
- disabled: n.disabled
606
+ u(l.SET_ACTION, {
607
+ title: i.title,
608
+ value: i.value,
609
+ subTitle: i.subTitle,
610
+ icon: i.icon,
611
+ disabled: i.disabled,
612
+ extendedActions: i.extendedActions?.map((s) => ({
613
+ title: s.title,
614
+ value: s.value,
615
+ subTitle: s.subTitle,
616
+ icon: s.icon,
617
+ disabled: s.disabled
551
618
  }))
552
619
  });
553
620
  },
554
621
  clearAction() {
555
- c(w.CLEAR_ACTION, {});
622
+ u(l.CLEAR_ACTION, {});
623
+ },
624
+ onActionClick(i) {
625
+ return t.subscribe(i);
556
626
  },
557
- onActionClick(e) {
558
- return t.subscribe(e);
627
+ addNavItem(i) {
628
+ const n = me(i);
629
+ return n.valid ? $(l.ADD_ITEM, { item: i }, 2e3) : (f(l.ADD_ITEM, n.errors), Promise.reject(new Error(n.errors[0])));
630
+ },
631
+ updateNavItem(i) {
632
+ const n = ge(i);
633
+ if (!n.valid) {
634
+ f(l.UPDATE_ITEM, n.errors);
635
+ return;
636
+ }
637
+ u(l.UPDATE_ITEM, { item: i });
638
+ },
639
+ removeNavItem(i) {
640
+ const n = Ee(i);
641
+ if (!n.valid) {
642
+ f(l.REMOVE_ITEM, n.errors);
643
+ return;
644
+ }
645
+ u(l.REMOVE_ITEM, { id: i });
646
+ },
647
+ onNavItemClick(i) {
648
+ return e.subscribe(i);
649
+ },
650
+ destroy() {
651
+ r.forEach((i) => i()), r.length = 0, t.clear(), e.clear();
559
652
  }
560
653
  };
561
654
  }
562
- function ye() {
655
+ function we() {
563
656
  return {
564
657
  /**
565
658
  * Show loading indicator.
566
659
  */
567
660
  show() {
568
- c(g.LOADING, { action: "show" });
661
+ u(h.LOADING, { action: "show" });
569
662
  },
570
663
  /**
571
664
  * Hide loading indicator.
572
665
  */
573
666
  hide() {
574
- c(g.LOADING, { action: "hide" });
667
+ u(h.LOADING, { action: "hide" });
575
668
  }
576
669
  };
577
670
  }
578
- function be() {
671
+ function Ie() {
672
+ return {
673
+ hide() {
674
+ u(h.BREADCRUMBS, { action: "hide" });
675
+ },
676
+ show() {
677
+ u(h.BREADCRUMBS, { action: "show" });
678
+ }
679
+ };
680
+ }
681
+ function Se() {
579
682
  const t = (e) => {
580
683
  const r = ce(e);
581
684
  if (!r.valid) {
582
- h(g.TOAST, r.errors);
685
+ f(h.TOAST, r.errors);
583
686
  return;
584
687
  }
585
- c(g.TOAST, {
688
+ u(h.TOAST, {
586
689
  type: e.type,
587
690
  message: e.message,
588
691
  duration: e.duration
@@ -619,29 +722,30 @@ function be() {
619
722
  }
620
723
  };
621
724
  }
622
- function Te() {
725
+ function Ae() {
623
726
  return async (t) => {
624
- const e = ge(t);
625
- return e.valid ? j(g.CONFIRM, {
727
+ const e = be(t);
728
+ return e.valid ? $(h.CONFIRM, {
626
729
  title: t.title,
627
730
  message: t.message,
628
731
  confirmText: t.confirmText ?? "Confirm",
629
732
  cancelText: t.cancelText ?? "Cancel",
630
733
  variant: t.variant ?? "info"
631
- }) : (h(g.CONFIRM, e.errors), Promise.reject(new Error(e.errors.join(", "))));
734
+ }) : (f(h.CONFIRM, e.errors), Promise.reject(new Error(e.errors.join(", "))));
632
735
  };
633
736
  }
634
- function ve() {
737
+ function Re() {
635
738
  return {
636
- loading: ye(),
637
- toast: be(),
638
- confirm: Te()
739
+ loading: we(),
740
+ breadcrumbs: Ie(),
741
+ toast: Se(),
742
+ confirm: Ae()
639
743
  };
640
744
  }
641
- function we() {
642
- const t = R(), e = [];
745
+ function Ne() {
746
+ const t = w(), e = [];
643
747
  return e.push(
644
- y(m.RESPONSE, (r) => {
748
+ m(g.RESPONSE, (r) => {
645
749
  t.notify({
646
750
  success: r.payload.success,
647
751
  order_id: r.payload.order_id,
@@ -651,10 +755,10 @@ function we() {
651
755
  });
652
756
  })
653
757
  ), e.push(
654
- y(
655
- m.GET_ADDONS_RESPONSE,
758
+ m(
759
+ g.GET_ADDONS_RESPONSE,
656
760
  (r) => {
657
- r.requestId && H(r.requestId, {
761
+ r.requestId && D(r.requestId, {
658
762
  success: r.payload.success,
659
763
  addons: r.payload.addons,
660
764
  error: r.payload.error
@@ -663,18 +767,18 @@ function we() {
663
767
  )
664
768
  ), {
665
769
  create(r, i) {
666
- const n = Array.isArray(r) ? r : [r], s = de({ items: n });
770
+ const n = Array.isArray(r) ? r : [r], s = le({ items: n });
667
771
  if (!s.valid)
668
- throw h(m.CREATE, s.errors), new Error(s.errors[0]);
669
- c(
670
- m.CREATE,
772
+ throw f(g.CREATE, s.errors), new Error(s.errors[0]);
773
+ u(
774
+ g.CREATE,
671
775
  {
672
- items: n.map((u) => ({
673
- type: u.type,
674
- slug: u.slug,
675
- quantity: u.quantity ?? 1
776
+ items: n.map((d) => ({
777
+ type: d.type,
778
+ slug: d.slug,
779
+ quantity: d.quantity ?? 1
676
780
  })),
677
- ...(i == null ? void 0 : i.context) !== void 0 && { context: i.context }
781
+ ...i?.context !== void 0 && { context: i.context }
678
782
  },
679
783
  "*",
680
784
  F()
@@ -685,8 +789,8 @@ function we() {
685
789
  },
686
790
  async getAddons() {
687
791
  try {
688
- return await j(
689
- m.GET_ADDONS,
792
+ return await $(
793
+ g.GET_ADDONS,
690
794
  {},
691
795
  3e4
692
796
  );
@@ -700,23 +804,27 @@ function we() {
700
804
  };
701
805
  }
702
806
  },
807
+ resetCache() {
808
+ u(g.RESET_CACHE, {}, "*");
809
+ },
703
810
  destroy() {
704
811
  e.forEach((r) => r()), e.length = 0, t.clear();
705
812
  }
706
813
  };
707
814
  }
708
- const M = {
815
+ const P = {
709
816
  theme: "light",
817
+ dir: "rtl",
710
818
  width: 0,
711
819
  locale: "ar",
712
820
  currency: "SAR"
713
821
  };
714
- class Se {
822
+ class Ce {
715
823
  constructor() {
716
- this.initialized = !1, this.initializing = !1, this.debugMode = !1, this.appReady = !1, this.layout = { ...M }, this.postInitHooks = [], this.themeSubscription = R(), this.initSubscription = R(), this.auth = ue(), this.page = me(), this.nav = Ee(), this.ui = ve(), this.checkout = we(), this.registerPostInitHook((e) => {
824
+ this.initialized = !1, this.initializing = !1, this.debugMode = !1, this.appReady = !1, this.layout = { ...P }, this.postInitHooks = [], this.themeSubscription = w(), this.initSubscription = w(), this.auth = de(), this.page = ye(), this.nav = Te(), this.ui = Re(), this.checkout = Ne(), this.registerPostInitHook((e) => {
717
825
  const r = e.payload.pendingCheckoutResult;
718
826
  r && (a.debug("Dispatching pending checkout result:", r), queueMicrotask(() => {
719
- re(m.RESPONSE, {
827
+ ie(g.RESPONSE, {
720
828
  success: r.success,
721
829
  status: r.status,
722
830
  error: r.error,
@@ -736,10 +844,10 @@ class Se {
736
844
  * Set up core event listeners.
737
845
  */
738
846
  setupListeners() {
739
- y(x.THEME_CHANGE, (e) => {
847
+ m(O.THEME_CHANGE, (e) => {
740
848
  this.layout.theme = e.payload.theme, a.debug("Theme changed:", e.payload.theme), this.themeSubscription.notify(e.payload.theme);
741
- }), y(g.CONFIRM_RESPONSE, (e) => {
742
- a.debug("Received confirm response:", e), e.requestId && H(e.requestId, { confirmed: e.payload.confirmed });
849
+ }), m(h.CONFIRM_RESPONSE, (e) => {
850
+ a.debug("Received confirm response:", e), e.requestId && D(e.requestId, { confirmed: e.payload.confirmed });
743
851
  });
744
852
  }
745
853
  /**
@@ -788,7 +896,7 @@ class Se {
788
896
  a.warn("Cannot signal ready before init() is called");
789
897
  return;
790
898
  }
791
- this.appReady = !0, c($.READY, {}), a.debug("Sent ready signal to host");
899
+ this.appReady = !0, u(C.READY, {}), a.debug("Sent ready signal to host");
792
900
  }
793
901
  /**
794
902
  * Initialize the SDK and establish connection with the host.
@@ -802,21 +910,22 @@ class Se {
802
910
  i(), r({ layout: { ...n.layout } });
803
911
  });
804
912
  });
805
- this.initializing = !0, this.debugMode = e.debug ?? !1, Y({ debug: this.debugMode }), te() || a.warn("Not running in an iframe. Some features may not work."), a.debug("Initializing SDK...");
913
+ this.initializing = !0, this.debugMode = e.debug ?? !1, Y({ debug: this.debugMode }), re() || a.warn("Not running in an iframe. Some features may not work."), a.debug("Initializing SDK...");
806
914
  try {
807
- c($.INIT, {
915
+ u(C.INIT, {
808
916
  height: document.documentElement.scrollHeight
809
917
  }), a.debug("Sent iframe.ready message, waiting for context...");
810
- const r = await Z(
811
- x.PROVIDE
918
+ const r = await ee(
919
+ O.PROVIDE
812
920
  );
813
921
  a.debug("Received context from host:", r);
814
922
  const { layout: i } = r.payload;
815
923
  return this.layout = {
816
- theme: (i == null ? void 0 : i.theme) ?? "light",
817
- width: (i == null ? void 0 : i.width) ?? 0,
818
- locale: (i == null ? void 0 : i.locale) ?? "ar",
819
- currency: (i == null ? void 0 : i.currency) ?? "SAR"
924
+ theme: i?.theme ?? "light",
925
+ dir: i?.dir ?? W(i?.locale),
926
+ width: i?.width ?? 0,
927
+ locale: i?.locale ?? "ar",
928
+ currency: i?.currency ?? "SAR"
820
929
  }, this.postInitHooks.forEach((n) => {
821
930
  try {
822
931
  n(r);
@@ -832,23 +941,23 @@ class Se {
832
941
  * Destroy the SDK instance and clean up resources.
833
942
  */
834
943
  destroy() {
835
- a.debug("Destroying SDK instance"), this.initialized && (c($.DESTROY, {}), a.debug("Sent destroy event to host")), this.checkout.destroy(), ne("SDK destroyed"), ee(), this.themeSubscription.clear(), this.initSubscription.clear(), this.postInitHooks = [], this.initialized = !1, this.initializing = !1, this.appReady = !1, this.layout = { ...M };
944
+ a.debug("Destroying SDK instance"), this.initialized && (u(C.DESTROY, {}), a.debug("Sent destroy event to host")), this.checkout.destroy(), this.nav.destroy(), se("SDK destroyed"), te(), this.themeSubscription.clear(), this.initSubscription.clear(), this.postInitHooks = [], this.initialized = !1, this.initializing = !1, this.appReady = !1, this.layout = { ...P };
836
945
  }
837
946
  }
838
- let E = null;
839
- function G() {
840
- return E || (E = new Se()), E;
947
+ let v = null;
948
+ function H() {
949
+ return v || (v = new Ce()), v;
841
950
  }
842
- function Ae() {
843
- E && (E.destroy(), E = null);
951
+ function $e() {
952
+ v && (v.destroy(), v = null);
844
953
  }
845
- const P = G(), Re = I;
846
- typeof window < "u" && (window.salla = window.salla || window.Salla || {}, window.Salla = window.salla, window.salla.embedded || (window.salla.embedded = P), window.Salla.embedded || (window.Salla.embedded = P));
954
+ const U = H(), De = R;
955
+ typeof window < "u" && (window.salla = window.salla || window.Salla || {}, window.Salla = window.salla, window.salla.embedded || (window.salla.embedded = U), window.Salla.embedded || (window.Salla.embedded = U));
847
956
  export {
848
- Se as EmbeddedApp,
849
- P as embedded,
850
- G as getEmbeddedApp,
851
- Ae as resetEmbeddedApp,
852
- Re as version
957
+ Ce as EmbeddedApp,
958
+ U as embedded,
959
+ H as getEmbeddedApp,
960
+ $e as resetEmbeddedApp,
961
+ De as version
853
962
  };
854
963
  //# sourceMappingURL=index.js.map