@cimplify/sdk 0.104.0 → 0.104.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/advanced.d.mts +3 -7
  2. package/dist/advanced.d.ts +3 -7
  3. package/dist/advanced.js +23 -23
  4. package/dist/advanced.mjs +4 -4
  5. package/dist/{client-BuLcOWLv.d.ts → catalogue-BlQ85Uma.d.mts} +415 -763
  6. package/dist/{client-D5AoobFc.d.mts → catalogue-C8TqOj9K.d.ts} +415 -763
  7. package/dist/{payment-g0HFkEDU.d.mts → checkout-BqK9XUz5.d.mts} +3824 -1446
  8. package/dist/{payment-g0HFkEDU.d.ts → checkout-BqK9XUz5.d.ts} +3824 -1446
  9. package/dist/{chunk-GOHSXBKW.mjs → chunk-33VCYWVL.mjs} +25 -1
  10. package/dist/{chunk-2WPVUIHX.mjs → chunk-6G3ANKQA.mjs} +1030 -360
  11. package/dist/{chunk-E4K2VQDD.js → chunk-BWEIMKLF.js} +541 -16
  12. package/dist/{chunk-IQFFSKE2.js → chunk-DQEXY542.js} +1345 -746
  13. package/dist/{chunk-CNN7Z2IP.js → chunk-EV2EVOYS.js} +27 -0
  14. package/dist/{chunk-YVAEY3VC.js → chunk-HYFA67A7.js} +1034 -364
  15. package/dist/{chunk-5RT4HYMP.mjs → chunk-L5SNEU2O.mjs} +524 -15
  16. package/dist/{chunk-4BKOKHE3.js → chunk-RBNBSQI7.mjs} +217 -19
  17. package/dist/{chunk-H3RATH4B.mjs → chunk-SFUJMS5E.js} +261 -2
  18. package/dist/{chunk-DYIAX3WI.mjs → chunk-U54CWUUT.mjs} +11 -2
  19. package/dist/{chunk-OKADBZAI.mjs → chunk-UFOWPN3D.mjs} +808 -574
  20. package/dist/{chunk-OCCNG6MO.mjs → chunk-V4457OKB.mjs} +1310 -722
  21. package/dist/{chunk-5BDYDZ4U.js → chunk-WXREIBFW.js} +892 -657
  22. package/dist/{chunk-7PDEX54K.js → chunk-XAUSDMMZ.js} +13 -3
  23. package/dist/{client-BVNWjk6W.d.ts → client-DhXeiUrf.d.ts} +2 -2
  24. package/dist/{client-fM716k7G.d.mts → client-mXiUrV4X.d.mts} +2 -2
  25. package/dist/{index-BtcoqrY1.d.ts → index-B0AdZvrM.d.mts} +9 -4
  26. package/dist/{index-D7Tf3v7c.d.mts → index-CK8Nk5uQ.d.ts} +9 -4
  27. package/dist/index-DPWI5XcU.d.ts +8 -0
  28. package/dist/index-DVfUh-ci.d.mts +8 -0
  29. package/dist/index.d.mts +31 -14
  30. package/dist/index.d.ts +31 -14
  31. package/dist/index.js +305 -133
  32. package/dist/index.mjs +6 -6
  33. package/dist/mock/cli.mjs +1442 -386
  34. package/dist/mock/library.js +1168 -352
  35. package/dist/mock/library.mjs +1168 -352
  36. package/dist/mock/msw.js +1168 -352
  37. package/dist/mock/msw.mjs +1168 -352
  38. package/dist/{price-BLIeAb8K.d.ts → price-6hQIIac9.d.ts} +1 -1
  39. package/dist/{price-Czq_cTC_.d.mts → price-BUDv1rI7.d.mts} +1 -1
  40. package/dist/react.d.mts +10 -5
  41. package/dist/react.d.ts +10 -5
  42. package/dist/react.js +227 -197
  43. package/dist/react.mjs +90 -60
  44. package/dist/{server-DKK_D-PP.d.ts → server-DJ0mSs9i.d.mts} +31 -57
  45. package/dist/{server-BkVhOIwn.d.mts → server-DSTX76Ki.d.ts} +31 -57
  46. package/dist/server.d.mts +3 -4
  47. package/dist/server.d.ts +3 -4
  48. package/dist/server.js +11 -11
  49. package/dist/server.mjs +5 -5
  50. package/dist/styles.css +2 -2
  51. package/dist/testing/msw.d.mts +2 -2
  52. package/dist/testing/msw.d.ts +2 -2
  53. package/dist/testing/msw.js +4 -4
  54. package/dist/testing/msw.mjs +3 -3
  55. package/dist/testing/suite.d.mts +5 -6
  56. package/dist/testing/suite.d.ts +5 -6
  57. package/dist/testing/suite.js +29 -28
  58. package/dist/testing/suite.mjs +10 -9
  59. package/dist/testing.d.mts +2177 -14
  60. package/dist/testing.d.ts +2177 -14
  61. package/dist/testing.js +167 -89
  62. package/dist/testing.mjs +24 -10
  63. package/dist/utils.d.mts +3 -4
  64. package/dist/utils.d.ts +3 -4
  65. package/dist/utils.js +35 -31
  66. package/dist/utils.mjs +2 -2
  67. package/package.json +9 -9
  68. package/registry/order-history.json +1 -1
  69. package/registry/order-summary.json +1 -1
  70. package/dist/link-D9iSVxt5.d.mts +0 -308
  71. package/dist/link-D9iSVxt5.d.ts +0 -308
@@ -1,9 +1,9 @@
1
1
  import { messagePreview } from './chunk-U4MW6PYU.mjs';
2
- import { PAYMENT_METHOD } from './chunk-GOHSXBKW.mjs';
3
- import { ErrorCode } from './chunk-H3RATH4B.mjs';
2
+ import { AUTHORIZATION_TYPE, CHECKOUT_ORDER_RESULT_STATUS, CHECKOUT_NEXT_ACTION, PAYMENT_METHOD, DEFAULT_CURRENCY } from './chunk-33VCYWVL.mjs';
3
+ import { PURCHASE_INTENT_MOBILE_MONEY_NETWORK, ErrorCode, PURCHASE_INTENT_CONFIRM_STATUS, PURCHASE_INTENT_STATUS, PAYMENT_OPTION_STATUS, CHECKOUT_TERMS_COMPONENT, CHECKOUT_TERMS_DELTA_KIND, CHECKOUT_INVALIDATION_REASON, PURCHASE_INTENT_SOURCE_KIND, PURCHASE_INTENT_PAYMENT_METHOD, PURCHASE_INTENT_PAYMENT_PROVIDER, currencyCode, PURCHASE_INTENT_LINE_CONFIGURATION_KIND, PURCHASE_INTENT_SELLABLE_KIND, PURCHASING_PRINCIPAL_KIND, LEGACY_CHECKOUT_PAYMENT_STATUS, CHECKOUT_COMPLIANCE_REASON, CHECKOUT_COMPLIANCE_LANE, MOBILE_MONEY_TENDER_AUTHORITY_KIND, PAYMENT_OPTION_NEXT_ACTION, PAYMENT_COLLECTION_MODE } from './chunk-RBNBSQI7.mjs';
4
4
  import { __publicField, __privateAdd, __privateSet, __privateGet, __privateMethod, __privateWrapper } from './chunk-3G6RQLXK.mjs';
5
5
 
6
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/compose.js
6
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/compose.js
7
7
  var compose = (middleware, onError, onNotFound) => {
8
8
  return (context, next) => {
9
9
  let index = -1;
@@ -47,21 +47,46 @@ var compose = (middleware, onError, onNotFound) => {
47
47
  };
48
48
  };
49
49
 
50
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/request/constants.js
50
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/request/constants.js
51
51
  var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
52
52
 
53
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/utils/body.js
53
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/buffer.js
54
+ var bufferToFormData = (arrayBuffer, contentType) => {
55
+ const response = new Response(arrayBuffer, {
56
+ headers: {
57
+ // Normalize the media type (case-insensitive) while keeping parameters like the boundary
58
+ "Content-Type": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())
59
+ }
60
+ });
61
+ return response.formData();
62
+ };
63
+
64
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/body.js
65
+ var isRawRequest = (request) => "headers" in request;
54
66
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
55
67
  const { all = false, dot = false } = options;
56
- const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
68
+ const headers = isRawRequest(request) ? request.headers : request.raw.headers;
57
69
  const contentType = headers.get("Content-Type");
58
- if (contentType?.startsWith("multipart/form-data") || contentType?.startsWith("application/x-www-form-urlencoded")) {
70
+ const mediaType = contentType?.split(";")[0].trim().toLowerCase();
71
+ if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
59
72
  return parseFormData(request, { all, dot });
60
73
  }
61
74
  return {};
62
75
  };
63
76
  async function parseFormData(request, options) {
64
- const formData = await request.formData();
77
+ if (!isRawRequest(request) && request.bodyCache.formData) {
78
+ return convertFormDataToBodyData(
79
+ await request.bodyCache.formData,
80
+ options
81
+ );
82
+ }
83
+ const headers = isRawRequest(request) ? request.headers : request.raw.headers;
84
+ const arrayBuffer = await request.arrayBuffer();
85
+ const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
86
+ if (!isRawRequest(request)) {
87
+ request.bodyCache.formData = formDataPromise;
88
+ }
89
+ const formData = await formDataPromise;
65
90
  if (formData) {
66
91
  return convertFormDataToBodyData(formData, options);
67
92
  }
@@ -121,7 +146,7 @@ var handleParsingNestedValues = (form, key, value) => {
121
146
  });
122
147
  };
123
148
 
124
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/utils/url.js
149
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/url.js
125
150
  var splitPath = (path) => {
126
151
  const paths = path.split("/");
127
152
  if (paths[0] === "") {
@@ -227,13 +252,13 @@ var checkOptionalParameter = (path) => {
227
252
  if (segment !== "" && !/\:/.test(segment)) {
228
253
  basePath += "/" + segment;
229
254
  } else if (/\:/.test(segment)) {
230
- if (/\?/.test(segment)) {
255
+ if (segment.charCodeAt(segment.length - 1) === 63) {
231
256
  if (results.length === 0 && basePath === "") {
232
257
  results.push("/");
233
258
  } else {
234
259
  results.push(basePath);
235
260
  }
236
- const optionalSegment = segment.replace("?", "");
261
+ const optionalSegment = segment.slice(0, -1);
237
262
  basePath += "/" + optionalSegment;
238
263
  results.push(basePath);
239
264
  } else {
@@ -243,18 +268,16 @@ var checkOptionalParameter = (path) => {
243
268
  });
244
269
  return results.filter((v, i, a) => a.indexOf(v) === i);
245
270
  };
271
+ var tryDecodeURIComponent = (str) => str.indexOf("%") !== -1 ? tryDecode(str, decodeURIComponent_) : str;
246
272
  var _decodeURI = (value) => {
247
- if (!/[%+]/.test(value)) {
248
- return value;
249
- }
250
273
  if (value.indexOf("+") !== -1) {
251
274
  value = value.replace(/\+/g, " ");
252
275
  }
253
- return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
276
+ return tryDecodeURIComponent(value);
254
277
  };
255
278
  var _getQueryParam = (url, key, multiple) => {
256
279
  let encoded;
257
- if (!multiple && key && !/[%+]/.test(key)) {
280
+ if (!multiple && key && key.indexOf("%") === -1 && key.indexOf("+") === -1) {
258
281
  let keyIndex2 = url.indexOf("?", 8);
259
282
  if (keyIndex2 === -1) {
260
283
  return void 0;
@@ -278,7 +301,7 @@ var _getQueryParam = (url, key, multiple) => {
278
301
  return void 0;
279
302
  }
280
303
  }
281
- const results = {};
304
+ const results = /* @__PURE__ */ Object.create(null);
282
305
  encoded ?? (encoded = /[%+]/.test(url));
283
306
  let keyIndex = url.indexOf("?", 8);
284
307
  while (keyIndex !== -1) {
@@ -324,8 +347,7 @@ var getQueryParams = (url, key) => {
324
347
  };
325
348
  var decodeURIComponent_ = decodeURIComponent;
326
349
 
327
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/request.js
328
- var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
350
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/request.js
329
351
  var _validatedData, _matchResult, _HonoRequest_instances, getDecodedParam_fn, getAllDecodedParams_fn, getParamValue_fn, _cachedBody, _a;
330
352
  var HonoRequest = (_a = class {
331
353
  constructor(request, path = "/", matchResult = [[]]) {
@@ -369,8 +391,7 @@ var HonoRequest = (_a = class {
369
391
  if (cachedBody) {
370
392
  return cachedBody;
371
393
  }
372
- const anyCachedKey = Object.keys(bodyCache)[0];
373
- if (anyCachedKey) {
394
+ for (const anyCachedKey in bodyCache) {
374
395
  return bodyCache[anyCachedKey].then((body) => {
375
396
  if (anyCachedKey === "json") {
376
397
  body = JSON.stringify(body);
@@ -383,7 +404,6 @@ var HonoRequest = (_a = class {
383
404
  this.raw = request;
384
405
  this.path = path;
385
406
  __privateSet(this, _matchResult, matchResult);
386
- __privateSet(this, _validatedData, {});
387
407
  }
388
408
  param(key) {
389
409
  return key ? __privateMethod(this, _HonoRequest_instances, getDecodedParam_fn).call(this, key) : __privateMethod(this, _HonoRequest_instances, getAllDecodedParams_fn).call(this);
@@ -398,7 +418,7 @@ var HonoRequest = (_a = class {
398
418
  if (name) {
399
419
  return this.raw.headers.get(name) ?? void 0;
400
420
  }
401
- const headerData = {};
421
+ const headerData = /* @__PURE__ */ Object.create(null);
402
422
  this.raw.headers.forEach((value, key) => {
403
423
  headerData[key] = value;
404
424
  });
@@ -500,10 +520,10 @@ var HonoRequest = (_a = class {
500
520
  * @param data - The validated data to add.
501
521
  */
502
522
  addValidatedData(target, data) {
503
- __privateGet(this, _validatedData)[target] = data;
523
+ (__privateGet(this, _validatedData) ?? __privateSet(this, _validatedData, {}))[target] = data;
504
524
  }
505
525
  valid(target) {
506
- return __privateGet(this, _validatedData)[target];
526
+ return __privateGet(this, _validatedData)?.[target];
507
527
  }
508
528
  /**
509
529
  * `.url()` can get the request url strings.
@@ -591,14 +611,14 @@ var HonoRequest = (_a = class {
591
611
  }, _validatedData = new WeakMap(), _matchResult = new WeakMap(), _HonoRequest_instances = new WeakSet(), getDecodedParam_fn = function(key) {
592
612
  const paramKey = __privateGet(this, _matchResult)[0][this.routeIndex][1][key];
593
613
  const param = __privateMethod(this, _HonoRequest_instances, getParamValue_fn).call(this, paramKey);
594
- return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
614
+ return param && tryDecodeURIComponent(param);
595
615
  }, getAllDecodedParams_fn = function() {
596
616
  const decoded = {};
597
617
  const keys = Object.keys(__privateGet(this, _matchResult)[0][this.routeIndex][1]);
598
618
  for (const key of keys) {
599
619
  const value = __privateMethod(this, _HonoRequest_instances, getParamValue_fn).call(this, __privateGet(this, _matchResult)[0][this.routeIndex][1][key]);
600
620
  if (value !== void 0) {
601
- decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
621
+ decoded[key] = tryDecodeURIComponent(value);
602
622
  }
603
623
  }
604
624
  return decoded;
@@ -606,7 +626,7 @@ var HonoRequest = (_a = class {
606
626
  return __privateGet(this, _matchResult)[1] ? __privateGet(this, _matchResult)[1][paramKey] : paramKey;
607
627
  }, _cachedBody = new WeakMap(), _a);
608
628
 
609
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/utils/html.js
629
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/html.js
610
630
  var HtmlEscapedCallbackPhase = {
611
631
  Stringify: 1};
612
632
  var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
@@ -637,7 +657,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
637
657
  }
638
658
  };
639
659
 
640
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/context.js
660
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/context.js
641
661
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
642
662
  var setDefaultContentType = (contentType, headers) => {
643
663
  return {
@@ -1010,11 +1030,11 @@ var Context = (_a2 = class {
1010
1030
  return Object.fromEntries(__privateGet(this, _var));
1011
1031
  }
1012
1032
  }, _rawRequest = new WeakMap(), _req = new WeakMap(), _var = new WeakMap(), _status = new WeakMap(), _executionCtx = new WeakMap(), _res = new WeakMap(), _layout = new WeakMap(), _renderer = new WeakMap(), _notFoundHandler = new WeakMap(), _preparedHeaders = new WeakMap(), _matchResult2 = new WeakMap(), _path = new WeakMap(), _Context_instances = new WeakSet(), newResponse_fn = function(data, arg, headers) {
1013
- const responseHeaders = __privateGet(this, _res) ? new Headers(__privateGet(this, _res).headers) : __privateGet(this, _preparedHeaders) ?? new Headers();
1014
- if (typeof arg === "object" && "headers" in arg) {
1015
- const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
1016
- for (const [key, value] of argHeaders) {
1017
- if (key.toLowerCase() === "set-cookie") {
1033
+ let responseHeaders = __privateGet(this, _res) ? new Headers(__privateGet(this, _res).headers) : __privateGet(this, _preparedHeaders);
1034
+ if (typeof arg === "object" && arg.headers) {
1035
+ responseHeaders ?? (responseHeaders = new Headers());
1036
+ for (const [key, value] of new Headers(arg.headers)) {
1037
+ if (key === "set-cookie") {
1018
1038
  responseHeaders.append(key, value);
1019
1039
  } else {
1020
1040
  responseHeaders.set(key, value);
@@ -1022,33 +1042,48 @@ var Context = (_a2 = class {
1022
1042
  }
1023
1043
  }
1024
1044
  if (headers) {
1025
- for (const [k, v] of Object.entries(headers)) {
1026
- if (typeof v === "string") {
1027
- responseHeaders.set(k, v);
1028
- } else {
1029
- responseHeaders.delete(k);
1030
- for (const v2 of v) {
1031
- responseHeaders.append(k, v2);
1045
+ if (!responseHeaders) {
1046
+ let count = 0;
1047
+ for (const k in headers) {
1048
+ if (++count > 1 || typeof headers[k] !== "string") {
1049
+ responseHeaders = new Headers();
1050
+ break;
1051
+ }
1052
+ }
1053
+ }
1054
+ if (responseHeaders) {
1055
+ for (const k in headers) {
1056
+ const v = headers[k];
1057
+ if (typeof v === "string") {
1058
+ responseHeaders.set(k, v);
1059
+ } else {
1060
+ responseHeaders.delete(k);
1061
+ for (const v2 of v) {
1062
+ responseHeaders.append(k, v2);
1063
+ }
1032
1064
  }
1033
1065
  }
1034
1066
  }
1035
1067
  }
1036
1068
  const status = typeof arg === "number" ? arg : arg?.status ?? __privateGet(this, _status);
1037
- return createResponseInstance(data, { status, headers: responseHeaders });
1069
+ return createResponseInstance(data, {
1070
+ status,
1071
+ headers: responseHeaders ?? headers
1072
+ });
1038
1073
  }, _a2);
1039
1074
 
1040
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router.js
1075
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router.js
1041
1076
  var METHOD_NAME_ALL = "ALL";
1042
1077
  var METHOD_NAME_ALL_LOWERCASE = "all";
1043
- var METHODS = ["get", "post", "put", "delete", "options", "patch"];
1078
+ var METHODS = ["get", "post", "put", "delete", "options", "patch", "query"];
1044
1079
  var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
1045
1080
  var UnsupportedPathError = class extends Error {
1046
1081
  };
1047
1082
 
1048
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/utils/constants.js
1083
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/constants.js
1049
1084
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
1050
1085
 
1051
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/hono-base.js
1086
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/hono-base.js
1052
1087
  var notFoundHandler = (c) => {
1053
1088
  return c.text("404 Not Found", 404);
1054
1089
  };
@@ -1070,6 +1105,7 @@ var Hono = (_a3 = class {
1070
1105
  __publicField(this, "delete");
1071
1106
  __publicField(this, "options");
1072
1107
  __publicField(this, "patch");
1108
+ __publicField(this, "query");
1073
1109
  __publicField(this, "all");
1074
1110
  __publicField(this, "on");
1075
1111
  __publicField(this, "use");
@@ -1131,8 +1167,8 @@ var Hono = (_a3 = class {
1131
1167
  * @see {@link https://hono.dev/docs/api/hono#fetch}
1132
1168
  *
1133
1169
  * @param {Request} request - request Object of request
1134
- * @param {Env} Env - env Object
1135
- * @param {ExecutionContext} - context of execution
1170
+ * @param {Env} env - env Object
1171
+ * @param {ExecutionContext} executionCtx - context of execution
1136
1172
  * @returns {Response | Promise<Response>} response of request
1137
1173
  *
1138
1174
  */
@@ -1423,7 +1459,7 @@ var Hono = (_a3 = class {
1423
1459
  })();
1424
1460
  }, _a3);
1425
1461
 
1426
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router/reg-exp-router/matcher.js
1462
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/matcher.js
1427
1463
  var emptyParam = [];
1428
1464
  function match(method, path) {
1429
1465
  const matchers = this.buildAllMatchers();
@@ -1444,7 +1480,7 @@ function match(method, path) {
1444
1480
  return match2(method, path);
1445
1481
  }
1446
1482
 
1447
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router/reg-exp-router/node.js
1483
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/node.js
1448
1484
  var LABEL_REG_EXP_STR = "[^/]+";
1449
1485
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
1450
1486
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
@@ -1458,7 +1494,7 @@ function compareKey(a, b) {
1458
1494
  return 1;
1459
1495
  }
1460
1496
  if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
1461
- return 1;
1497
+ return b === TAIL_WILDCARD_REG_EXP_STR ? -1 : 1;
1462
1498
  } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
1463
1499
  return -1;
1464
1500
  }
@@ -1472,77 +1508,76 @@ function compareKey(a, b) {
1472
1508
  var _index, _varIndex, _children, _a4;
1473
1509
  var Node = (_a4 = class {
1474
1510
  constructor() {
1511
+ // handler index of a dynamic path, or -1 for a static path terminal
1475
1512
  __privateAdd(this, _index);
1476
1513
  __privateAdd(this, _varIndex);
1477
1514
  __privateAdd(this, _children, /* @__PURE__ */ Object.create(null));
1478
1515
  }
1479
- insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
1480
- if (tokens.length === 0) {
1481
- if (__privateGet(this, _index) !== void 0) {
1482
- throw PATH_ERROR;
1483
- }
1484
- if (pathErrorCheckOnly) {
1485
- return;
1486
- }
1487
- __privateSet(this, _index, index);
1488
- return;
1489
- }
1490
- const [token, ...restTokens] = tokens;
1491
- const pattern = token === "*" ? restTokens.length === 0 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
1492
- let node;
1493
- if (pattern) {
1494
- const name = pattern[1];
1495
- let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
1496
- if (name && pattern[2]) {
1497
- if (regexpStr === ".*") {
1498
- throw PATH_ERROR;
1499
- }
1500
- regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
1501
- if (/\((?!\?:)/.test(regexpStr)) {
1502
- throw PATH_ERROR;
1503
- }
1504
- }
1505
- node = __privateGet(this, _children)[regexpStr];
1506
- if (!node) {
1507
- if (Object.keys(__privateGet(this, _children)).some(
1508
- (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
1509
- )) {
1510
- throw PATH_ERROR;
1516
+ insert(tokens, index, paramMap, context, isStatic) {
1517
+ let node = this;
1518
+ for (let i = 0, len = tokens.length; i < len; i++) {
1519
+ const token = tokens[i];
1520
+ const pattern = token.length === 1 ? token === "*" ? i === len - 1 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : null : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
1521
+ let nextNode;
1522
+ if (pattern) {
1523
+ const name = pattern[1];
1524
+ let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
1525
+ if (name && pattern[2]) {
1526
+ if (regexpStr === ".*") {
1527
+ throw PATH_ERROR;
1528
+ }
1529
+ regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
1530
+ if (/\((?!\?:)/.test(regexpStr)) {
1531
+ throw PATH_ERROR;
1532
+ }
1533
+ if (regexpStr.length === 1 && regExpMetaChars.has(regexpStr)) {
1534
+ throw PATH_ERROR;
1535
+ }
1511
1536
  }
1512
- if (pathErrorCheckOnly) {
1513
- return;
1537
+ nextNode = __privateGet(node, _children)[regexpStr];
1538
+ if (!nextNode) {
1539
+ if (regexpStr !== ONLY_WILDCARD_REG_EXP_STR && regexpStr !== TAIL_WILDCARD_REG_EXP_STR) {
1540
+ for (const k in __privateGet(node, _children)) {
1541
+ if (
1542
+ // a single-char pattern coexists with single-char literals as a literal does
1543
+ (regexpStr.length > 1 || k.length > 1) && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
1544
+ ) {
1545
+ throw PATH_ERROR;
1546
+ }
1547
+ }
1548
+ }
1549
+ nextNode = __privateGet(node, _children)[regexpStr] = new _a4();
1514
1550
  }
1515
- node = __privateGet(this, _children)[regexpStr] = new _a4();
1516
1551
  if (name !== "") {
1517
- __privateSet(node, _varIndex, context.varIndex++);
1552
+ __privateGet(nextNode, _varIndex) ?? __privateSet(nextNode, _varIndex, context.varIndex++);
1553
+ paramMap.push([name, __privateGet(nextNode, _varIndex)]);
1518
1554
  }
1519
- }
1520
- if (!pathErrorCheckOnly && name !== "") {
1521
- paramMap.push([name, __privateGet(node, _varIndex)]);
1522
- }
1523
- } else {
1524
- node = __privateGet(this, _children)[token];
1525
- if (!node) {
1526
- if (Object.keys(__privateGet(this, _children)).some(
1527
- (k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
1528
- )) {
1529
- throw PATH_ERROR;
1530
- }
1531
- if (pathErrorCheckOnly) {
1532
- return;
1555
+ } else {
1556
+ nextNode = __privateGet(node, _children)[token];
1557
+ if (!nextNode) {
1558
+ for (const k in __privateGet(node, _children)) {
1559
+ if (k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR) {
1560
+ throw PATH_ERROR;
1561
+ }
1562
+ }
1563
+ nextNode = __privateGet(node, _children)[token] = new _a4();
1533
1564
  }
1534
- node = __privateGet(this, _children)[token] = new _a4();
1535
1565
  }
1566
+ node = nextNode;
1536
1567
  }
1537
- node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
1568
+ if (__privateGet(node, _index) !== void 0) {
1569
+ throw PATH_ERROR;
1570
+ }
1571
+ __privateSet(node, _index, isStatic ? -1 : index);
1538
1572
  }
1539
1573
  buildRegExpStr() {
1540
1574
  const childKeys = Object.keys(__privateGet(this, _children)).sort(compareKey);
1541
1575
  const strList = childKeys.map((k) => {
1542
1576
  const c = __privateGet(this, _children)[k];
1543
- return (typeof __privateGet(c, _varIndex) === "number" ? `(${k})@${__privateGet(c, _varIndex)}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr();
1544
- });
1545
- if (typeof __privateGet(this, _index) === "number") {
1577
+ const childStr = c.buildRegExpStr();
1578
+ return childStr === "" ? "" : (typeof __privateGet(c, _varIndex) === "number" ? `(${k})@${__privateGet(c, _varIndex)}` : regExpMetaChars.has(k) ? `\\${k}` : k) + childStr;
1579
+ }).filter(Boolean);
1580
+ if (typeof __privateGet(this, _index) === "number" && __privateGet(this, _index) !== -1) {
1546
1581
  strList.unshift(`#${__privateGet(this, _index)}`);
1547
1582
  }
1548
1583
  if (strList.length === 0) {
@@ -1555,19 +1590,27 @@ var Node = (_a4 = class {
1555
1590
  }
1556
1591
  }, _index = new WeakMap(), _varIndex = new WeakMap(), _children = new WeakMap(), _a4);
1557
1592
 
1558
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router/reg-exp-router/trie.js
1559
- var _context, _root, _a5;
1593
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/trie.js
1594
+ var _context, _root, _index2, _a5;
1560
1595
  var Trie = (_a5 = class {
1561
1596
  constructor() {
1562
1597
  __privateAdd(this, _context, { varIndex: 0 });
1563
1598
  __privateAdd(this, _root, new Node());
1599
+ __privateAdd(this, _index2, 0);
1600
+ // dynamic path -> [handler index, param assoc]; static paths are not registered
1601
+ __publicField(this, "paths", /* @__PURE__ */ Object.create(null));
1564
1602
  }
1565
- insert(path, index, pathErrorCheckOnly) {
1603
+ insert(path, isStatic) {
1604
+ if (isStatic) {
1605
+ __privateGet(this, _root).insert(path.split(""), 0, [], __privateGet(this, _context), true);
1606
+ return;
1607
+ }
1566
1608
  const paramAssoc = [];
1567
1609
  const groups = [];
1610
+ let markedPath = path;
1568
1611
  for (let i = 0; ; ) {
1569
1612
  let replaced = false;
1570
- path = path.replace(/\{[^}]+\}/g, (m) => {
1613
+ markedPath = markedPath.replace(/\{[^}]+\}/g, (m) => {
1571
1614
  const mark = `@\\${i}`;
1572
1615
  groups[i] = [mark, m];
1573
1616
  i++;
@@ -1578,7 +1621,7 @@ var Trie = (_a5 = class {
1578
1621
  break;
1579
1622
  }
1580
1623
  }
1581
- const tokens = path.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
1624
+ const tokens = markedPath.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
1582
1625
  for (let i = groups.length - 1; i >= 0; i--) {
1583
1626
  const [mark] = groups[i];
1584
1627
  for (let j = tokens.length - 1; j >= 0; j--) {
@@ -1588,8 +1631,8 @@ var Trie = (_a5 = class {
1588
1631
  }
1589
1632
  }
1590
1633
  }
1591
- __privateGet(this, _root).insert(tokens, index, paramAssoc, __privateGet(this, _context), pathErrorCheckOnly);
1592
- return paramAssoc;
1634
+ __privateGet(this, _root).insert(tokens, __privateGet(this, _index2), paramAssoc, __privateGet(this, _context), false);
1635
+ this.paths[path] = [__privateWrapper(this, _index2)._++, paramAssoc];
1593
1636
  }
1594
1637
  buildRegExp() {
1595
1638
  let regexp = __privateGet(this, _root).buildRegExpStr();
@@ -1612,10 +1655,9 @@ var Trie = (_a5 = class {
1612
1655
  });
1613
1656
  return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
1614
1657
  }
1615
- }, _context = new WeakMap(), _root = new WeakMap(), _a5);
1658
+ }, _context = new WeakMap(), _root = new WeakMap(), _index2 = new WeakMap(), _a5);
1616
1659
 
1617
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router/reg-exp-router/router.js
1618
- var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
1660
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/router.js
1619
1661
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
1620
1662
  function buildWildcardRegExp(path) {
1621
1663
  return wildcardRegExpCache[path] ?? (wildcardRegExpCache[path] = new RegExp(
@@ -1628,63 +1670,6 @@ function buildWildcardRegExp(path) {
1628
1670
  function clearWildcardRegExpCache() {
1629
1671
  wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
1630
1672
  }
1631
- function buildMatcherFromPreprocessedRoutes(routes) {
1632
- const trie = new Trie();
1633
- const handlerData = [];
1634
- if (routes.length === 0) {
1635
- return nullMatcher;
1636
- }
1637
- const routesWithStaticPathFlag = routes.map(
1638
- (route) => [!/\*|\/:/.test(route[0]), ...route]
1639
- ).sort(
1640
- ([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
1641
- );
1642
- const staticMap = /* @__PURE__ */ Object.create(null);
1643
- for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
1644
- const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
1645
- if (pathErrorCheckOnly) {
1646
- staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
1647
- } else {
1648
- j++;
1649
- }
1650
- let paramAssoc;
1651
- try {
1652
- paramAssoc = trie.insert(path, j, pathErrorCheckOnly);
1653
- } catch (e) {
1654
- throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
1655
- }
1656
- if (pathErrorCheckOnly) {
1657
- continue;
1658
- }
1659
- handlerData[j] = handlers.map(([h, paramCount]) => {
1660
- const paramIndexMap = /* @__PURE__ */ Object.create(null);
1661
- paramCount -= 1;
1662
- for (; paramCount >= 0; paramCount--) {
1663
- const [key, value] = paramAssoc[paramCount];
1664
- paramIndexMap[key] = value;
1665
- }
1666
- return [h, paramIndexMap];
1667
- });
1668
- }
1669
- const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
1670
- for (let i = 0, len = handlerData.length; i < len; i++) {
1671
- for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
1672
- const map = handlerData[i][j]?.[1];
1673
- if (!map) {
1674
- continue;
1675
- }
1676
- const keys = Object.keys(map);
1677
- for (let k = 0, len3 = keys.length; k < len3; k++) {
1678
- map[keys[k]] = paramReplacementMap[map[keys[k]]];
1679
- }
1680
- }
1681
- }
1682
- const handlerMap = [];
1683
- for (const i in indexReplacementMap) {
1684
- handlerMap[i] = handlerData[indexReplacementMap[i]];
1685
- }
1686
- return [regexp, handlerMap, staticMap];
1687
- }
1688
1673
  function findMiddleware(middleware, path) {
1689
1674
  if (!middleware) {
1690
1675
  return void 0;
@@ -1696,29 +1681,32 @@ function findMiddleware(middleware, path) {
1696
1681
  }
1697
1682
  return void 0;
1698
1683
  }
1699
- var _middleware, _routes, _RegExpRouter_instances, buildMatcher_fn, _a6;
1684
+ var _middleware, _routes, _tries, _RegExpRouter_instances, insertPath_fn, buildMatcher_fn, _a6;
1700
1685
  var RegExpRouter = (_a6 = class {
1701
1686
  constructor() {
1702
1687
  __privateAdd(this, _RegExpRouter_instances);
1703
1688
  __publicField(this, "name", "RegExpRouter");
1704
1689
  __privateAdd(this, _middleware);
1705
1690
  __privateAdd(this, _routes);
1691
+ __privateAdd(this, _tries);
1706
1692
  __publicField(this, "match", match);
1707
1693
  __privateSet(this, _middleware, { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) });
1708
1694
  __privateSet(this, _routes, { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) });
1695
+ __privateSet(this, _tries, { [METHOD_NAME_ALL]: new Trie() });
1709
1696
  }
1710
1697
  add(method, path, handler) {
1711
- var _a10;
1712
1698
  const middleware = __privateGet(this, _middleware);
1713
1699
  const routes = __privateGet(this, _routes);
1714
1700
  if (!middleware || !routes) {
1715
1701
  throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
1716
1702
  }
1717
1703
  if (!middleware[method]) {
1704
+ __privateGet(this, _tries)[method] = new Trie();
1718
1705
  [middleware, routes].forEach((handlerMap) => {
1719
1706
  handlerMap[method] = /* @__PURE__ */ Object.create(null);
1720
1707
  Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
1721
1708
  handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
1709
+ __privateMethod(this, _RegExpRouter_instances, insertPath_fn).call(this, method, p);
1722
1710
  });
1723
1711
  });
1724
1712
  }
@@ -1728,14 +1716,12 @@ var RegExpRouter = (_a6 = class {
1728
1716
  const paramCount = (path.match(/\/:/g) || []).length;
1729
1717
  if (/\*$/.test(path)) {
1730
1718
  const re = buildWildcardRegExp(path);
1731
- if (method === METHOD_NAME_ALL) {
1732
- Object.keys(middleware).forEach((m) => {
1733
- var _a11;
1734
- (_a11 = middleware[m])[path] || (_a11[path] = findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || []);
1735
- });
1736
- } else {
1737
- (_a10 = middleware[method])[path] || (_a10[path] = findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || []);
1738
- }
1719
+ Object.keys(middleware).forEach((m) => {
1720
+ if ((method === METHOD_NAME_ALL || method === m) && !middleware[m][path]) {
1721
+ __privateMethod(this, _RegExpRouter_instances, insertPath_fn).call(this, m, path);
1722
+ middleware[m][path] = findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
1723
+ }
1724
+ });
1739
1725
  Object.keys(middleware).forEach((m) => {
1740
1726
  if (method === METHOD_NAME_ALL || method === m) {
1741
1727
  Object.keys(middleware[m]).forEach((p) => {
@@ -1756,11 +1742,13 @@ var RegExpRouter = (_a6 = class {
1756
1742
  for (let i = 0, len = paths.length; i < len; i++) {
1757
1743
  const path2 = paths[i];
1758
1744
  Object.keys(routes).forEach((m) => {
1759
- var _a11;
1760
1745
  if (method === METHOD_NAME_ALL || method === m) {
1761
- (_a11 = routes[m])[path2] || (_a11[path2] = [
1762
- ...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
1763
- ]);
1746
+ if (!routes[m][path2]) {
1747
+ __privateMethod(this, _RegExpRouter_instances, insertPath_fn).call(this, m, path2);
1748
+ routes[m][path2] = [
1749
+ ...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
1750
+ ];
1751
+ }
1764
1752
  routes[m][path2].push([handler, paramCount - len + i + 1]);
1765
1753
  }
1766
1754
  });
@@ -1771,32 +1759,63 @@ var RegExpRouter = (_a6 = class {
1771
1759
  Object.keys(__privateGet(this, _routes)).concat(Object.keys(__privateGet(this, _middleware))).forEach((method) => {
1772
1760
  matchers[method] || (matchers[method] = __privateMethod(this, _RegExpRouter_instances, buildMatcher_fn).call(this, method));
1773
1761
  });
1774
- __privateSet(this, _middleware, __privateSet(this, _routes, void 0));
1762
+ __privateSet(this, _middleware, __privateSet(this, _routes, __privateSet(this, _tries, void 0)));
1775
1763
  clearWildcardRegExpCache();
1776
1764
  return matchers;
1777
1765
  }
1778
- }, _middleware = new WeakMap(), _routes = new WeakMap(), _RegExpRouter_instances = new WeakSet(), buildMatcher_fn = function(method) {
1779
- const routes = [];
1780
- let hasOwnRoute = method === METHOD_NAME_ALL;
1781
- [__privateGet(this, _middleware), __privateGet(this, _routes)].forEach((r) => {
1782
- const ownRoute = r[method] ? Object.keys(r[method]).map((path) => [path, r[method][path]]) : [];
1783
- if (ownRoute.length !== 0) {
1784
- hasOwnRoute || (hasOwnRoute = true);
1785
- routes.push(...ownRoute);
1786
- } else if (method !== METHOD_NAME_ALL) {
1787
- routes.push(
1788
- ...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]])
1789
- );
1766
+ }, _middleware = new WeakMap(), _routes = new WeakMap(), _tries = new WeakMap(), _RegExpRouter_instances = new WeakSet(), insertPath_fn = function(method, path) {
1767
+ try {
1768
+ __privateGet(this, _tries)[method].insert(path, !/\*|\/:/.test(path));
1769
+ } catch (e) {
1770
+ throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
1771
+ }
1772
+ }, buildMatcher_fn = function(method) {
1773
+ const middleware = __privateGet(this, _middleware)[method];
1774
+ const routes = __privateGet(this, _routes)[method];
1775
+ const trie = __privateGet(this, _tries)[method];
1776
+ const staticMap = /* @__PURE__ */ Object.create(null);
1777
+ const handlerData = [];
1778
+ [middleware, routes].forEach((r) => {
1779
+ for (const path in r) {
1780
+ const handlers = r[path];
1781
+ const pathData = trie.paths[path];
1782
+ if (!pathData) {
1783
+ staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
1784
+ continue;
1785
+ }
1786
+ const paramAssoc = pathData[1];
1787
+ handlerData[pathData[0]] = handlers.map(([h, paramCount]) => {
1788
+ const paramIndexMap = /* @__PURE__ */ Object.create(null);
1789
+ paramCount -= 1;
1790
+ for (; paramCount >= 0; paramCount--) {
1791
+ const [key, value] = paramAssoc[paramCount];
1792
+ paramIndexMap[key] = value;
1793
+ }
1794
+ return [h, paramIndexMap];
1795
+ });
1790
1796
  }
1791
1797
  });
1792
- if (!hasOwnRoute) {
1793
- return null;
1794
- } else {
1795
- return buildMatcherFromPreprocessedRoutes(routes);
1798
+ const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
1799
+ for (let i = 0, len = handlerData.length; i < len; i++) {
1800
+ for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
1801
+ const map = handlerData[i][j]?.[1];
1802
+ if (!map) {
1803
+ continue;
1804
+ }
1805
+ const keys = Object.keys(map);
1806
+ for (let k = 0, len3 = keys.length; k < len3; k++) {
1807
+ map[keys[k]] = paramReplacementMap[map[keys[k]]];
1808
+ }
1809
+ }
1796
1810
  }
1811
+ const handlerMap = [];
1812
+ for (const i in indexReplacementMap) {
1813
+ handlerMap[i] = handlerData[indexReplacementMap[i]];
1814
+ }
1815
+ return [regexp, handlerMap, staticMap];
1797
1816
  }, _a6);
1798
1817
 
1799
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router/smart-router/router.js
1818
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/smart-router/router.js
1800
1819
  var _routers, _routes2, _a7;
1801
1820
  var SmartRouter = (_a7 = class {
1802
1821
  constructor(init) {
@@ -1852,7 +1871,7 @@ var SmartRouter = (_a7 = class {
1852
1871
  }
1853
1872
  }, _routers = new WeakMap(), _routes2 = new WeakMap(), _a7);
1854
1873
 
1855
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router/trie-router/node.js
1874
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/trie-router/node.js
1856
1875
  var emptyParams = /* @__PURE__ */ Object.create(null);
1857
1876
  var hasChildren = (children) => {
1858
1877
  for (const _ in children) {
@@ -1969,9 +1988,12 @@ var Node2 = (_a8 = class {
1969
1988
  if (m) {
1970
1989
  params[name] = m[0];
1971
1990
  __privateMethod(this, __Node_instances, pushHandlerSets_fn).call(this, handlerSets, child, method, __privateGet(node, _params), params);
1991
+ if (m[0].length === restPathString.length && __privateGet(child, _children2)["*"]) {
1992
+ __privateMethod(this, __Node_instances, pushHandlerSets_fn).call(this, handlerSets, __privateGet(child, _children2)["*"], method, __privateGet(node, _params), params);
1993
+ }
1972
1994
  if (hasChildren(__privateGet(child, _children2))) {
1973
1995
  __privateSet(child, _params, params);
1974
- const componentCount = m[0].match(/\//)?.length ?? 0;
1996
+ const componentCount = m[0].match(/\//g)?.length ?? 0;
1975
1997
  const targetCurNodes = curNodesQueue[componentCount] || (curNodesQueue[componentCount] = []);
1976
1998
  targetCurNodes.push(child);
1977
1999
  }
@@ -2022,7 +2044,7 @@ var Node2 = (_a8 = class {
2022
2044
  }
2023
2045
  }, _a8);
2024
2046
 
2025
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/router/trie-router/router.js
2047
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/trie-router/router.js
2026
2048
  var _node, _a9;
2027
2049
  var TrieRouter = (_a9 = class {
2028
2050
  constructor() {
@@ -2045,7 +2067,7 @@ var TrieRouter = (_a9 = class {
2045
2067
  }
2046
2068
  }, _node = new WeakMap(), _a9);
2047
2069
 
2048
- // ../node_modules/.bun/hono@4.12.25/node_modules/hono/dist/hono.js
2070
+ // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/hono.js
2049
2071
  var Hono2 = class extends Hono {
2050
2072
  /**
2051
2073
  * Creates an instance of the Hono class.
@@ -2090,7 +2112,7 @@ function authMiddleware(deps) {
2090
2112
  await next();
2091
2113
  };
2092
2114
  }
2093
- var IDEMPOTENT_PATH_RE = /\/(cart\/items|cart\/coupons|checkout|payments\/authorization|auth\/(request-otp|verify-otp|profile|logout))(\/|$)/;
2115
+ var IDEMPOTENT_PATH_RE = /\/(cart\/items|cart\/coupons|checkout|purchase-intents|payments\/authorization|auth\/(request-otp|verify-otp|profile|logout))(\/|$)/;
2094
2116
  var IDEMPOTENCY_TTL_MS = 24 * 60 * 60 * 1e3;
2095
2117
  function idempotencyMiddleware(deps) {
2096
2118
  return async (c, next) => {
@@ -2100,7 +2122,8 @@ function idempotencyMiddleware(deps) {
2100
2122
  const key = c.req.header("idempotency-key") ?? c.req.header("Idempotency-Key");
2101
2123
  if (!key || key.length > 200) return next();
2102
2124
  const session = c.var.session;
2103
- const recordId = `${session.id}:${key}`;
2125
+ const routeScope = c.req.path.includes("/purchase-intents") ? `:${c.req.path}` : "";
2126
+ const recordId = `${session.id}${routeScope}:${key}`;
2104
2127
  const existing = deps.registry.idempotency.get(recordId);
2105
2128
  if (existing) {
2106
2129
  const expiresAt = Date.parse(existing.expires_at);
@@ -2174,6 +2197,21 @@ function getQueryNum(c, key) {
2174
2197
  }
2175
2198
 
2176
2199
  // src/mock/routes/v1.ts
2200
+ var PURCHASE_INTENT_ROUTE = {
2201
+ COLLECTION: "/purchase-intents",
2202
+ MEMBER: "/purchase-intents/:intent_id",
2203
+ REFRESH: "/purchase-intents/:intent_id/refresh",
2204
+ CONFIRM: "/purchase-intents/:intent_id/confirm",
2205
+ ACTION: "/purchase-intents/:intent_id/attempts/:attempt_id/actions"
2206
+ };
2207
+ var PURCHASE_INTENT_ROUTE_PARAM = {
2208
+ INTENT_ID: "intent_id",
2209
+ ATTEMPT_ID: "attempt_id"
2210
+ };
2211
+ var PAYMENT_ROUTE = {
2212
+ COLLECTION_OPTIONS: "/payments/collection-options",
2213
+ AUTHORIZATION: "/payments/authorization"
2214
+ };
2177
2215
  function buildV1(deps) {
2178
2216
  const app = new Hono2();
2179
2217
  app.use("*", chaosMiddleware(deps));
@@ -2546,28 +2584,81 @@ function buildV1(deps) {
2546
2584
  "/subscriptions/:subscription_id/skip",
2547
2585
  (c) => tryRoute(c, () => deps.subscriptions.skipNext(c.req.param("subscription_id")))
2548
2586
  );
2549
- app.get("/payments/collection-options", (c) => {
2587
+ app.get(PAYMENT_ROUTE.COLLECTION_OPTIONS, async (c) => {
2550
2588
  const currency = c.req.query("currency")?.trim().toUpperCase();
2551
2589
  if (!currency || !/^[A-Z]{3}$/.test(currency)) {
2552
2590
  return fail(c, validation("currency must be a canonical three-letter code"));
2553
2591
  }
2554
2592
  return tryRoute(c, () => ({
2555
2593
  presentment_currency: currency,
2556
- options: currency === "GHS" ? [
2594
+ options: currency === DEFAULT_CURRENCY ? [
2557
2595
  { method: PAYMENT_METHOD.CARD, network: null },
2558
- { method: PAYMENT_METHOD.MOBILE_MONEY, network: "mtn" },
2559
- { method: PAYMENT_METHOD.MOBILE_MONEY, network: "telecel" },
2560
- { method: PAYMENT_METHOD.MOBILE_MONEY, network: "airteltigo" }
2596
+ {
2597
+ method: PAYMENT_METHOD.MOBILE_MONEY,
2598
+ network: PURCHASE_INTENT_MOBILE_MONEY_NETWORK.MTN
2599
+ },
2600
+ {
2601
+ method: PAYMENT_METHOD.MOBILE_MONEY,
2602
+ network: PURCHASE_INTENT_MOBILE_MONEY_NETWORK.TELECEL
2603
+ },
2604
+ {
2605
+ method: PAYMENT_METHOD.MOBILE_MONEY,
2606
+ network: PURCHASE_INTENT_MOBILE_MONEY_NETWORK.AIRTEL
2607
+ }
2561
2608
  ] : currency === "USD" ? [{ method: PAYMENT_METHOD.CARD, network: null }] : []
2562
2609
  }));
2563
2610
  });
2564
- app.post("/checkout", async (c) => {
2611
+ app.post(PURCHASE_INTENT_ROUTE.COLLECTION, async (c) => {
2612
+ const body = await c.req.json().catch(() => ({}));
2613
+ return tryRoute(c, () => deps.purchaseIntents.mint(c.var.session, body));
2614
+ });
2615
+ app.get(
2616
+ PURCHASE_INTENT_ROUTE.MEMBER,
2617
+ (c) => tryRoute(
2618
+ c,
2619
+ () => deps.purchaseIntents.get(
2620
+ c.var.session,
2621
+ c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID)
2622
+ )
2623
+ )
2624
+ );
2625
+ app.post(PURCHASE_INTENT_ROUTE.REFRESH, async (c) => {
2626
+ const body = await c.req.json().catch(() => ({}));
2627
+ return tryRoute(
2628
+ c,
2629
+ () => deps.purchaseIntents.refresh(
2630
+ c.var.session,
2631
+ c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID),
2632
+ body.expected_intent_revision
2633
+ )
2634
+ );
2635
+ });
2636
+ app.post(PURCHASE_INTENT_ROUTE.CONFIRM, async (c) => {
2637
+ const body = await c.req.json().catch(() => ({}));
2638
+ return tryRoute(
2639
+ c,
2640
+ () => deps.purchaseIntents.confirm(
2641
+ c.var.session,
2642
+ c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID),
2643
+ body
2644
+ )
2645
+ );
2646
+ });
2647
+ app.post(PURCHASE_INTENT_ROUTE.ACTION, async (c) => {
2565
2648
  const body = await c.req.json().catch(() => ({}));
2566
- return tryRoute(c, () => deps.checkout.process(c.var.session, body));
2649
+ return tryRoute(
2650
+ c,
2651
+ () => deps.purchaseIntents.submitAction(
2652
+ c.var.session,
2653
+ c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID),
2654
+ c.req.param(PURCHASE_INTENT_ROUTE_PARAM.ATTEMPT_ID),
2655
+ body
2656
+ )
2657
+ );
2567
2658
  });
2568
- app.post("/payments/authorization", async (c) => {
2659
+ app.post(PAYMENT_ROUTE.AUTHORIZATION, async (c) => {
2569
2660
  const body = await c.req.json().catch(() => ({}));
2570
- return tryRoute(c, () => deps.checkout.authorize(body));
2661
+ return tryRoute(c, () => deps.payments.authorize(body));
2571
2662
  });
2572
2663
  app.get("/auth/status", (c) => tryRoute(c, () => deps.auth.status(c.var.session.token)));
2573
2664
  app.post("/auth/request-otp", async (c) => {
@@ -2873,6 +2964,7 @@ function createStateRegistry() {
2873
2964
  collections: createMemoryStore(),
2874
2965
  carts: createMemoryStore(),
2875
2966
  orders: createMemoryStore(),
2967
+ purchaseIntents: createMemoryStore(),
2876
2968
  subscriptions: createMemoryStore(),
2877
2969
  bookings: createMemoryStore(),
2878
2970
  services: createMemoryStore(),
@@ -3022,9 +3114,9 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3022
3114
  // injected into the HTML page served by the mock. Edit this file directly \u2014
3023
3115
  // type-check via tsgo + the IframeToParentMessage shape from the SDK.
3024
3116
  (function () {
3025
- var TYPE = window.__CIMPLIFY_MOCK_ELEMENT__;
3026
- var DEFAULT_BUSINESS = window.__CIMPLIFY_MOCK_BUSINESS__;
3027
- var MSG = {
3117
+ const TYPE = window.__CIMPLIFY_MOCK_ELEMENT__;
3118
+ const DEFAULT_BUSINESS = window.__CIMPLIFY_MOCK_BUSINESS__;
3119
+ const MSG = {
3028
3120
  INIT: "init", SET_TOKEN: "set_token", SET_CART: "set_cart", GET_DATA: "get_data",
3029
3121
  REFRESH_TOKEN: "refresh_token", LOGOUT: "logout",
3030
3122
  PROCESS_CHECKOUT: "process_checkout", ABORT_CHECKOUT: "abort_checkout",
@@ -3037,12 +3129,36 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3037
3129
  CHECKOUT_STATUS: "checkout_status", CHECKOUT_COMPLETE: "checkout_complete",
3038
3130
  ORDER_TYPE_CHANGED: "order_type_changed", REQUEST_SUBMIT: "request_submit"
3039
3131
  };
3040
- var qs = new URLSearchParams(location.search);
3041
- var AUTO = qs.get("auto") === "true";
3042
- var DEMO_OTP = qs.get("otp") || "123456";
3043
- var ORIGIN = qs.get("origin") || "*";
3044
- var NONCE = qs.get("nonce");
3045
- var state = {
3132
+ const PURCHASE_INTENT = {
3133
+ PATH: "/api/v1/purchase-intents",
3134
+ ORDER_CREATED: "order_created",
3135
+ CARD_POPUP_REQUIRED: "card_popup_required",
3136
+ AUTHORIZATION_REQUIRED: "authorization_required",
3137
+ ELIGIBLE: "eligible"
3138
+ };
3139
+ const CHECKOUT_STATUS = {
3140
+ PROCESSING: "processing",
3141
+ SUCCESS: "success",
3142
+ FAILED: "failed"
3143
+ };
3144
+ const CHECKOUT_ERROR = { FAILED: "CHECKOUT_FAILED" };
3145
+ const ORDER_STATUS = { CONFIRMED: "confirmed" };
3146
+ const TENDER = {
3147
+ CARD: "card",
3148
+ MOBILE_MONEY: "mobile_money",
3149
+ AUTHORITY_TRANSIENT: "transient",
3150
+ MTN: "mtn"
3151
+ };
3152
+ const PAYMENT_PROVIDER = { PAYSTACK: "paystack" };
3153
+ const SOURCE_KIND = { CART: "cart" };
3154
+ const AUTHORIZATION = { OTP: "otp" };
3155
+ const EXACT_ZERO_MONEY = /^[+-]?0+(?:\\.0+)?(?:[eE][+-]?\\d+)?$/;
3156
+ const qs = new URLSearchParams(location.search);
3157
+ const AUTO = qs.get("auto") === "true";
3158
+ const DEMO_OTP = qs.get("otp") || "123456";
3159
+ const ORIGIN = qs.get("origin") || "*";
3160
+ const NONCE = qs.get("nonce");
3161
+ const state = {
3046
3162
  businessId: DEFAULT_BUSINESS,
3047
3163
  token: null,
3048
3164
  cart: null,
@@ -3053,15 +3169,33 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3053
3169
  contact: null,
3054
3170
  pendingOtp: null
3055
3171
  };
3056
- var content = document.getElementById("content");
3057
- var title = document.getElementById("title");
3172
+ const content = document.getElementById("content");
3173
+ const title = document.getElementById("title");
3058
3174
 
3059
3175
  function send(msg) {
3060
3176
  if (NONCE) msg.nonce = NONCE;
3061
3177
  parent.postMessage(msg, ORIGIN);
3062
3178
  }
3179
+ function isExactlyZeroMoney(value) {
3180
+ return typeof value === "number"
3181
+ ? Object.is(value, 0) || Object.is(value, -0)
3182
+ : EXACT_ZERO_MONEY.test(String(value).trim());
3183
+ }
3063
3184
  function reportHeight() { send({ type: MSG.HEIGHT_CHANGE, height: document.documentElement.scrollHeight }); }
3064
3185
  function ready() { send({ type: MSG.READY, height: document.documentElement.scrollHeight }); }
3186
+ function responseWithBody(response) {
3187
+ return response.json().then(function (body) {
3188
+ return { status: response.status, body: body };
3189
+ });
3190
+ }
3191
+ function assertSuccessfulResponse(response, fallbackMessage) {
3192
+ if (response.status >= 400) {
3193
+ throw new Error(
3194
+ (response.body && response.body.error && response.body.error.message) || fallbackMessage
3195
+ );
3196
+ }
3197
+ return response.body;
3198
+ }
3065
3199
 
3066
3200
  function defaultAddress() {
3067
3201
  return {
@@ -3071,9 +3205,20 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3071
3205
  };
3072
3206
  }
3073
3207
  function defaultPayment(type) {
3074
- if (type === "card") return { type: "card", provider: "paystack", last_four: "4242", label: "Visa \u2022\u2022\u2022\u2022 4242" };
3075
- if (type === "cash") return { type: "cash", label: "Cash on delivery" };
3076
- return { type: "mobile_money", provider: "mtn", phone_number: "+233244000000", label: "MTN Mobile Money" };
3208
+ if (type === TENDER.CARD) {
3209
+ return {
3210
+ type: TENDER.CARD,
3211
+ provider: PAYMENT_PROVIDER.PAYSTACK,
3212
+ last_four: "4242",
3213
+ label: "Visa \u2022\u2022\u2022\u2022 4242"
3214
+ };
3215
+ }
3216
+ return {
3217
+ type: TENDER.MOBILE_MONEY,
3218
+ provider: TENDER.MTN,
3219
+ phone_number: "+233244000000",
3220
+ label: "MTN Mobile Money"
3221
+ };
3077
3222
  }
3078
3223
 
3079
3224
  function renderAuth() {
@@ -3098,12 +3243,12 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3098
3243
  ' <div class="option" data-key="lagos">5 Allen Ave, Ikeja, Lagos</div>' +
3099
3244
  '</div>' +
3100
3245
  '<button id="confirm">Use this address</button>';
3101
- var options = {
3246
+ const options = {
3102
3247
  "default": defaultAddress(),
3103
3248
  "east-legon": { street_address: "8 Ring Road", city: "Accra", region: "Greater Accra", country: "GH", latitude: 5.65, longitude: -0.16 },
3104
3249
  "lagos": { street_address: "5 Allen Avenue", city: "Lagos", region: "Lagos", country: "NG", latitude: 6.5244, longitude: 3.3792 }
3105
3250
  };
3106
- var picked = "default";
3251
+ let picked = "default";
3107
3252
  Array.prototype.forEach.call(document.querySelectorAll(".option"), function (el) {
3108
3253
  el.onclick = function () {
3109
3254
  picked = el.getAttribute("data-key");
@@ -3126,10 +3271,9 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3126
3271
  '<div class="options" id="pay-options">' +
3127
3272
  ' <div class="option selected" data-method="mobile_money">\u{1F4F1} MTN Mobile Money</div>' +
3128
3273
  ' <div class="option" data-method="card">\u{1F4B3} Card (Paystack)</div>' +
3129
- ' <div class="option" data-method="cash">\u{1F4B5} Cash on delivery</div>' +
3130
3274
  '</div>' +
3131
3275
  '<button id="confirm">Use this method</button>';
3132
- var picked = "mobile_money";
3276
+ let picked = TENDER.MOBILE_MONEY;
3133
3277
  Array.prototype.forEach.call(document.querySelectorAll(".option"), function (el) {
3134
3278
  el.onclick = function () {
3135
3279
  picked = el.getAttribute("data-method");
@@ -3173,7 +3317,6 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3173
3317
  '</div>' +
3174
3318
  '<label>Payment method</label>' +
3175
3319
  '<select id="pay-method">' +
3176
- ' <option value="cash">Cash</option>' +
3177
3320
  ' <option value="mobile_money">Mobile Money (MTN)</option>' +
3178
3321
  ' <option value="card">Card (Paystack)</option>' +
3179
3322
  '</select>' +
@@ -3190,65 +3333,139 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3190
3333
  }
3191
3334
 
3192
3335
  function runCheckout() {
3193
- var statusEl = document.getElementById("status");
3194
- var errEl = document.getElementById("err");
3195
- var resultEl = document.getElementById("result");
3336
+ const statusEl = document.getElementById("status");
3337
+ const errEl = document.getElementById("err");
3338
+ const resultEl = document.getElementById("result");
3196
3339
  if (errEl) errEl.textContent = "";
3197
3340
  if (!state.cart) { errEl.textContent = "No cart provided"; return; }
3198
- var customer = {
3341
+ const customer = {
3199
3342
  name: document.getElementById("cust-name").value.trim() || "Customer",
3200
3343
  email: document.getElementById("cust-email").value.trim() || "noemail@example.com",
3201
3344
  phone: document.getElementById("cust-phone").value.trim() || "+233000000000",
3202
3345
  save_details: false
3203
3346
  };
3204
- var paymentMethod = document.getElementById("pay-method").value;
3205
- var orderType = document.getElementById("order-type").value;
3347
+ const paymentMethod = document.getElementById("pay-method").value;
3348
+ const orderType = document.getElementById("order-type").value;
3206
3349
  statusEl.textContent = "Processing\u2026";
3207
- send({ type: MSG.CHECKOUT_STATUS, status: "processing", context: {} });
3350
+ send({ type: MSG.CHECKOUT_STATUS, status: CHECKOUT_STATUS.PROCESSING, context: {} });
3208
3351
 
3209
- var headers = { "content-type": "application/json" };
3352
+ const headers = { "content-type": "application/json" };
3210
3353
  if (state.token) headers["x-session-token"] = state.token;
3211
3354
 
3212
- fetch("/api/v1/checkout", {
3355
+ const preference = paymentMethod === TENDER.MOBILE_MONEY
3356
+ ? {
3357
+ method_kind: TENDER.MOBILE_MONEY,
3358
+ authority: {
3359
+ authority_kind: TENDER.AUTHORITY_TRANSIENT,
3360
+ phone_number: customer.phone,
3361
+ network: TENDER.MTN
3362
+ }
3363
+ }
3364
+ : { method_kind: TENDER.CARD };
3365
+ const intentKey = "mock-element:" + state.cart.id;
3366
+ fetch(PURCHASE_INTENT.PATH, {
3213
3367
  method: "POST",
3214
3368
  headers: headers,
3215
3369
  body: JSON.stringify({
3216
- cart_id: state.cart.id,
3217
- customer: customer,
3218
- order_type: orderType,
3219
- payment_method: paymentMethod,
3220
- address_info: state.address || undefined
3370
+ client_intent_key: intentKey,
3371
+ source: { kind: SOURCE_KIND.CART, cart_id: state.cart.id },
3372
+ checkout: {
3373
+ customer: customer,
3374
+ order_type: orderType,
3375
+ address_info: state.address || {},
3376
+ tender_preference: preference
3377
+ }
3221
3378
  })
3222
3379
  })
3223
- .then(function (r) { return r.json().then(function (b) { return { status: r.status, body: b }; }); })
3380
+ .then(responseWithBody)
3224
3381
  .then(function (resp) {
3225
- if (resp.status >= 400) {
3226
- var msg = (resp.body && resp.body.error && resp.body.error.message) || "Checkout failed";
3227
- send({ type: MSG.CHECKOUT_COMPLETE, success: false, error: { code: (resp.body.error && resp.body.error.code) || "CHECKOUT_FAILED", message: msg, recoverable: true } });
3228
- statusEl.textContent = "Failed";
3229
- errEl.textContent = msg;
3230
- return;
3382
+ const intent = assertSuccessfulResponse(resp, "Intent creation failed");
3383
+ const terms = intent.current_terms;
3384
+ const option = terms && terms.payment_options && terms.payment_options.filter(function (candidate) {
3385
+ return candidate.status === PURCHASE_INTENT.ELIGIBLE && candidate.method_kind === preference.method_kind;
3386
+ })[0];
3387
+ if (!terms || (!option && !isExactlyZeroMoney(terms.money.rail_amount))) {
3388
+ throw new Error("No eligible payment option");
3389
+ }
3390
+ const confirmationPath = PURCHASE_INTENT.PATH + "/" + encodeURIComponent(intent.id) + "/confirm";
3391
+ const confirmationBody = JSON.stringify({
3392
+ accepted_intent_revision: terms.intent_revision,
3393
+ accepted_terms_version: terms.terms_version,
3394
+ accepted_due_now: terms.money.due_now,
3395
+ accepted_customer_debit_amount: option
3396
+ ? option.customer_debit_amount
3397
+ : terms.money.rail_amount,
3398
+ currency: terms.money.currency,
3399
+ payment_option_id: option ? option.id : null,
3400
+ idempotency_key: "mock-confirm:" + intent.id
3401
+ });
3402
+ function confirmIntent() {
3403
+ return fetch(confirmationPath, {
3404
+ method: "POST",
3405
+ headers: headers,
3406
+ body: confirmationBody
3407
+ })
3408
+ .then(responseWithBody)
3409
+ .then(function (response) {
3410
+ return assertSuccessfulResponse(response, "Intent confirmation failed");
3411
+ });
3412
+ }
3413
+
3414
+ return confirmIntent().then(function (outcome) {
3415
+ // This mock has no external provider window. Replaying the exact
3416
+ // idempotent confirmation models the provider-approved callback.
3417
+ return outcome.status === PURCHASE_INTENT.CARD_POPUP_REQUIRED
3418
+ ? confirmIntent()
3419
+ : outcome;
3420
+ });
3421
+ })
3422
+ .then(function (outcome) {
3423
+ if (outcome.status !== PURCHASE_INTENT.AUTHORIZATION_REQUIRED) return outcome;
3424
+ return fetch(
3425
+ PURCHASE_INTENT.PATH + "/" + encodeURIComponent(outcome.intent_id) +
3426
+ "/attempts/" + encodeURIComponent(outcome.attempt_id) + "/actions",
3427
+ {
3428
+ method: "POST",
3429
+ headers: headers,
3430
+ body: JSON.stringify({ authorization: { type: AUTHORIZATION.OTP, value: DEMO_OTP } })
3431
+ }
3432
+ )
3433
+ .then(responseWithBody)
3434
+ .then(function (response) {
3435
+ return assertSuccessfulResponse(response, "Authorization failed");
3436
+ });
3437
+ })
3438
+ .then(function (outcome) {
3439
+ if (outcome.status !== PURCHASE_INTENT.ORDER_CREATED) {
3440
+ throw new Error("Checkout requires " + outcome.status.replace(/_/g, " "));
3231
3441
  }
3232
- var b = resp.body;
3233
- send({ type: MSG.CHECKOUT_STATUS, status: "success", context: { order_id: b.order_id, order_number: b.order_number, provider: b.provider } });
3442
+ send({
3443
+ type: MSG.CHECKOUT_STATUS,
3444
+ status: CHECKOUT_STATUS.SUCCESS,
3445
+ context: { order_id: outcome.order_id }
3446
+ });
3234
3447
  send({
3235
3448
  type: MSG.CHECKOUT_COMPLETE,
3236
3449
  success: true,
3237
3450
  order: {
3238
- id: b.order_id,
3239
- order_number: b.order_number,
3240
- status: b.requires_authorization ? "pending" : "confirmed",
3451
+ id: outcome.order_id,
3452
+ order_number: outcome.order_number || outcome.order_id,
3453
+ status: ORDER_STATUS.CONFIRMED,
3241
3454
  total: (state.cart && state.cart.total_price) || "0.00",
3242
3455
  currency: (state.cart && state.cart.currency) || "GHS"
3243
3456
  }
3244
3457
  });
3245
- statusEl.textContent = "Success \u2014 order " + b.order_number;
3458
+ statusEl.textContent = "Success \u2014 order " + outcome.order_id;
3246
3459
  resultEl.style.display = "block";
3247
- resultEl.textContent = JSON.stringify(b, null, 2);
3460
+ resultEl.textContent = JSON.stringify(outcome, null, 2);
3248
3461
  })
3249
3462
  .catch(function (e) {
3250
- send({ type: MSG.CHECKOUT_COMPLETE, success: false, error: { code: "NETWORK", message: String(e), recoverable: true } });
3251
- statusEl.textContent = "Network error";
3463
+ send({
3464
+ type: MSG.CHECKOUT_COMPLETE,
3465
+ success: false,
3466
+ error: { code: CHECKOUT_ERROR.FAILED, message: String(e), recoverable: true }
3467
+ });
3468
+ statusEl.textContent = "Failed";
3252
3469
  errEl.textContent = String(e);
3253
3470
  });
3254
3471
  }
@@ -3265,7 +3482,7 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3265
3482
  break;
3266
3483
  case MSG.SET_CART:
3267
3484
  state.cart = msg.cart;
3268
- var s = document.getElementById("status");
3485
+ const s = document.getElementById("status");
3269
3486
  if (s) s.textContent = "Cart loaded \u2014 " + (msg.cart && msg.cart.items ? msg.cart.items.length : 0) + " item(s), " + ((msg.cart && msg.cart.currency) || "GHS") + " " + ((msg.cart && msg.cart.total_price) || "0.00");
3270
3487
  reportHeight();
3271
3488
  break;
@@ -3289,7 +3506,7 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
3289
3506
  }
3290
3507
  break;
3291
3508
  case MSG.ABORT_CHECKOUT:
3292
- send({ type: MSG.CHECKOUT_STATUS, status: "failed", context: {} });
3509
+ send({ type: MSG.CHECKOUT_STATUS, status: CHECKOUT_STATUS.FAILED, context: {} });
3293
3510
  break;
3294
3511
  }
3295
3512
  }
@@ -3903,6 +4120,7 @@ function createAuthService(opts) {
3903
4120
  token: id,
3904
4121
  business_id: options.defaultBusinessId,
3905
4122
  is_authenticated: authenticated,
4123
+ account_id: authenticated ? ids.raw("account") : void 0,
3906
4124
  customer_id: authenticated ? ids.customer() : void 0,
3907
4125
  customer_name: profile?.name,
3908
4126
  customer_email: profile?.email,
@@ -3985,7 +4203,7 @@ function createAuthService(opts) {
3985
4203
  if (!s) return { is_authenticated: false, user_type: "guest" };
3986
4204
  return {
3987
4205
  is_authenticated: s.is_authenticated,
3988
- account_id: s.customer_id,
4206
+ account_id: s.account_id,
3989
4207
  user_type: s.is_authenticated ? "customer" : "guest",
3990
4208
  session_expires_at: s.expires_at ? Math.floor(new Date(s.expires_at).getTime() / 1e3) : void 0,
3991
4209
  session: s
@@ -5283,88 +5501,10 @@ function createCartService(opts) {
5283
5501
  };
5284
5502
  }
5285
5503
 
5286
- // src/mock/domain/checkout.ts
5287
- function createCheckoutService(opts) {
5288
- const { registry, clock, ids, bus } = opts;
5504
+ // src/mock/domain/payment.ts
5505
+ function createPaymentService(options) {
5506
+ const { registry, clock, bus } = options;
5289
5507
  return {
5290
- process(session, body) {
5291
- if (!body.cart_id) throw validation("cart_id required");
5292
- const c = registry.carts.get(body.cart_id);
5293
- if (!c) throw notFound(`Cart ${body.cart_id} not found`);
5294
- if (c.items.length === 0) throw validation("Cart is empty", { code: "CART_EMPTY" });
5295
- const orderId = ids.order();
5296
- const orderNumber = ids.orderNumber();
5297
- const paymentId = ids.payment();
5298
- const reference = ids.payment();
5299
- const requiresAuth = body.payment_method === "mobile_money";
5300
- const isCard = body.payment_method === "card" || body.payment_method === "stripe";
5301
- const cardProvider = body.payment_method === "stripe" || body.pay_currency?.toUpperCase() === "USD" ? "stripe" : "paystack";
5302
- const order = {
5303
- id: orderId,
5304
- business_id: c.business_id,
5305
- user_friendly_id: orderNumber,
5306
- channel: c.channel,
5307
- status: requiresAuth ? "pending" : "confirmed",
5308
- payment_state: requiresAuth ? "not_paid" : "paid",
5309
- order_type: body.order_type,
5310
- customer_id: session.customer_id,
5311
- customer_name: body.customer.name,
5312
- customer_email: body.customer.email,
5313
- customer_phone: body.customer.phone,
5314
- delivery_address: body.address_info?.street_address,
5315
- delivery_fee: c.delivery_fee,
5316
- subtotal: c.subtotal,
5317
- tax_amount: c.tax_amount,
5318
- service_charge: c.service_charge,
5319
- total_discounts: c.total_discounts,
5320
- total_price: c.total_price,
5321
- currency: c.currency,
5322
- items: c.items,
5323
- applied_discount_ids: c.applied_discount_ids,
5324
- applied_discount_codes: c.applied_discount_codes,
5325
- payment_id: paymentId,
5326
- payment_reference: reference,
5327
- metadata: body.metadata,
5328
- created_at: clock.iso(),
5329
- updated_at: clock.iso()
5330
- };
5331
- registry.orders.put(orderId, order);
5332
- registry.carts.put(c.id, { ...c, status: "converted", updated_at: clock.iso() });
5333
- bus.emit("order.created", { order_id: orderId, order_number: orderNumber }, c.business_id);
5334
- if (!requiresAuth) {
5335
- bus.emit("order.payment.captured", { order_id: orderId, reference }, c.business_id);
5336
- bus.emit("order.confirmed", { order_id: orderId }, c.business_id);
5337
- }
5338
- const billToken = `bt_${reference.slice(-12)}_${Math.random().toString(36).slice(2, 10)}`;
5339
- const result = {
5340
- order_id: orderId,
5341
- order_number: orderNumber,
5342
- payment_id: paymentId,
5343
- payment_status: requiresAuth || isCard ? "pending" : "succeeded",
5344
- payment_reference: reference,
5345
- requires_authorization: requiresAuth,
5346
- authorization_type: requiresAuth ? "otp" : void 0,
5347
- next_action: requiresAuth ? {
5348
- type: "authorization",
5349
- authorization_type: "otp",
5350
- display_text: "Approve on your mobile money app"
5351
- } : { type: "none" },
5352
- provider: isCard ? cardProvider : body.payment_method,
5353
- bill_token: billToken
5354
- };
5355
- if (isCard) {
5356
- const proc = globalThis.process;
5357
- result.client_secret = cardProvider === "stripe" ? `pi_${orderId.slice(-12)}_secret_${Math.random().toString(36).slice(2, 18)}` : `access_${reference}`;
5358
- result.public_key = cardProvider === "stripe" ? proc?.env?.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ?? "pk_test_mock_stripe" : proc?.env?.NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY ?? "pk_test_mock_paystack";
5359
- result.next_action = {
5360
- type: "card_popup",
5361
- provider: cardProvider,
5362
- client_secret: result.client_secret,
5363
- public_key: result.public_key
5364
- };
5365
- }
5366
- return result;
5367
- },
5368
5508
  authorize(body) {
5369
5509
  if (!body.payment_id?.trim()) throw validation("payment_id required");
5370
5510
  if (!body.authorization) throw validation("authorization required");
@@ -5375,7 +5515,7 @@ function createCheckoutService(opts) {
5375
5515
  const updated = {
5376
5516
  ...order,
5377
5517
  payment_state: "paid",
5378
- status: "confirmed",
5518
+ status: CHECKOUT_ORDER_RESULT_STATUS.CONFIRMED,
5379
5519
  updated_at: clock.iso()
5380
5520
  };
5381
5521
  registry.orders.put(order.id, updated);
@@ -5386,10 +5526,538 @@ function createCheckoutService(opts) {
5386
5526
  order_number: order.user_friendly_id,
5387
5527
  payment_id: body.payment_id,
5388
5528
  payment_reference: order.payment_reference,
5389
- payment_status: "succeeded",
5529
+ payment_status: LEGACY_CHECKOUT_PAYMENT_STATUS.SUCCEEDED,
5390
5530
  requires_authorization: false,
5391
- next_action: { type: "none" }
5531
+ next_action: { type: CHECKOUT_NEXT_ACTION.NONE }
5532
+ };
5533
+ }
5534
+ };
5535
+ }
5536
+
5537
+ // src/mock/domain/purchase-intent.ts
5538
+ var INTENT_LIFETIME_MS = 15 * 60 * 1e3;
5539
+ var ZERO_MONEY = "0.00";
5540
+ var PURCHASE_INTENT_MOBILE_MONEY_NETWORKS = new Set(
5541
+ Object.values(PURCHASE_INTENT_MOBILE_MONEY_NETWORK)
5542
+ );
5543
+ var MOCK_PURCHASE_INTENT = {
5544
+ OWNER_KIND: { ACCOUNT: "account", STOREFRONT_SESSION: "storefront_session" },
5545
+ CART_STATUS: { ACTIVE: "active", CONVERTED: "converted" },
5546
+ ORDER_STATUS: { PENDING: "pending", CONFIRMED: "confirmed" },
5547
+ PAYMENT_STATE: { NOT_PAID: "not_paid", PAID: "paid" },
5548
+ EVENT: {
5549
+ ORDER_CREATED: "order.created",
5550
+ PAYMENT_CAPTURED: "order.payment.captured",
5551
+ ORDER_CONFIRMED: "order.confirmed"
5552
+ },
5553
+ ID_PREFIX: { INTENT: "pi", ATTEMPT: "attempt" },
5554
+ DEFAULT_LOCATION_ID: "mock-location",
5555
+ MOCK_PAYSTACK_PUBLIC_KEY: "pk_test_mock_paystack",
5556
+ COMPLIANCE: {
5557
+ POLICY_NAME: "mock-storefront-commerce"
5558
+ }
5559
+ };
5560
+ var DECIMAL_WIRE_VALUE = /^([+-]?)(\d+)(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
5561
+ function isExactlyZero(value) {
5562
+ if (typeof value === "number") return Object.is(value, 0) || Object.is(value, -0);
5563
+ const match2 = DECIMAL_WIRE_VALUE.exec(value.trim());
5564
+ return Boolean(match2 && [...match2[2], ...match2[3] ?? ""].every((digit) => digit === "0"));
5565
+ }
5566
+ function sameDecimal(left, right) {
5567
+ const canonical = (value) => {
5568
+ const wire = typeof value === "number" ? String(value) : value.trim();
5569
+ const match2 = DECIMAL_WIRE_VALUE.exec(wire);
5570
+ if (!match2) return null;
5571
+ let digits = `${match2[2]}${match2[3] ?? ""}`.replace(/^0+/, "");
5572
+ if (!digits) return "0";
5573
+ let scale = BigInt((match2[3] ?? "").length) - BigInt(match2[4] ?? "0");
5574
+ while (digits.endsWith("0")) {
5575
+ digits = digits.slice(0, -1);
5576
+ scale -= 1n;
5577
+ }
5578
+ const sign = match2[1] === "-" ? "-" : "";
5579
+ return `${sign}${digits}:${scale}`;
5580
+ };
5581
+ const normalizedLeft = canonical(left);
5582
+ return normalizedLeft !== null && normalizedLeft === canonical(right);
5583
+ }
5584
+ function wireMoney(value) {
5585
+ return typeof value === "string" ? value.trim() : String(value);
5586
+ }
5587
+ function decimal(value) {
5588
+ return wireMoney(value.toFixed(2));
5589
+ }
5590
+ function paymentOptions(intentId, currency, amount, expiresAt) {
5591
+ const normalizedCurrency = currencyCode(currency);
5592
+ const normalizedAmount = wireMoney(amount);
5593
+ return [
5594
+ {
5595
+ id: `${intentId}:${PURCHASE_INTENT_PAYMENT_METHOD.CARD}`,
5596
+ rank: 0,
5597
+ method_kind: PURCHASE_INTENT_PAYMENT_METHOD.CARD,
5598
+ collection_mode: PAYMENT_COLLECTION_MODE.CREDENTIAL_CHARGE,
5599
+ provider: PURCHASE_INTENT_PAYMENT_PROVIDER.PAYSTACK,
5600
+ principal_amount: normalizedAmount,
5601
+ fee_amount: wireMoney(ZERO_MONEY),
5602
+ customer_debit_amount: normalizedAmount,
5603
+ currency: normalizedCurrency,
5604
+ status: PAYMENT_OPTION_STATUS.ELIGIBLE,
5605
+ expected_next_action: PAYMENT_OPTION_NEXT_ACTION.PROVIDER_APPROVAL,
5606
+ expires_at: expiresAt
5607
+ },
5608
+ {
5609
+ id: `${intentId}:${PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY}`,
5610
+ rank: 1,
5611
+ method_kind: PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY,
5612
+ collection_mode: PAYMENT_COLLECTION_MODE.REQUEST_TO_PAY,
5613
+ provider: PURCHASE_INTENT_PAYMENT_PROVIDER.PAYSTACK,
5614
+ principal_amount: normalizedAmount,
5615
+ fee_amount: wireMoney(ZERO_MONEY),
5616
+ customer_debit_amount: normalizedAmount,
5617
+ currency: normalizedCurrency,
5618
+ status: PAYMENT_OPTION_STATUS.ELIGIBLE,
5619
+ expected_next_action: PAYMENT_OPTION_NEXT_ACTION.PROVIDER_APPROVAL,
5620
+ expires_at: expiresAt
5621
+ }
5622
+ ];
5623
+ }
5624
+ function termsForCart(input) {
5625
+ const total = wireMoney(input.total);
5626
+ return {
5627
+ id: `${input.intentId}:terms:${input.version}`,
5628
+ intent_revision: input.revision,
5629
+ terms_version: input.version,
5630
+ terms_digest: `mock:${input.intentId}:${input.revision}:${input.version}`,
5631
+ money: {
5632
+ currency: currencyCode(input.currency),
5633
+ subtotal: wireMoney(input.subtotal),
5634
+ discount_total: wireMoney(input.discount),
5635
+ tax_total: wireMoney(input.tax),
5636
+ delivery_total: wireMoney(input.delivery),
5637
+ statutory_total: wireMoney(ZERO_MONEY),
5638
+ total_obligation: total,
5639
+ due_now: total,
5640
+ rail_amount: total,
5641
+ store_credit_consumed: wireMoney(ZERO_MONEY),
5642
+ voucher_credit_consumed: wireMoney(ZERO_MONEY)
5643
+ },
5644
+ material: {
5645
+ line_digest: `mock-lines:${input.intentId}`,
5646
+ destination_digest: `mock-destination:${input.intentId}`,
5647
+ delivery_promise_digest: `mock-delivery:${input.intentId}`,
5648
+ entitlement_digest: `mock-entitlement:${input.intentId}`,
5649
+ cancellation_terms_digest: `mock-cancellation:${input.intentId}`
5650
+ },
5651
+ compliance: {
5652
+ policy_name: MOCK_PURCHASE_INTENT.COMPLIANCE.POLICY_NAME,
5653
+ policy_version: 1,
5654
+ lane: CHECKOUT_COMPLIANCE_LANE.NATIVE,
5655
+ reason_code: CHECKOUT_COMPLIANCE_REASON.PHYSICAL_GOODS_NATIVE,
5656
+ evidence_digest: `mock-compliance:${input.intentId}`
5657
+ },
5658
+ payment_options: isExactlyZero(input.total) ? [] : paymentOptions(input.intentId, input.currency, input.total, input.validUntil),
5659
+ valid_until: input.validUntil,
5660
+ created_at: input.now
5661
+ };
5662
+ }
5663
+ function intentView(intent) {
5664
+ const {
5665
+ intent_owner: _owner,
5666
+ mint_request: _request,
5667
+ last_confirmation: _confirmation,
5668
+ ...view
5669
+ } = intent;
5670
+ return view;
5671
+ }
5672
+ function purchasingPrincipal(session) {
5673
+ if (!session.is_authenticated) {
5674
+ return { kind: PURCHASING_PRINCIPAL_KIND.GUEST };
5675
+ }
5676
+ if (!session.account_id) throw validation("Authenticated mock session has no account authority");
5677
+ return {
5678
+ kind: PURCHASING_PRINCIPAL_KIND.ACCOUNT,
5679
+ account_id: session.account_id
5680
+ };
5681
+ }
5682
+ function assertSupportedTenderPreference(request) {
5683
+ if (request.source.kind !== PURCHASE_INTENT_SOURCE_KIND.CART) return;
5684
+ const checkout = request.checkout;
5685
+ if (!checkout) throw validation("Cart checkout input is required");
5686
+ const preference = checkout.tender_preference;
5687
+ if (preference?.method_kind !== PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY || preference.authority.authority_kind !== MOBILE_MONEY_TENDER_AUTHORITY_KIND.TRANSIENT) {
5688
+ return;
5689
+ }
5690
+ if (!PURCHASE_INTENT_MOBILE_MONEY_NETWORKS.has(preference.authority.network)) {
5691
+ throw validation("Mobile Money network is not available for PurchaseIntent checkout");
5692
+ }
5693
+ }
5694
+ function intentOwner(session) {
5695
+ if (!session.is_authenticated) {
5696
+ return { kind: MOCK_PURCHASE_INTENT.OWNER_KIND.STOREFRONT_SESSION, id: session.id };
5697
+ }
5698
+ if (!session.account_id) throw validation("Authenticated mock session has no account authority");
5699
+ return { kind: MOCK_PURCHASE_INTENT.OWNER_KIND.ACCOUNT, id: session.account_id };
5700
+ }
5701
+ function createPurchaseIntentMockService(options) {
5702
+ const { registry, clock, ids, bus } = options;
5703
+ function stored(session, intentId) {
5704
+ const intent = registry.purchaseIntents.get(intentId);
5705
+ if (!intent) throw notFound(`Purchase intent ${intentId} not found`);
5706
+ const owner = intentOwner(session);
5707
+ if (intent.intent_owner.kind !== owner.kind || intent.intent_owner.id !== owner.id) {
5708
+ throw notFound(`Purchase intent ${intentId} not found`);
5709
+ }
5710
+ return intent;
5711
+ }
5712
+ function completeProviderOrder(intent, order, attemptId) {
5713
+ const updated = {
5714
+ ...order,
5715
+ payment_state: MOCK_PURCHASE_INTENT.PAYMENT_STATE.PAID,
5716
+ status: MOCK_PURCHASE_INTENT.ORDER_STATUS.CONFIRMED,
5717
+ updated_at: clock.iso()
5718
+ };
5719
+ registry.orders.put(order.id, updated);
5720
+ bus.emit(
5721
+ MOCK_PURCHASE_INTENT.EVENT.PAYMENT_CAPTURED,
5722
+ { order_id: order.id, reference: order.payment_reference },
5723
+ order.business_id
5724
+ );
5725
+ bus.emit(MOCK_PURCHASE_INTENT.EVENT.ORDER_CONFIRMED, { order_id: order.id }, order.business_id);
5726
+ const completed = {
5727
+ status: PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED,
5728
+ intent_id: intent.id,
5729
+ attempt_id: attemptId,
5730
+ order_id: order.id,
5731
+ order_number: order.user_friendly_id,
5732
+ payment_id: order.payment_id
5733
+ };
5734
+ registry.purchaseIntents.put(intent.id, {
5735
+ ...intent,
5736
+ updated_at: clock.iso(),
5737
+ last_confirmation: completed
5738
+ });
5739
+ return completed;
5740
+ }
5741
+ return {
5742
+ mint(session, request) {
5743
+ if (!request.client_intent_key.trim()) throw validation("client_intent_key required");
5744
+ if (request.source.kind !== PURCHASE_INTENT_SOURCE_KIND.CART) {
5745
+ throw validation("The mock currently prepares cart purchase intents only");
5746
+ }
5747
+ const checkoutInput = request.checkout;
5748
+ if (!checkoutInput) throw validation("Cart checkout input is required");
5749
+ assertSupportedTenderPreference(request);
5750
+ const cart = registry.carts.get(request.source.cart_id);
5751
+ if (!cart) throw notFound(`Cart ${request.source.cart_id} not found`);
5752
+ if (cart.items.length === 0) {
5753
+ throw validation("Cart is empty", { code: ErrorCode.CART_EMPTY });
5754
+ }
5755
+ const principal = purchasingPrincipal(session);
5756
+ const owner = intentOwner(session);
5757
+ const existing = registry.purchaseIntents.list(
5758
+ (candidate) => candidate.mint_request.client_intent_key === request.client_intent_key && candidate.intent_owner.kind === owner.kind && candidate.intent_owner.id === owner.id
5759
+ )[0];
5760
+ if (existing) return intentView(existing);
5761
+ const now = clock.iso();
5762
+ const expiresAt = new Date(clock.nowMs() + INTENT_LIFETIME_MS).toISOString();
5763
+ const intentId = ids.raw(MOCK_PURCHASE_INTENT.ID_PREFIX.INTENT);
5764
+ const terms = termsForCart({
5765
+ intentId,
5766
+ revision: 1,
5767
+ version: 1,
5768
+ currency: cart.currency,
5769
+ subtotal: cart.subtotal,
5770
+ discount: cart.total_discounts,
5771
+ tax: cart.tax_amount,
5772
+ delivery: cart.delivery_fee,
5773
+ total: cart.total_price,
5774
+ now,
5775
+ validUntil: expiresAt
5776
+ });
5777
+ const intent = {
5778
+ id: intentId,
5779
+ seller_business_id: cart.business_id,
5780
+ principal,
5781
+ revision: 1,
5782
+ status: PURCHASE_INTENT_STATUS.OPEN,
5783
+ source: {
5784
+ kind: PURCHASE_INTENT_SOURCE_KIND.CART,
5785
+ source_id: cart.id,
5786
+ source_version: cart.updated_at,
5787
+ seller_business_id: cart.business_id,
5788
+ subject: {
5789
+ kind: PURCHASING_PRINCIPAL_KIND.BUSINESS,
5790
+ business_id: cart.business_id
5791
+ },
5792
+ binding_digest: `mock-cart:${cart.id}:${cart.updated_at}`
5793
+ },
5794
+ lines: cart.items.map((line, ordinal) => ({
5795
+ id: line.id,
5796
+ ordinal,
5797
+ sellable: {
5798
+ kind: line.variant_id ? PURCHASE_INTENT_SELLABLE_KIND.VARIANT : PURCHASE_INTENT_SELLABLE_KIND.PRODUCT,
5799
+ product_id: line.item_id,
5800
+ variant_id: line.variant_id,
5801
+ location_id: checkoutInput.location_id || MOCK_PURCHASE_INTENT.DEFAULT_LOCATION_ID
5802
+ },
5803
+ quantity: line.quantity,
5804
+ configuration: {
5805
+ kind: PURCHASE_INTENT_LINE_CONFIGURATION_KIND.SIMPLE,
5806
+ variant_id: line.variant_id,
5807
+ customer_inputs: line.customer_inputs
5808
+ }
5809
+ })),
5810
+ line_pricing: cart.items.map((line) => {
5811
+ const unitPrice = Number(line.price) + Number(line.add_ons_price);
5812
+ const lineSubtotal = unitPrice * line.quantity - Number(line.item_discount_amount);
5813
+ return {
5814
+ intent_line_id: line.id,
5815
+ quantity: line.quantity,
5816
+ unit_price: decimal(unitPrice),
5817
+ line_subtotal: decimal(lineSubtotal),
5818
+ currency: currencyCode(cart.currency)
5819
+ };
5820
+ }),
5821
+ current_terms: terms,
5822
+ expires_at: expiresAt,
5823
+ created_at: now,
5824
+ updated_at: now,
5825
+ intent_owner: owner,
5826
+ mint_request: request
5827
+ };
5828
+ registry.purchaseIntents.put(intentId, intent);
5829
+ return intentView(intent);
5830
+ },
5831
+ get(session, intentId) {
5832
+ return intentView(stored(session, intentId));
5833
+ },
5834
+ refresh(session, intentId, expectedRevision) {
5835
+ const intent = stored(session, intentId);
5836
+ if (intent.revision !== expectedRevision) {
5837
+ throw validation("expected_intent_revision does not match current intent revision");
5838
+ }
5839
+ if (!intent.current_terms) throw validation("Purchase intent has no current terms");
5840
+ const previous = intent.current_terms;
5841
+ const nextDelivery = Number(previous.money.delivery_total) + 1;
5842
+ const nextTotal = Number(previous.money.total_obligation) + 1;
5843
+ const now = clock.iso();
5844
+ const replacement = termsForCart({
5845
+ intentId,
5846
+ revision: intent.revision,
5847
+ version: previous.terms_version + 1,
5848
+ currency: previous.money.currency,
5849
+ subtotal: String(previous.money.subtotal),
5850
+ discount: String(previous.money.discount_total),
5851
+ tax: String(previous.money.tax_total),
5852
+ delivery: nextDelivery.toFixed(2),
5853
+ total: nextTotal.toFixed(2),
5854
+ now,
5855
+ validUntil: intent.expires_at
5856
+ });
5857
+ const updated = { ...intent, current_terms: replacement, updated_at: now };
5858
+ registry.purchaseIntents.put(intentId, updated);
5859
+ return intentView(updated);
5860
+ },
5861
+ confirm(session, intentId, request) {
5862
+ const intent = stored(session, intentId);
5863
+ if (intent.status === PURCHASE_INTENT_STATUS.CONVERTED && intent.last_confirmation) {
5864
+ const orderId2 = "order_id" in intent.last_confirmation ? intent.last_confirmation.order_id : void 0;
5865
+ const order2 = orderId2 ? registry.orders.get(orderId2) : void 0;
5866
+ if (order2?.payment_state === MOCK_PURCHASE_INTENT.PAYMENT_STATE.PAID) {
5867
+ return {
5868
+ status: PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED,
5869
+ intent_id: intent.id,
5870
+ attempt_id: "attempt_id" in intent.last_confirmation ? intent.last_confirmation.attempt_id : ids.raw(MOCK_PURCHASE_INTENT.ID_PREFIX.ATTEMPT),
5871
+ order_id: order2.id
5872
+ };
5873
+ }
5874
+ if (order2?.payment_id && intent.last_confirmation.status === PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED) {
5875
+ return completeProviderOrder(intent, order2, intent.last_confirmation.attempt_id);
5876
+ }
5877
+ return intent.last_confirmation;
5878
+ }
5879
+ const terms = intent.current_terms;
5880
+ if (!terms) throw validation("Purchase intent has no current terms");
5881
+ const zeroRail = isExactlyZero(terms.money.rail_amount);
5882
+ const option = request.payment_option_id ? terms.payment_options.find(
5883
+ (candidate) => candidate.id === request.payment_option_id && candidate.status === PAYMENT_OPTION_STATUS.ELIGIBLE
5884
+ ) : void 0;
5885
+ const acceptedBaseTermsChanged = !sameDecimal(request.accepted_due_now, terms.money.due_now) || request.currency !== terms.money.currency;
5886
+ if (request.accepted_intent_revision !== intent.revision || request.accepted_terms_version !== terms.terms_version || acceptedBaseTermsChanged) {
5887
+ const deltas = acceptedBaseTermsChanged ? [
5888
+ {
5889
+ kind: CHECKOUT_TERMS_DELTA_KIND.MONEY,
5890
+ component: CHECKOUT_TERMS_COMPONENT.DUE_NOW,
5891
+ accepted: request.accepted_due_now,
5892
+ replacement: terms.money.due_now
5893
+ }
5894
+ ] : [
5895
+ {
5896
+ kind: CHECKOUT_TERMS_DELTA_KIND.PAYMENT_OPTION,
5897
+ accepted_option_id: request.payment_option_id ?? null,
5898
+ accepted_customer_debit_amount: request.accepted_customer_debit_amount,
5899
+ replacement_option_id: option?.id ?? null,
5900
+ replacement_customer_debit_amount: option?.customer_debit_amount ?? null
5901
+ }
5902
+ ];
5903
+ return {
5904
+ status: PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED,
5905
+ intent_id: intent.id,
5906
+ replacement: terms,
5907
+ deltas
5908
+ };
5909
+ }
5910
+ if (!zeroRail && !option || zeroRail && request.payment_option_id != null) {
5911
+ return {
5912
+ status: PURCHASE_INTENT_CONFIRM_STATUS.SELECTION_UNAVAILABLE,
5913
+ intent_id: intent.id,
5914
+ lines: intent.lines.map((line) => ({
5915
+ line_id: line.id,
5916
+ reason: CHECKOUT_INVALIDATION_REASON.PAYMENT_OPTION_CHANGED
5917
+ }))
5918
+ };
5919
+ }
5920
+ const acceptedCustomerDebitMatches = zeroRail ? isExactlyZero(request.accepted_customer_debit_amount) : Boolean(
5921
+ option && sameDecimal(request.accepted_customer_debit_amount, option.customer_debit_amount)
5922
+ );
5923
+ if (!acceptedCustomerDebitMatches) {
5924
+ return {
5925
+ status: PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED,
5926
+ intent_id: intent.id,
5927
+ replacement: terms,
5928
+ deltas: [
5929
+ {
5930
+ kind: CHECKOUT_TERMS_DELTA_KIND.PAYMENT_OPTION,
5931
+ accepted_option_id: request.payment_option_id ?? null,
5932
+ accepted_customer_debit_amount: request.accepted_customer_debit_amount,
5933
+ replacement_option_id: option?.id ?? null,
5934
+ replacement_customer_debit_amount: option?.customer_debit_amount ?? null
5935
+ }
5936
+ ]
5937
+ };
5938
+ }
5939
+ if (intent.mint_request.source.kind !== PURCHASE_INTENT_SOURCE_KIND.CART) {
5940
+ throw validation("The mock currently confirms cart purchase intents only");
5941
+ }
5942
+ const checkoutInput = intent.mint_request.checkout;
5943
+ if (!checkoutInput) throw validation("Cart checkout input is required");
5944
+ const cart = registry.carts.get(intent.mint_request.source.cart_id);
5945
+ if (!cart || cart.status !== MOCK_PURCHASE_INTENT.CART_STATUS.ACTIVE) {
5946
+ return { status: PURCHASE_INTENT_CONFIRM_STATUS.SOURCE_UNAVAILABLE, intent_id: intent.id };
5947
+ }
5948
+ const attemptId = ids.raw(MOCK_PURCHASE_INTENT.ID_PREFIX.ATTEMPT);
5949
+ const orderId = ids.order();
5950
+ const orderNumber = ids.orderNumber();
5951
+ const paymentId = zeroRail ? void 0 : ids.payment();
5952
+ const paymentReference = zeroRail ? void 0 : ids.payment();
5953
+ const needsProvider = option?.method_kind === PURCHASE_INTENT_PAYMENT_METHOD.CARD || option?.method_kind === PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY;
5954
+ const paid = zeroRail;
5955
+ const order = {
5956
+ id: orderId,
5957
+ business_id: cart.business_id,
5958
+ user_friendly_id: orderNumber,
5959
+ channel: cart.channel,
5960
+ status: paid ? MOCK_PURCHASE_INTENT.ORDER_STATUS.CONFIRMED : MOCK_PURCHASE_INTENT.ORDER_STATUS.PENDING,
5961
+ payment_state: paid ? MOCK_PURCHASE_INTENT.PAYMENT_STATE.PAID : MOCK_PURCHASE_INTENT.PAYMENT_STATE.NOT_PAID,
5962
+ order_type: checkoutInput.order_type,
5963
+ customer_id: session.customer_id,
5964
+ customer_name: checkoutInput.customer.name,
5965
+ customer_email: checkoutInput.customer.email,
5966
+ customer_phone: checkoutInput.customer.phone,
5967
+ delivery_address: checkoutInput.address_info.street_address,
5968
+ delivery_fee: cart.delivery_fee,
5969
+ subtotal: cart.subtotal,
5970
+ tax_amount: cart.tax_amount,
5971
+ service_charge: cart.service_charge,
5972
+ total_discounts: cart.total_discounts,
5973
+ total_price: cart.total_price,
5974
+ currency: cart.currency,
5975
+ items: cart.items,
5976
+ applied_discount_ids: cart.applied_discount_ids,
5977
+ applied_discount_codes: cart.applied_discount_codes,
5978
+ payment_id: paymentId,
5979
+ payment_reference: paymentReference,
5980
+ metadata: checkoutInput.metadata,
5981
+ created_at: clock.iso(),
5982
+ updated_at: clock.iso()
5392
5983
  };
5984
+ registry.orders.put(orderId, order);
5985
+ registry.carts.put(cart.id, {
5986
+ ...cart,
5987
+ status: MOCK_PURCHASE_INTENT.CART_STATUS.CONVERTED,
5988
+ updated_at: clock.iso()
5989
+ });
5990
+ bus.emit(
5991
+ MOCK_PURCHASE_INTENT.EVENT.ORDER_CREATED,
5992
+ { order_id: orderId, order_number: orderNumber },
5993
+ cart.business_id
5994
+ );
5995
+ if (paid) {
5996
+ if (paymentReference) {
5997
+ bus.emit(
5998
+ MOCK_PURCHASE_INTENT.EVENT.PAYMENT_CAPTURED,
5999
+ { order_id: orderId, reference: paymentReference },
6000
+ cart.business_id
6001
+ );
6002
+ }
6003
+ bus.emit(
6004
+ MOCK_PURCHASE_INTENT.EVENT.ORDER_CONFIRMED,
6005
+ { order_id: orderId },
6006
+ cart.business_id
6007
+ );
6008
+ }
6009
+ let confirmation;
6010
+ if (option?.method_kind === PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY) {
6011
+ confirmation = {
6012
+ status: PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED,
6013
+ intent_id: intent.id,
6014
+ attempt_id: attemptId,
6015
+ order_id: orderId,
6016
+ authorization_type: AUTHORIZATION_TYPE.OTP,
6017
+ display_text: "Approve on your mobile money app"
6018
+ };
6019
+ } else if (option?.method_kind === PURCHASE_INTENT_PAYMENT_METHOD.CARD) {
6020
+ confirmation = {
6021
+ status: PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED,
6022
+ intent_id: intent.id,
6023
+ attempt_id: attemptId,
6024
+ order_id: orderId,
6025
+ provider: PURCHASE_INTENT_PAYMENT_PROVIDER.PAYSTACK,
6026
+ client_secret: `access_${paymentReference}`,
6027
+ public_key: MOCK_PURCHASE_INTENT.MOCK_PAYSTACK_PUBLIC_KEY
6028
+ };
6029
+ } else {
6030
+ confirmation = {
6031
+ status: PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED,
6032
+ intent_id: intent.id,
6033
+ attempt_id: attemptId,
6034
+ order_id: orderId
6035
+ };
6036
+ }
6037
+ if (needsProvider && !paymentId) {
6038
+ throw validation("Provider-backed purchase intent has no payment authority");
6039
+ }
6040
+ registry.purchaseIntents.put(intent.id, {
6041
+ ...intent,
6042
+ status: PURCHASE_INTENT_STATUS.CONVERTED,
6043
+ converted_order_id: orderId,
6044
+ updated_at: clock.iso(),
6045
+ last_confirmation: confirmation
6046
+ });
6047
+ return confirmation;
6048
+ },
6049
+ submitAction(session, intentId, attemptId, request) {
6050
+ const intent = stored(session, intentId);
6051
+ const previous = intent.last_confirmation;
6052
+ if (!previous || previous.status !== PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED || previous.attempt_id !== attemptId) {
6053
+ throw validation("Purchase-intent attempt is not awaiting authorization");
6054
+ }
6055
+ if (!request.authorization) throw validation("authorization required");
6056
+ const order = registry.orders.get(previous.order_id);
6057
+ if (!order || !order.payment_id) {
6058
+ throw notFound(`Purchase-intent attempt ${attemptId} not found`);
6059
+ }
6060
+ return completeProviderOrder(intent, order, attemptId);
5393
6061
  }
5394
6062
  };
5395
6063
  }
@@ -10683,7 +11351,7 @@ var ID_PREFIX = {
10683
11351
  product: "prod_",
10684
11352
  service: "svc_"
10685
11353
  };
10686
- var DEFAULT_CURRENCY = "GHS";
11354
+ var DEFAULT_CURRENCY2 = "GHS";
10687
11355
  function slugify(value) {
10688
11356
  return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10689
11357
  }
@@ -10718,7 +11386,7 @@ function makeSeedContext(registry) {
10718
11386
  const business = {
10719
11387
  business_type: "other",
10720
11388
  email: `hello@${handle}.test`,
10721
- default_currency: DEFAULT_CURRENCY,
11389
+ default_currency: DEFAULT_CURRENCY2,
10722
11390
  default_offers_table_service: false,
10723
11391
  default_accepts_online_orders: true,
10724
11392
  status: "active",
@@ -10897,7 +11565,8 @@ function createDeps(options = {}) {
10897
11565
  const inventory = createInventoryService({ registry });
10898
11566
  const cart = createCartService({ registry, clock, ids, bus, inventory });
10899
11567
  const orders = createOrderService({ registry, clock, bus });
10900
- const checkout = createCheckoutService({ registry, clock, ids, bus});
11568
+ const payments = createPaymentService({ registry, clock, bus });
11569
+ const purchaseIntents = createPurchaseIntentMockService({ registry, clock, ids, bus });
10901
11570
  const subscriptions = createSubscriptionService({ registry, clock, bus });
10902
11571
  const scheduling = createSchedulingService({ registry, clock, bus });
10903
11572
  const fx = createFxService({ registry, clock, ids });
@@ -10918,7 +11587,8 @@ function createDeps(options = {}) {
10918
11587
  business,
10919
11588
  catalogue,
10920
11589
  cart,
10921
- checkout,
11590
+ payments,
11591
+ purchaseIntents,
10922
11592
  orders,
10923
11593
  subscriptions,
10924
11594
  scheduling,