@cimplify/sdk 0.90.0 → 0.92.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 (67) hide show
  1. package/dist/advanced.d.mts +3 -3
  2. package/dist/advanced.d.ts +3 -3
  3. package/dist/advanced.js +20 -20
  4. package/dist/advanced.mjs +1 -1
  5. package/dist/{chunk-JVWFIFQ7.js → chunk-3MBMIEWT.js} +4 -4
  6. package/dist/{chunk-2UDEWILL.mjs → chunk-3XD2FVP4.mjs} +117 -35
  7. package/dist/{chunk-NGE37REW.mjs → chunk-54H2YYIW.mjs} +2 -2
  8. package/dist/{chunk-BN4V4ONE.js → chunk-DCRN67NO.js} +158 -73
  9. package/dist/{chunk-T7Z25EY4.js → chunk-HKN3YG76.js} +84 -0
  10. package/dist/{chunk-GHFDYM5K.js → chunk-IVJEUGWF.js} +10 -1
  11. package/dist/{chunk-KJP4U6L3.js → chunk-OAHSF542.js} +12 -0
  12. package/dist/{chunk-NNGKC3MM.mjs → chunk-PYBFTMHI.mjs} +12 -0
  13. package/dist/{chunk-OZDDHSIB.mjs → chunk-RRBY35TJ.mjs} +80 -1
  14. package/dist/{chunk-ZU4ZRYUR.mjs → chunk-T7LDBZZZ.mjs} +10 -1
  15. package/dist/{client-YiSelM7x.d.mts → client-BQbSKlHS.d.mts} +90 -11
  16. package/dist/{client-DMttx1xk.d.mts → client-Bw4HtLP1.d.mts} +2 -2
  17. package/dist/{client-CR1f94wY.d.ts → client-CeW3acve.d.ts} +90 -11
  18. package/dist/{client-CqpOcbin.d.ts → client-Otzv_rgP.d.ts} +2 -2
  19. package/dist/{index-DD9z396M.d.mts → index-CmIboQjl.d.mts} +3 -3
  20. package/dist/{index-CxTVu0HZ.d.ts → index-DgoRwz8l.d.ts} +3 -3
  21. package/dist/index.d.mts +49 -7
  22. package/dist/index.d.ts +49 -7
  23. package/dist/index.js +103 -83
  24. package/dist/index.mjs +5 -5
  25. package/dist/mock/cli.mjs +12 -0
  26. package/dist/mock/library.js +12 -0
  27. package/dist/mock/library.mjs +12 -0
  28. package/dist/mock/msw.js +12 -0
  29. package/dist/mock/msw.mjs +12 -0
  30. package/dist/{payment-5d8FTA1q.d.mts → payment-BFtLqiG2.d.mts} +1 -1
  31. package/dist/{payment-BX7ccIKY.d.ts → payment-Cq8FT1B6.d.ts} +1 -1
  32. package/dist/{price-DtfP_Xfq.d.ts → price-DaFXT-Lr.d.ts} +1 -1
  33. package/dist/{price-arl_4Rzn.d.mts → price-DleDWk_s.d.mts} +1 -1
  34. package/dist/{product-DZX4QuKS.d.ts → product-bZ8G5Z8D.d.mts} +38 -0
  35. package/dist/{product-DZX4QuKS.d.mts → product-bZ8G5Z8D.d.ts} +38 -0
  36. package/dist/react.d.mts +71 -6
  37. package/dist/react.d.ts +71 -6
  38. package/dist/react.js +466 -337
  39. package/dist/react.mjs +398 -272
  40. package/dist/{server-BceZMxcK.d.mts → server-D-iK-bNt.d.mts} +1 -1
  41. package/dist/{server-DoJGSC7L.d.ts → server-DwsY9hlX.d.ts} +1 -1
  42. package/dist/server.d.mts +4 -4
  43. package/dist/server.d.ts +4 -4
  44. package/dist/server.js +7 -7
  45. package/dist/server.mjs +2 -2
  46. package/dist/styles.css +1 -1
  47. package/dist/testing/msw.d.mts +2 -2
  48. package/dist/testing/msw.d.ts +2 -2
  49. package/dist/testing/msw.js +2 -2
  50. package/dist/testing/msw.mjs +1 -1
  51. package/dist/testing/suite.d.mts +6 -6
  52. package/dist/testing/suite.d.ts +6 -6
  53. package/dist/testing/suite.js +23 -23
  54. package/dist/testing/suite.mjs +4 -4
  55. package/dist/testing.d.mts +5 -5
  56. package/dist/testing.d.ts +5 -5
  57. package/dist/testing.js +79 -79
  58. package/dist/testing.mjs +5 -5
  59. package/dist/utils.d.mts +4 -4
  60. package/dist/utils.d.ts +4 -4
  61. package/package.json +1 -1
  62. package/registry/booking-page.json +1 -1
  63. package/registry/chat-widget.json +1 -1
  64. package/registry/customer-input-fields.json +1 -1
  65. package/registry/date-slot-picker.json +1 -1
  66. package/registry/product-customizer.json +1 -1
  67. package/registry/rental-service-card.json +1 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkGHFDYM5K_js = require('./chunk-GHFDYM5K.js');
3
+ var chunkIVJEUGWF_js = require('./chunk-IVJEUGWF.js');
4
4
  var chunkAETVRBKI_js = require('./chunk-AETVRBKI.js');
5
5
 
6
6
  // src/store-credit.ts
@@ -13,7 +13,7 @@ var StoreCreditQueries = class {
13
13
  * currency. Requires a signed-in customer; returns an error otherwise.
14
14
  */
15
15
  async balance() {
16
- return chunkGHFDYM5K_js.safe(this.client.get("/api/v1/store-credit/balance"));
16
+ return chunkIVJEUGWF_js.safe(this.client.get("/api/v1/store-credit/balance"));
17
17
  }
18
18
  };
19
19
 
@@ -95,7 +95,7 @@ var ActivityService = class {
95
95
  this.sendEvents([event]);
96
96
  }
97
97
  async getState() {
98
- return chunkGHFDYM5K_js.safe(this.client.get("/api/v1/activity/state"));
98
+ return chunkIVJEUGWF_js.safe(this.client.get("/api/v1/activity/state"));
99
99
  }
100
100
  async getRecommendations(options) {
101
101
  const params = new URLSearchParams();
@@ -103,10 +103,10 @@ var ActivityService = class {
103
103
  if (options?.limit) params.set("limit", String(options.limit));
104
104
  const query = params.toString();
105
105
  const path = query ? `/api/v1/activity/recommendations?${query}` : "/api/v1/activity/recommendations";
106
- return chunkGHFDYM5K_js.safe(this.client.get(path));
106
+ return chunkIVJEUGWF_js.safe(this.client.get(path));
107
107
  }
108
108
  async dismissMessage(code) {
109
- return chunkGHFDYM5K_js.safe(
109
+ return chunkIVJEUGWF_js.safe(
110
110
  this.client.post("/api/v1/activity/messages/dismiss", { code })
111
111
  );
112
112
  }
@@ -142,16 +142,16 @@ var SubscriptionService = class {
142
142
  this.client = client;
143
143
  }
144
144
  async list() {
145
- return chunkGHFDYM5K_js.safe(this.client.get("/api/v1/subscriptions"));
145
+ return chunkIVJEUGWF_js.safe(this.client.get("/api/v1/subscriptions"));
146
146
  }
147
147
  async get(id) {
148
148
  const encodedId = encodeURIComponent(id);
149
- return chunkGHFDYM5K_js.safe(this.client.get(`/api/v1/subscriptions/${encodedId}`));
149
+ return chunkIVJEUGWF_js.safe(this.client.get(`/api/v1/subscriptions/${encodedId}`));
150
150
  }
151
151
  async cancel(id, reason, opts) {
152
152
  const encodedId = encodeURIComponent(id);
153
- const idempotencyKey = opts?.idempotencyKey ?? chunkGHFDYM5K_js.generateIdempotencyKey();
154
- return chunkGHFDYM5K_js.safe(
153
+ const idempotencyKey = opts?.idempotencyKey ?? chunkIVJEUGWF_js.generateIdempotencyKey();
154
+ return chunkIVJEUGWF_js.safe(
155
155
  this.client.post(
156
156
  `/api/v1/subscriptions/${encodedId}/cancel`,
157
157
  { reason },
@@ -161,20 +161,20 @@ var SubscriptionService = class {
161
161
  }
162
162
  async pause(id) {
163
163
  const encodedId = encodeURIComponent(id);
164
- return chunkGHFDYM5K_js.safe(
164
+ return chunkIVJEUGWF_js.safe(
165
165
  this.client.post(`/api/v1/subscriptions/${encodedId}/pause`)
166
166
  );
167
167
  }
168
168
  async resume(id) {
169
169
  const encodedId = encodeURIComponent(id);
170
- return chunkGHFDYM5K_js.safe(
170
+ return chunkIVJEUGWF_js.safe(
171
171
  this.client.post(`/api/v1/subscriptions/${encodedId}/resume`)
172
172
  );
173
173
  }
174
174
  async skipNextRenewal(id, opts) {
175
175
  const encodedId = encodeURIComponent(id);
176
- const idempotencyKey = opts?.idempotencyKey ?? chunkGHFDYM5K_js.generateIdempotencyKey();
177
- return chunkGHFDYM5K_js.safe(
176
+ const idempotencyKey = opts?.idempotencyKey ?? chunkIVJEUGWF_js.generateIdempotencyKey();
177
+ return chunkIVJEUGWF_js.safe(
178
178
  this.client.post(
179
179
  `/api/v1/subscriptions/${encodedId}/skip`,
180
180
  void 0,
@@ -190,8 +190,8 @@ var UploadService = class {
190
190
  this.client = client;
191
191
  }
192
192
  async init(filename, contentType, sizeBytes, opts) {
193
- const idempotencyKey = opts?.idempotencyKey ?? chunkGHFDYM5K_js.generateIdempotencyKey();
194
- return chunkGHFDYM5K_js.safe(
193
+ const idempotencyKey = opts?.idempotencyKey ?? chunkIVJEUGWF_js.generateIdempotencyKey();
194
+ return chunkIVJEUGWF_js.safe(
195
195
  this.client.post(
196
196
  "/api/v1/uploads/init",
197
197
  {
@@ -204,7 +204,7 @@ var UploadService = class {
204
204
  );
205
205
  }
206
206
  async confirm(uploadId) {
207
- return chunkGHFDYM5K_js.safe(
207
+ return chunkIVJEUGWF_js.safe(
208
208
  this.client.post("/api/v1/uploads/confirm", {
209
209
  upload_id: uploadId
210
210
  })
@@ -250,7 +250,7 @@ var PlacesService = class {
250
250
  this.client = client;
251
251
  }
252
252
  async autocomplete(input, sessionToken) {
253
- return chunkGHFDYM5K_js.safe(
253
+ return chunkIVJEUGWF_js.safe(
254
254
  this.client.post("/api/v1/places/autocomplete", {
255
255
  input,
256
256
  sessionToken
@@ -258,7 +258,7 @@ var PlacesService = class {
258
258
  );
259
259
  }
260
260
  async details(placeId, sessionToken) {
261
- return chunkGHFDYM5K_js.safe(
261
+ return chunkIVJEUGWF_js.safe(
262
262
  this.client.post("/api/v1/places/details", {
263
263
  place_id: placeId,
264
264
  sessionToken
@@ -277,7 +277,7 @@ var DeliveryService = class {
277
277
  params.set("dropoff_lat", String(dropoffLat));
278
278
  params.set("dropoff_lng", String(dropoffLng));
279
279
  if (country) params.set("country", country);
280
- return chunkGHFDYM5K_js.safe(
280
+ return chunkIVJEUGWF_js.safe(
281
281
  this.client.get(`/api/v1/delivery/fee?${params.toString()}`)
282
282
  );
283
283
  }
@@ -289,21 +289,112 @@ var DeliveryService = class {
289
289
  params.set("dropoff_lng", String(dropoffLng));
290
290
  if (opts?.country) params.set("country", opts.country);
291
291
  if (opts?.orderValue != null) params.set("order_value", String(opts.orderValue));
292
- return chunkGHFDYM5K_js.safe(
292
+ return chunkIVJEUGWF_js.safe(
293
293
  this.client.get(`/api/v1/delivery/options?${params.toString()}`)
294
294
  );
295
295
  }
296
296
  };
297
297
 
298
+ // src/internal/events.ts
299
+ var MUTATION_ERROR = "mutation:error";
300
+ var AUTH_TOKEN_CHANGED = "auth:token-changed";
301
+ var SESSION_CLAIMED = "session:claimed";
302
+ var SESSION_CLEARED = "session:cleared";
303
+ function createClientEvents() {
304
+ const listeners = /* @__PURE__ */ new Map();
305
+ return {
306
+ on(name, listener) {
307
+ let set = listeners.get(name);
308
+ if (!set) {
309
+ set = /* @__PURE__ */ new Set();
310
+ listeners.set(name, set);
311
+ }
312
+ set.add(listener);
313
+ return () => {
314
+ set?.delete(listener);
315
+ };
316
+ },
317
+ off(name, listener) {
318
+ listeners.get(name)?.delete(listener);
319
+ },
320
+ emit(name, payload) {
321
+ const set = listeners.get(name);
322
+ if (!set) return;
323
+ const snapshot = Array.from(set);
324
+ for (const listener of snapshot) {
325
+ try {
326
+ listener(payload);
327
+ } catch (err2) {
328
+ console.error(`[Cimplify] event listener for "${name}" threw:`, err2);
329
+ }
330
+ }
331
+ }
332
+ };
333
+ }
334
+
298
335
  // src/support.ts
299
336
  var SupportService = class {
300
337
  constructor(client) {
301
338
  this.client = client;
339
+ this.claimInFlight = null;
340
+ this.lastClaimedAccessToken = null;
341
+ this.claimedName = null;
342
+ this.client.events.on(SESSION_CLEARED, () => {
343
+ this.lastClaimedAccessToken = null;
344
+ this.claimedName = null;
345
+ });
346
+ }
347
+ /** The verified customer this session's conversation was claimed for, null while anonymous. */
348
+ get claimedCustomerName() {
349
+ return this.claimedName;
350
+ }
351
+ /**
352
+ * Claim the anonymous session for the verified Link identity: the server
353
+ * verifies the access token, rotates the session token (adopted here, so
354
+ * every subsequent request rides the bound session), folds the guest cart
355
+ * in, and adopts or merges the widget conversation.
356
+ *
357
+ * Idempotent and single-flight: concurrent calls share one request, and a
358
+ * token already claimed by this instance short-circuits without a network
359
+ * round trip. Emits `session:claimed` on the client's event channel.
360
+ */
361
+ async claimConversation() {
362
+ const accessToken = this.client.getAccessToken();
363
+ if (!accessToken) {
364
+ return chunkIVJEUGWF_js.err(new chunkAETVRBKI_js.CimplifyError("not_authenticated", "No access token to claim with"));
365
+ }
366
+ if (this.claimInFlight) return this.claimInFlight;
367
+ if (this.lastClaimedAccessToken === accessToken) {
368
+ return chunkIVJEUGWF_js.err(new chunkAETVRBKI_js.CimplifyError("already_claimed", "Session already claimed for this token"));
369
+ }
370
+ this.claimInFlight = (async () => {
371
+ const result = await chunkIVJEUGWF_js.safe(
372
+ this.client.post("/api/v1/support/conversation/claim", {
373
+ access_token: accessToken
374
+ })
375
+ );
376
+ if (result.ok) {
377
+ this.lastClaimedAccessToken = accessToken;
378
+ this.claimedName = result.value.customer_name || null;
379
+ this.client.adoptSessionToken(result.value.session_token);
380
+ this.client.events.emit(SESSION_CLAIMED, {
381
+ sessionToken: result.value.session_token,
382
+ threadId: result.value.thread_id ?? null,
383
+ customerName: result.value.customer_name
384
+ });
385
+ }
386
+ return result;
387
+ })();
388
+ try {
389
+ return await this.claimInFlight;
390
+ } finally {
391
+ this.claimInFlight = null;
392
+ }
302
393
  }
303
394
  /** Open (or resume) the customer's widget conversation. */
304
395
  async openConversation(opts) {
305
- const idempotencyKey = opts?.idempotencyKey ?? chunkGHFDYM5K_js.generateIdempotencyKey();
306
- return chunkGHFDYM5K_js.safe(
396
+ const idempotencyKey = opts?.idempotencyKey ?? chunkIVJEUGWF_js.generateIdempotencyKey();
397
+ return chunkIVJEUGWF_js.safe(
307
398
  this.client.post("/api/v1/support/conversation", void 0, {
308
399
  idempotencyKey
309
400
  })
@@ -318,8 +409,8 @@ var SupportService = class {
318
409
  * server resolves it thread-scoped and echoes the quote as `reply_to`.
319
410
  */
320
411
  async sendMessage(content, opts) {
321
- const idempotencyKey = opts?.idempotencyKey ?? chunkGHFDYM5K_js.generateIdempotencyKey();
322
- return chunkGHFDYM5K_js.safe(
412
+ const idempotencyKey = opts?.idempotencyKey ?? chunkIVJEUGWF_js.generateIdempotencyKey();
413
+ return chunkIVJEUGWF_js.safe(
323
414
  this.client.post(
324
415
  "/api/v1/support/conversation/messages",
325
416
  {
@@ -343,11 +434,11 @@ var SupportService = class {
343
434
  if (options.limit) params.set("limit", String(options.limit));
344
435
  const query = params.toString();
345
436
  const path = query ? `/api/v1/support/conversation/messages?${query}` : "/api/v1/support/conversation/messages";
346
- return chunkGHFDYM5K_js.safe(this.client.get(path));
437
+ return chunkIVJEUGWF_js.safe(this.client.get(path));
347
438
  }
348
439
  /** React to a message in the active conversation by its `ChatMessage.id`. */
349
440
  async reactToMessage(messageId, emoji) {
350
- return chunkGHFDYM5K_js.safe(
441
+ return chunkIVJEUGWF_js.safe(
351
442
  this.client.post(
352
443
  `/api/v1/support/conversation/messages/${messageId}/reactions`,
353
444
  { emoji }
@@ -356,8 +447,8 @@ var SupportService = class {
356
447
  }
357
448
  /** Ask for a person: flags the thread for the merchant's inbox. */
358
449
  async requestHuman(opts) {
359
- const idempotencyKey = opts?.idempotencyKey ?? chunkGHFDYM5K_js.generateIdempotencyKey();
360
- return chunkGHFDYM5K_js.safe(
450
+ const idempotencyKey = opts?.idempotencyKey ?? chunkIVJEUGWF_js.generateIdempotencyKey();
451
+ return chunkIVJEUGWF_js.safe(
361
452
  this.client.post(
362
453
  "/api/v1/support/conversation/handoff",
363
454
  void 0,
@@ -367,39 +458,6 @@ var SupportService = class {
367
458
  }
368
459
  };
369
460
 
370
- // src/internal/events.ts
371
- function createClientEvents() {
372
- const listeners = /* @__PURE__ */ new Map();
373
- return {
374
- on(name, listener) {
375
- let set = listeners.get(name);
376
- if (!set) {
377
- set = /* @__PURE__ */ new Set();
378
- listeners.set(name, set);
379
- }
380
- set.add(listener);
381
- return () => {
382
- set?.delete(listener);
383
- };
384
- },
385
- off(name, listener) {
386
- listeners.get(name)?.delete(listener);
387
- },
388
- emit(name, payload) {
389
- const set = listeners.get(name);
390
- if (!set) return;
391
- const snapshot = Array.from(set);
392
- for (const listener of snapshot) {
393
- try {
394
- listener(payload);
395
- } catch (err) {
396
- console.error(`[Cimplify] event listener for "${name}" threw:`, err);
397
- }
398
- }
399
- }
400
- };
401
- }
402
-
403
461
  // src/client.ts
404
462
  var SESSION_TOKEN_STORAGE_KEY = "cimplify_session_token";
405
463
  var ORDER_TOKEN_PREFIX = "cimplify_ot_";
@@ -579,6 +637,28 @@ var CimplifyClient = class {
579
637
  newToken: token,
580
638
  source: "manual"
581
639
  });
640
+ this.events.emit(AUTH_TOKEN_CHANGED, { token });
641
+ }
642
+ /**
643
+ * Zero-UI claim: a freshly verified customer identity (OTP verify, silent
644
+ * refresh restore) binds the anonymous session so the conversation, cart
645
+ * and orders survive a cleared browser. Best-effort by design — a failed
646
+ * claim leaves the session anonymous, exactly as it was. Called by the
647
+ * auth flows, never by the raw token setter.
648
+ */
649
+ autoClaimChatIdentity() {
650
+ if (typeof window === "undefined" || !this.sessionToken || !this.accessToken) return;
651
+ void this.support.claimConversation();
652
+ }
653
+ /**
654
+ * Adopt a server-rotated session token (claim flow). The old token stays
655
+ * in flight-safe use until the next request; the storage swap makes the
656
+ * rotation durable across reloads.
657
+ */
658
+ adoptSessionToken(token) {
659
+ if (!token || token === this.sessionToken) return;
660
+ this.sessionToken = token;
661
+ this.saveSessionToken(token);
582
662
  }
583
663
  clearSession() {
584
664
  const previous = this.accessToken;
@@ -593,6 +673,8 @@ var CimplifyClient = class {
593
673
  newToken: null,
594
674
  source: "clear"
595
675
  });
676
+ this.events.emit(AUTH_TOKEN_CHANGED, { token: null });
677
+ this.events.emit(SESSION_CLEARED, {});
596
678
  }
597
679
  setOrderToken(orderId, token) {
598
680
  if (typeof window !== "undefined" && window.localStorage) {
@@ -999,25 +1081,25 @@ var CimplifyClient = class {
999
1081
  }
1000
1082
  get catalogue() {
1001
1083
  if (!this._catalogue) {
1002
- this._catalogue = new chunkGHFDYM5K_js.CatalogueQueries(this);
1084
+ this._catalogue = new chunkIVJEUGWF_js.CatalogueQueries(this);
1003
1085
  }
1004
1086
  return this._catalogue;
1005
1087
  }
1006
1088
  get cart() {
1007
1089
  if (!this._cart) {
1008
- this._cart = new chunkGHFDYM5K_js.CartOperations(this);
1090
+ this._cart = new chunkIVJEUGWF_js.CartOperations(this);
1009
1091
  }
1010
1092
  return this._cart;
1011
1093
  }
1012
1094
  get checkout() {
1013
1095
  if (!this._checkout) {
1014
- this._checkout = new chunkGHFDYM5K_js.CheckoutService(this);
1096
+ this._checkout = new chunkIVJEUGWF_js.CheckoutService(this);
1015
1097
  }
1016
1098
  return this._checkout;
1017
1099
  }
1018
1100
  get orders() {
1019
1101
  if (!this._orders) {
1020
- this._orders = new chunkGHFDYM5K_js.OrderQueries(this);
1102
+ this._orders = new chunkIVJEUGWF_js.OrderQueries(this);
1021
1103
  }
1022
1104
  return this._orders;
1023
1105
  }
@@ -1047,43 +1129,43 @@ var CimplifyClient = class {
1047
1129
  }
1048
1130
  get link() {
1049
1131
  if (!this._link) {
1050
- this._link = new chunkGHFDYM5K_js.LinkService(this);
1132
+ this._link = new chunkIVJEUGWF_js.LinkService(this);
1051
1133
  }
1052
1134
  return this._link;
1053
1135
  }
1054
1136
  get auth() {
1055
1137
  if (!this._auth) {
1056
- this._auth = new chunkGHFDYM5K_js.AuthService(this);
1138
+ this._auth = new chunkIVJEUGWF_js.AuthService(this);
1057
1139
  }
1058
1140
  return this._auth;
1059
1141
  }
1060
1142
  get business() {
1061
1143
  if (!this._business) {
1062
- this._business = new chunkGHFDYM5K_js.BusinessService(this);
1144
+ this._business = new chunkIVJEUGWF_js.BusinessService(this);
1063
1145
  }
1064
1146
  return this._business;
1065
1147
  }
1066
1148
  get inventory() {
1067
1149
  if (!this._inventory) {
1068
- this._inventory = new chunkGHFDYM5K_js.InventoryService(this);
1150
+ this._inventory = new chunkIVJEUGWF_js.InventoryService(this);
1069
1151
  }
1070
1152
  return this._inventory;
1071
1153
  }
1072
1154
  get scheduling() {
1073
1155
  if (!this._scheduling) {
1074
- this._scheduling = new chunkGHFDYM5K_js.SchedulingService(this);
1156
+ this._scheduling = new chunkIVJEUGWF_js.SchedulingService(this);
1075
1157
  }
1076
1158
  return this._scheduling;
1077
1159
  }
1078
1160
  get lite() {
1079
1161
  if (!this._lite) {
1080
- this._lite = new chunkGHFDYM5K_js.LiteService(this);
1162
+ this._lite = new chunkIVJEUGWF_js.LiteService(this);
1081
1163
  }
1082
1164
  return this._lite;
1083
1165
  }
1084
1166
  get fx() {
1085
1167
  if (!this._fx) {
1086
- this._fx = new chunkGHFDYM5K_js.FxService(this);
1168
+ this._fx = new chunkIVJEUGWF_js.FxService(this);
1087
1169
  }
1088
1170
  return this._fx;
1089
1171
  }
@@ -1118,7 +1200,7 @@ var CimplifyClient = class {
1118
1200
  if (businessId) {
1119
1201
  this.setBusinessId(businessId);
1120
1202
  }
1121
- return chunkGHFDYM5K_js.createElements(this, businessId ?? this.businessId ?? void 0, options);
1203
+ return chunkIVJEUGWF_js.createElements(this, businessId ?? this.businessId ?? void 0, options);
1122
1204
  }
1123
1205
  };
1124
1206
  function createCimplifyClient(config = {}) {
@@ -1128,7 +1210,10 @@ function createCimplifyClient(config = {}) {
1128
1210
  exports.ActivityService = ActivityService;
1129
1211
  exports.CimplifyClient = CimplifyClient;
1130
1212
  exports.DeliveryService = DeliveryService;
1213
+ exports.MUTATION_ERROR = MUTATION_ERROR;
1131
1214
  exports.PlacesService = PlacesService;
1215
+ exports.SESSION_CLAIMED = SESSION_CLAIMED;
1216
+ exports.SESSION_CLEARED = SESSION_CLEARED;
1132
1217
  exports.StoreCreditQueries = StoreCreditQueries;
1133
1218
  exports.SubscriptionService = SubscriptionService;
1134
1219
  exports.SupportService = SupportService;
@@ -74,6 +74,85 @@ function getVariantDisplayName(variant, productName) {
74
74
  return productName || (variant.is_default ? "Default" : "Option");
75
75
  }
76
76
 
77
+ // src/utils/price-basis.ts
78
+ var MULTI_DAY_UNITS = /* @__PURE__ */ new Set([
79
+ "days",
80
+ "nights",
81
+ "weeks",
82
+ "months",
83
+ "years"
84
+ ]);
85
+ var PERIOD_LABELS = {
86
+ minutes: "session",
87
+ hours: "session",
88
+ days: "day",
89
+ nights: "night",
90
+ weeks: "week",
91
+ months: "month",
92
+ years: "year"
93
+ };
94
+ function isMultiDayService(product) {
95
+ if ((product.type || "product") !== "service") return false;
96
+ if (product.scheduling_mode) return product.scheduling_mode === "multi_day";
97
+ return product.duration_unit != null && MULTI_DAY_UNITS.has(product.duration_unit);
98
+ }
99
+ function priceBasisLabel(product) {
100
+ if ((product.type || "product") !== "service") return null;
101
+ const basis = product.price_basis ?? (isMultiDayService(product) ? "per_duration_unit" : null);
102
+ if (basis === null || basis === "flat") return null;
103
+ if (basis === "per_person") return "person";
104
+ return PERIOD_LABELS[product.duration_unit ?? "nights"];
105
+ }
106
+ var DAY_MS = 864e5;
107
+ function utcDateParts(iso) {
108
+ const date = new Date(iso);
109
+ if (Number.isNaN(date.getTime())) return null;
110
+ return { year: date.getUTCFullYear(), month: date.getUTCMonth() + 1, day: date.getUTCDate() };
111
+ }
112
+ function stayPeriods(scheduledStart, scheduledEnd, durationUnit) {
113
+ const start = utcDateParts(scheduledStart);
114
+ const end = utcDateParts(scheduledEnd);
115
+ if (!start || !end) return 1;
116
+ const days = Math.max(
117
+ 1,
118
+ Math.round(
119
+ (Date.UTC(end.year, end.month - 1, end.day) - Date.UTC(start.year, start.month - 1, start.day)) / DAY_MS
120
+ )
121
+ );
122
+ switch (durationUnit) {
123
+ case "weeks":
124
+ return Math.max(1, Math.ceil(days / 7));
125
+ case "months": {
126
+ let months = (end.year - start.year) * 12 + (end.month - start.month);
127
+ if (end.day > start.day) months += 1;
128
+ return Math.max(1, months);
129
+ }
130
+ case "years": {
131
+ let years = end.year - start.year;
132
+ if (end.month > start.month || end.month === start.month && end.day > start.day) {
133
+ years += 1;
134
+ }
135
+ return Math.max(1, years);
136
+ }
137
+ default:
138
+ return days;
139
+ }
140
+ }
141
+ function stayLength(scheduledStart, scheduledEnd, durationUnit) {
142
+ const periods = stayPeriods(scheduledStart, scheduledEnd, durationUnit);
143
+ const label = PERIOD_LABELS[durationUnit ?? "nights"];
144
+ return `${periods} ${label}${periods === 1 ? "" : "s"}`;
145
+ }
146
+ function serviceBillingMultiplier(product, selection) {
147
+ if ((product.type || "product") !== "service") return null;
148
+ const basis = product.price_basis ?? (isMultiDayService(product) ? "per_duration_unit" : "per_person");
149
+ const units = Math.max(1, selection.units ?? 1);
150
+ if (basis === "flat") return units;
151
+ if (basis === "per_person") return Math.max(1, selection.quantity) * units;
152
+ const periods = selection.scheduledStart && selection.scheduledEnd ? stayPeriods(selection.scheduledStart, selection.scheduledEnd, product.duration_unit) : 1;
153
+ return periods * units;
154
+ }
155
+
77
156
  // src/types/product.ts
78
157
  var PRODUCT_TYPE = {
79
158
  Product: "product",
@@ -174,4 +253,9 @@ exports.allGalleryImages = allGalleryImages;
174
253
  exports.assetUrl = assetUrl;
175
254
  exports.getVariantDisplayName = getVariantDisplayName;
176
255
  exports.isCimplifyAsset = isCimplifyAsset;
256
+ exports.isMultiDayService = isMultiDayService;
257
+ exports.priceBasisLabel = priceBasisLabel;
177
258
  exports.resolveGallery = resolveGallery;
259
+ exports.serviceBillingMultiplier = serviceBillingMultiplier;
260
+ exports.stayLength = stayLength;
261
+ exports.stayPeriods = stayPeriods;
@@ -1673,7 +1673,10 @@ var CheckoutService = class {
1673
1673
  idempotency_key: data.idempotency_key || generateIdempotencyKey(),
1674
1674
  metadata: data.metadata,
1675
1675
  pay_currency: data.pay_currency,
1676
- fx_quote_id: data.fx_quote_id
1676
+ fx_quote_id: data.fx_quote_id,
1677
+ use_store_credit: data.use_store_credit,
1678
+ voucher_code: data.voucher_code,
1679
+ pay_deposit: data.pay_deposit
1677
1680
  };
1678
1681
  const baseCurrency = chunkAETVRBKI_js.currencyCode(
1679
1682
  (cart.pricing.currency || checkoutData.pay_currency || "GHS").toUpperCase()
@@ -1804,6 +1807,7 @@ var LinkService = class {
1804
1807
  );
1805
1808
  if (result.ok && result.value.session_token) {
1806
1809
  this.client.setAccessToken(result.value.session_token);
1810
+ this.client.autoClaimChatIdentity();
1807
1811
  }
1808
1812
  return result;
1809
1813
  }
@@ -1815,6 +1819,7 @@ var LinkService = class {
1815
1819
  );
1816
1820
  if (result.ok && result.value.session_token) {
1817
1821
  this.client.setAccessToken(result.value.session_token);
1822
+ this.client.autoClaimChatIdentity();
1818
1823
  }
1819
1824
  return result;
1820
1825
  }
@@ -2000,6 +2005,7 @@ var AuthService = class {
2000
2005
  );
2001
2006
  if (result.ok && result.value.session_token) {
2002
2007
  this.client.setAccessToken(result.value.session_token);
2008
+ this.client.autoClaimChatIdentity();
2003
2009
  }
2004
2010
  return result;
2005
2011
  }
@@ -2153,6 +2159,7 @@ var SchedulingService = class {
2153
2159
  service_id: input.service_id,
2154
2160
  date: input.date,
2155
2161
  participant_count: input.participant_count,
2162
+ units: input.units,
2156
2163
  variant_id: input.variant_id
2157
2164
  });
2158
2165
  return safe(this.client.get(path));
@@ -2173,6 +2180,7 @@ var SchedulingService = class {
2173
2180
  end_date: params.end_date,
2174
2181
  location_id: params.location_id,
2175
2182
  participant_count: params.participant_count,
2183
+ units: params.units,
2176
2184
  variant_id: params.variant_id
2177
2185
  });
2178
2186
  return safe(this.client.get(path));
@@ -3145,6 +3153,7 @@ var CimplifyElements = class {
3145
3153
  this.accessToken = token;
3146
3154
  this.accountId = decodeJwtSub(token);
3147
3155
  this.client.setAccessToken(token);
3156
+ this.client.autoClaimChatIdentity();
3148
3157
  await this.hydrateCustomerData();
3149
3158
  return {
3150
3159
  accountId: this.accountId ?? "",
@@ -2498,6 +2498,18 @@ function buildV1(deps) {
2498
2498
  return tryRoute(c, () => deps.support.react(c.req.param("messageId"), body.emoji ?? ""));
2499
2499
  });
2500
2500
  app.post("/support/conversation/handoff", (c) => c.json({ data: { requested: true } }));
2501
+ app.post("/support/conversation/claim", async (c) => {
2502
+ const body = await c.req.json().catch(() => ({}));
2503
+ if (!body.access_token) return c.json({ error: "access_token is required" }, 400);
2504
+ const session = c.var.session;
2505
+ return c.json({
2506
+ data: {
2507
+ session_token: session.token,
2508
+ thread_id: null,
2509
+ customer_name: session.customer_name ?? "Test User"
2510
+ }
2511
+ });
2512
+ });
2501
2513
  app.get(
2502
2514
  "/support/conversation/ws",
2503
2515
  (c) => c.json({ note: "WebSocket connection \u2014 connect via ws:// at the same path", supported: false }, 426)
@@ -2496,6 +2496,18 @@ function buildV1(deps) {
2496
2496
  return tryRoute(c, () => deps.support.react(c.req.param("messageId"), body.emoji ?? ""));
2497
2497
  });
2498
2498
  app.post("/support/conversation/handoff", (c) => c.json({ data: { requested: true } }));
2499
+ app.post("/support/conversation/claim", async (c) => {
2500
+ const body = await c.req.json().catch(() => ({}));
2501
+ if (!body.access_token) return c.json({ error: "access_token is required" }, 400);
2502
+ const session = c.var.session;
2503
+ return c.json({
2504
+ data: {
2505
+ session_token: session.token,
2506
+ thread_id: null,
2507
+ customer_name: session.customer_name ?? "Test User"
2508
+ }
2509
+ });
2510
+ });
2499
2511
  app.get(
2500
2512
  "/support/conversation/ws",
2501
2513
  (c) => c.json({ note: "WebSocket connection \u2014 connect via ws:// at the same path", supported: false }, 426)