@cimplify/sdk 0.103.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.
- package/dist/advanced.d.mts +3 -7
- package/dist/advanced.d.ts +3 -7
- package/dist/advanced.js +23 -23
- package/dist/advanced.mjs +4 -4
- package/dist/{client-DHBwvh7U.d.ts → catalogue-BlQ85Uma.d.mts} +492 -748
- package/dist/{client-BfpNjJ_a.d.mts → catalogue-C8TqOj9K.d.ts} +492 -748
- package/dist/{payment-H5LoIvXU.d.mts → checkout-BqK9XUz5.d.mts} +4338 -1495
- package/dist/{payment-H5LoIvXU.d.ts → checkout-BqK9XUz5.d.ts} +4338 -1495
- package/dist/{chunk-GOHSXBKW.mjs → chunk-33VCYWVL.mjs} +25 -1
- package/dist/{chunk-C2JSNJUC.mjs → chunk-6G3ANKQA.mjs} +1080 -369
- package/dist/{chunk-QOWPGS7Z.js → chunk-BWEIMKLF.js} +572 -17
- package/dist/{chunk-JSWJ4XDE.js → chunk-DQEXY542.js} +1630 -824
- package/dist/{chunk-CNN7Z2IP.js → chunk-EV2EVOYS.js} +27 -0
- package/dist/{chunk-VIL6IQCG.js → chunk-HYFA67A7.js} +1084 -373
- package/dist/{chunk-H7ACMHM3.mjs → chunk-L5SNEU2O.mjs} +553 -16
- package/dist/{chunk-JG5CQNCB.js → chunk-RBNBSQI7.mjs} +221 -19
- package/dist/{chunk-VNPEYLB2.mjs → chunk-SFUJMS5E.js} +265 -2
- package/dist/{chunk-M4URVKHE.mjs → chunk-U54CWUUT.mjs} +11 -2
- package/dist/{chunk-GERXZQSX.mjs → chunk-UFOWPN3D.mjs} +967 -582
- package/dist/{chunk-J6PNHDHL.mjs → chunk-V4457OKB.mjs} +1580 -785
- package/dist/{chunk-R6OLQ33I.js → chunk-WXREIBFW.js} +1041 -654
- package/dist/{chunk-NNG6IFFX.js → chunk-XAUSDMMZ.js} +13 -3
- package/dist/{client-DpqRobY9.d.mts → client-DhXeiUrf.d.ts} +2 -2
- package/dist/{client-Dqg2mc-7.d.ts → client-mXiUrV4X.d.mts} +2 -2
- package/dist/{index-C8uDqLwJ.d.ts → index-B0AdZvrM.d.mts} +9 -4
- package/dist/{index-e2y6AK70.d.mts → index-CK8Nk5uQ.d.ts} +9 -4
- package/dist/index-DPWI5XcU.d.ts +8 -0
- package/dist/index-DVfUh-ci.d.mts +8 -0
- package/dist/index.d.mts +34 -15
- package/dist/index.d.ts +34 -15
- package/dist/index.js +306 -133
- package/dist/index.mjs +7 -6
- package/dist/mock/cli.mjs +1494 -395
- package/dist/mock/library.js +1220 -361
- package/dist/mock/library.mjs +1220 -361
- package/dist/mock/msw.js +1220 -361
- package/dist/mock/msw.mjs +1220 -361
- package/dist/{price-C2RqscMY.d.ts → price-6hQIIac9.d.ts} +1 -1
- package/dist/{price-BvePgDXe.d.mts → price-BUDv1rI7.d.mts} +1 -1
- package/dist/react.d.mts +10 -5
- package/dist/react.d.ts +10 -5
- package/dist/react.js +279 -225
- package/dist/react.mjs +140 -86
- package/dist/{server-DoXIpSd7.d.ts → server-DJ0mSs9i.d.mts} +33 -57
- package/dist/{server-C7FyLdrz.d.mts → server-DSTX76Ki.d.ts} +33 -57
- package/dist/server.d.mts +3 -4
- package/dist/server.d.ts +3 -4
- package/dist/server.js +12 -11
- package/dist/server.mjs +6 -5
- package/dist/styles.css +2 -2
- package/dist/testing/msw.d.mts +2 -2
- package/dist/testing/msw.d.ts +2 -2
- package/dist/testing/msw.js +4 -4
- package/dist/testing/msw.mjs +3 -3
- package/dist/testing/suite.d.mts +5 -6
- package/dist/testing/suite.d.ts +5 -6
- package/dist/testing/suite.js +29 -28
- package/dist/testing/suite.mjs +10 -9
- package/dist/testing.d.mts +2217 -14
- package/dist/testing.d.ts +2217 -14
- package/dist/testing.js +173 -83
- package/dist/testing.mjs +28 -10
- package/dist/utils.d.mts +3 -4
- package/dist/utils.d.ts +3 -4
- package/dist/utils.js +35 -31
- package/dist/utils.mjs +2 -2
- package/package.json +9 -9
- package/registry/chat-widget.json +1 -1
- package/registry/order-history.json +1 -1
- package/registry/order-summary.json +1 -1
- package/dist/link-cuNVYc2s.d.mts +0 -297
- package/dist/link-cuNVYc2s.d.ts +0 -297
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkXREIZ56K_js = require('./chunk-XREIZ56K.js');
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var chunkEV2EVOYS_js = require('./chunk-EV2EVOYS.js');
|
|
5
|
+
var chunkSFUJMS5E_js = require('./chunk-SFUJMS5E.js');
|
|
6
6
|
var chunkOWW5GUSB_js = require('./chunk-OWW5GUSB.js');
|
|
7
7
|
|
|
8
|
-
// ../node_modules/.bun/hono@4.
|
|
8
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/compose.js
|
|
9
9
|
var compose = (middleware, onError, onNotFound) => {
|
|
10
10
|
return (context, next) => {
|
|
11
11
|
let index = -1;
|
|
@@ -49,21 +49,46 @@ var compose = (middleware, onError, onNotFound) => {
|
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
// ../node_modules/.bun/hono@4.
|
|
52
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/request/constants.js
|
|
53
53
|
var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
|
|
54
54
|
|
|
55
|
-
// ../node_modules/.bun/hono@4.
|
|
55
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/buffer.js
|
|
56
|
+
var bufferToFormData = (arrayBuffer, contentType) => {
|
|
57
|
+
const response = new Response(arrayBuffer, {
|
|
58
|
+
headers: {
|
|
59
|
+
// Normalize the media type (case-insensitive) while keeping parameters like the boundary
|
|
60
|
+
"Content-Type": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return response.formData();
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/body.js
|
|
67
|
+
var isRawRequest = (request) => "headers" in request;
|
|
56
68
|
var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
|
|
57
69
|
const { all = false, dot = false } = options;
|
|
58
|
-
const headers = request
|
|
70
|
+
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
|
59
71
|
const contentType = headers.get("Content-Type");
|
|
60
|
-
|
|
72
|
+
const mediaType = contentType?.split(";")[0].trim().toLowerCase();
|
|
73
|
+
if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
|
|
61
74
|
return parseFormData(request, { all, dot });
|
|
62
75
|
}
|
|
63
76
|
return {};
|
|
64
77
|
};
|
|
65
78
|
async function parseFormData(request, options) {
|
|
66
|
-
|
|
79
|
+
if (!isRawRequest(request) && request.bodyCache.formData) {
|
|
80
|
+
return convertFormDataToBodyData(
|
|
81
|
+
await request.bodyCache.formData,
|
|
82
|
+
options
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
|
86
|
+
const arrayBuffer = await request.arrayBuffer();
|
|
87
|
+
const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
|
|
88
|
+
if (!isRawRequest(request)) {
|
|
89
|
+
request.bodyCache.formData = formDataPromise;
|
|
90
|
+
}
|
|
91
|
+
const formData = await formDataPromise;
|
|
67
92
|
if (formData) {
|
|
68
93
|
return convertFormDataToBodyData(formData, options);
|
|
69
94
|
}
|
|
@@ -123,7 +148,7 @@ var handleParsingNestedValues = (form, key, value) => {
|
|
|
123
148
|
});
|
|
124
149
|
};
|
|
125
150
|
|
|
126
|
-
// ../node_modules/.bun/hono@4.
|
|
151
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/url.js
|
|
127
152
|
var splitPath = (path) => {
|
|
128
153
|
const paths = path.split("/");
|
|
129
154
|
if (paths[0] === "") {
|
|
@@ -229,13 +254,13 @@ var checkOptionalParameter = (path) => {
|
|
|
229
254
|
if (segment !== "" && !/\:/.test(segment)) {
|
|
230
255
|
basePath += "/" + segment;
|
|
231
256
|
} else if (/\:/.test(segment)) {
|
|
232
|
-
if (
|
|
257
|
+
if (segment.charCodeAt(segment.length - 1) === 63) {
|
|
233
258
|
if (results.length === 0 && basePath === "") {
|
|
234
259
|
results.push("/");
|
|
235
260
|
} else {
|
|
236
261
|
results.push(basePath);
|
|
237
262
|
}
|
|
238
|
-
const optionalSegment = segment.
|
|
263
|
+
const optionalSegment = segment.slice(0, -1);
|
|
239
264
|
basePath += "/" + optionalSegment;
|
|
240
265
|
results.push(basePath);
|
|
241
266
|
} else {
|
|
@@ -245,18 +270,16 @@ var checkOptionalParameter = (path) => {
|
|
|
245
270
|
});
|
|
246
271
|
return results.filter((v, i, a) => a.indexOf(v) === i);
|
|
247
272
|
};
|
|
273
|
+
var tryDecodeURIComponent = (str) => str.indexOf("%") !== -1 ? tryDecode(str, decodeURIComponent_) : str;
|
|
248
274
|
var _decodeURI = (value) => {
|
|
249
|
-
if (!/[%+]/.test(value)) {
|
|
250
|
-
return value;
|
|
251
|
-
}
|
|
252
275
|
if (value.indexOf("+") !== -1) {
|
|
253
276
|
value = value.replace(/\+/g, " ");
|
|
254
277
|
}
|
|
255
|
-
return
|
|
278
|
+
return tryDecodeURIComponent(value);
|
|
256
279
|
};
|
|
257
280
|
var _getQueryParam = (url, key, multiple) => {
|
|
258
281
|
let encoded;
|
|
259
|
-
if (!multiple && key &&
|
|
282
|
+
if (!multiple && key && key.indexOf("%") === -1 && key.indexOf("+") === -1) {
|
|
260
283
|
let keyIndex2 = url.indexOf("?", 8);
|
|
261
284
|
if (keyIndex2 === -1) {
|
|
262
285
|
return void 0;
|
|
@@ -280,7 +303,7 @@ var _getQueryParam = (url, key, multiple) => {
|
|
|
280
303
|
return void 0;
|
|
281
304
|
}
|
|
282
305
|
}
|
|
283
|
-
const results =
|
|
306
|
+
const results = /* @__PURE__ */ Object.create(null);
|
|
284
307
|
encoded ?? (encoded = /[%+]/.test(url));
|
|
285
308
|
let keyIndex = url.indexOf("?", 8);
|
|
286
309
|
while (keyIndex !== -1) {
|
|
@@ -326,8 +349,7 @@ var getQueryParams = (url, key) => {
|
|
|
326
349
|
};
|
|
327
350
|
var decodeURIComponent_ = decodeURIComponent;
|
|
328
351
|
|
|
329
|
-
// ../node_modules/.bun/hono@4.
|
|
330
|
-
var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
|
|
352
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/request.js
|
|
331
353
|
var _validatedData, _matchResult, _HonoRequest_instances, getDecodedParam_fn, getAllDecodedParams_fn, getParamValue_fn, _cachedBody, _a;
|
|
332
354
|
var HonoRequest = (_a = class {
|
|
333
355
|
constructor(request, path = "/", matchResult = [[]]) {
|
|
@@ -371,8 +393,7 @@ var HonoRequest = (_a = class {
|
|
|
371
393
|
if (cachedBody) {
|
|
372
394
|
return cachedBody;
|
|
373
395
|
}
|
|
374
|
-
const anyCachedKey
|
|
375
|
-
if (anyCachedKey) {
|
|
396
|
+
for (const anyCachedKey in bodyCache) {
|
|
376
397
|
return bodyCache[anyCachedKey].then((body) => {
|
|
377
398
|
if (anyCachedKey === "json") {
|
|
378
399
|
body = JSON.stringify(body);
|
|
@@ -385,7 +406,6 @@ var HonoRequest = (_a = class {
|
|
|
385
406
|
this.raw = request;
|
|
386
407
|
this.path = path;
|
|
387
408
|
chunkOWW5GUSB_js.__privateSet(this, _matchResult, matchResult);
|
|
388
|
-
chunkOWW5GUSB_js.__privateSet(this, _validatedData, {});
|
|
389
409
|
}
|
|
390
410
|
param(key) {
|
|
391
411
|
return key ? chunkOWW5GUSB_js.__privateMethod(this, _HonoRequest_instances, getDecodedParam_fn).call(this, key) : chunkOWW5GUSB_js.__privateMethod(this, _HonoRequest_instances, getAllDecodedParams_fn).call(this);
|
|
@@ -400,7 +420,7 @@ var HonoRequest = (_a = class {
|
|
|
400
420
|
if (name) {
|
|
401
421
|
return this.raw.headers.get(name) ?? void 0;
|
|
402
422
|
}
|
|
403
|
-
const headerData =
|
|
423
|
+
const headerData = /* @__PURE__ */ Object.create(null);
|
|
404
424
|
this.raw.headers.forEach((value, key) => {
|
|
405
425
|
headerData[key] = value;
|
|
406
426
|
});
|
|
@@ -502,10 +522,10 @@ var HonoRequest = (_a = class {
|
|
|
502
522
|
* @param data - The validated data to add.
|
|
503
523
|
*/
|
|
504
524
|
addValidatedData(target, data) {
|
|
505
|
-
chunkOWW5GUSB_js.__privateGet(this, _validatedData)[target] = data;
|
|
525
|
+
(chunkOWW5GUSB_js.__privateGet(this, _validatedData) ?? chunkOWW5GUSB_js.__privateSet(this, _validatedData, {}))[target] = data;
|
|
506
526
|
}
|
|
507
527
|
valid(target) {
|
|
508
|
-
return chunkOWW5GUSB_js.__privateGet(this, _validatedData)[target];
|
|
528
|
+
return chunkOWW5GUSB_js.__privateGet(this, _validatedData)?.[target];
|
|
509
529
|
}
|
|
510
530
|
/**
|
|
511
531
|
* `.url()` can get the request url strings.
|
|
@@ -593,14 +613,14 @@ var HonoRequest = (_a = class {
|
|
|
593
613
|
}, _validatedData = new WeakMap(), _matchResult = new WeakMap(), _HonoRequest_instances = new WeakSet(), getDecodedParam_fn = function(key) {
|
|
594
614
|
const paramKey = chunkOWW5GUSB_js.__privateGet(this, _matchResult)[0][this.routeIndex][1][key];
|
|
595
615
|
const param = chunkOWW5GUSB_js.__privateMethod(this, _HonoRequest_instances, getParamValue_fn).call(this, paramKey);
|
|
596
|
-
return param &&
|
|
616
|
+
return param && tryDecodeURIComponent(param);
|
|
597
617
|
}, getAllDecodedParams_fn = function() {
|
|
598
618
|
const decoded = {};
|
|
599
619
|
const keys = Object.keys(chunkOWW5GUSB_js.__privateGet(this, _matchResult)[0][this.routeIndex][1]);
|
|
600
620
|
for (const key of keys) {
|
|
601
621
|
const value = chunkOWW5GUSB_js.__privateMethod(this, _HonoRequest_instances, getParamValue_fn).call(this, chunkOWW5GUSB_js.__privateGet(this, _matchResult)[0][this.routeIndex][1][key]);
|
|
602
622
|
if (value !== void 0) {
|
|
603
|
-
decoded[key] =
|
|
623
|
+
decoded[key] = tryDecodeURIComponent(value);
|
|
604
624
|
}
|
|
605
625
|
}
|
|
606
626
|
return decoded;
|
|
@@ -608,7 +628,7 @@ var HonoRequest = (_a = class {
|
|
|
608
628
|
return chunkOWW5GUSB_js.__privateGet(this, _matchResult)[1] ? chunkOWW5GUSB_js.__privateGet(this, _matchResult)[1][paramKey] : paramKey;
|
|
609
629
|
}, _cachedBody = new WeakMap(), _a);
|
|
610
630
|
|
|
611
|
-
// ../node_modules/.bun/hono@4.
|
|
631
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/html.js
|
|
612
632
|
var HtmlEscapedCallbackPhase = {
|
|
613
633
|
Stringify: 1};
|
|
614
634
|
var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
|
|
@@ -639,7 +659,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
|
|
|
639
659
|
}
|
|
640
660
|
};
|
|
641
661
|
|
|
642
|
-
// ../node_modules/.bun/hono@4.
|
|
662
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/context.js
|
|
643
663
|
var TEXT_PLAIN = "text/plain; charset=UTF-8";
|
|
644
664
|
var setDefaultContentType = (contentType, headers) => {
|
|
645
665
|
return {
|
|
@@ -1012,11 +1032,11 @@ var Context = (_a2 = class {
|
|
|
1012
1032
|
return Object.fromEntries(chunkOWW5GUSB_js.__privateGet(this, _var));
|
|
1013
1033
|
}
|
|
1014
1034
|
}, _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) {
|
|
1015
|
-
|
|
1016
|
-
if (typeof arg === "object" &&
|
|
1017
|
-
|
|
1018
|
-
for (const [key, value] of
|
|
1019
|
-
if (key
|
|
1035
|
+
let responseHeaders = chunkOWW5GUSB_js.__privateGet(this, _res) ? new Headers(chunkOWW5GUSB_js.__privateGet(this, _res).headers) : chunkOWW5GUSB_js.__privateGet(this, _preparedHeaders);
|
|
1036
|
+
if (typeof arg === "object" && arg.headers) {
|
|
1037
|
+
responseHeaders ?? (responseHeaders = new Headers());
|
|
1038
|
+
for (const [key, value] of new Headers(arg.headers)) {
|
|
1039
|
+
if (key === "set-cookie") {
|
|
1020
1040
|
responseHeaders.append(key, value);
|
|
1021
1041
|
} else {
|
|
1022
1042
|
responseHeaders.set(key, value);
|
|
@@ -1024,33 +1044,48 @@ var Context = (_a2 = class {
|
|
|
1024
1044
|
}
|
|
1025
1045
|
}
|
|
1026
1046
|
if (headers) {
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1047
|
+
if (!responseHeaders) {
|
|
1048
|
+
let count = 0;
|
|
1049
|
+
for (const k in headers) {
|
|
1050
|
+
if (++count > 1 || typeof headers[k] !== "string") {
|
|
1051
|
+
responseHeaders = new Headers();
|
|
1052
|
+
break;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
if (responseHeaders) {
|
|
1057
|
+
for (const k in headers) {
|
|
1058
|
+
const v = headers[k];
|
|
1059
|
+
if (typeof v === "string") {
|
|
1060
|
+
responseHeaders.set(k, v);
|
|
1061
|
+
} else {
|
|
1062
|
+
responseHeaders.delete(k);
|
|
1063
|
+
for (const v2 of v) {
|
|
1064
|
+
responseHeaders.append(k, v2);
|
|
1065
|
+
}
|
|
1034
1066
|
}
|
|
1035
1067
|
}
|
|
1036
1068
|
}
|
|
1037
1069
|
}
|
|
1038
1070
|
const status = typeof arg === "number" ? arg : arg?.status ?? chunkOWW5GUSB_js.__privateGet(this, _status);
|
|
1039
|
-
return createResponseInstance(data, {
|
|
1071
|
+
return createResponseInstance(data, {
|
|
1072
|
+
status,
|
|
1073
|
+
headers: responseHeaders ?? headers
|
|
1074
|
+
});
|
|
1040
1075
|
}, _a2);
|
|
1041
1076
|
|
|
1042
|
-
// ../node_modules/.bun/hono@4.
|
|
1077
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router.js
|
|
1043
1078
|
var METHOD_NAME_ALL = "ALL";
|
|
1044
1079
|
var METHOD_NAME_ALL_LOWERCASE = "all";
|
|
1045
|
-
var METHODS = ["get", "post", "put", "delete", "options", "patch"];
|
|
1080
|
+
var METHODS = ["get", "post", "put", "delete", "options", "patch", "query"];
|
|
1046
1081
|
var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
|
|
1047
1082
|
var UnsupportedPathError = class extends Error {
|
|
1048
1083
|
};
|
|
1049
1084
|
|
|
1050
|
-
// ../node_modules/.bun/hono@4.
|
|
1085
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/utils/constants.js
|
|
1051
1086
|
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
|
1052
1087
|
|
|
1053
|
-
// ../node_modules/.bun/hono@4.
|
|
1088
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/hono-base.js
|
|
1054
1089
|
var notFoundHandler = (c) => {
|
|
1055
1090
|
return c.text("404 Not Found", 404);
|
|
1056
1091
|
};
|
|
@@ -1072,6 +1107,7 @@ var Hono = (_a3 = class {
|
|
|
1072
1107
|
chunkOWW5GUSB_js.__publicField(this, "delete");
|
|
1073
1108
|
chunkOWW5GUSB_js.__publicField(this, "options");
|
|
1074
1109
|
chunkOWW5GUSB_js.__publicField(this, "patch");
|
|
1110
|
+
chunkOWW5GUSB_js.__publicField(this, "query");
|
|
1075
1111
|
chunkOWW5GUSB_js.__publicField(this, "all");
|
|
1076
1112
|
chunkOWW5GUSB_js.__publicField(this, "on");
|
|
1077
1113
|
chunkOWW5GUSB_js.__publicField(this, "use");
|
|
@@ -1133,8 +1169,8 @@ var Hono = (_a3 = class {
|
|
|
1133
1169
|
* @see {@link https://hono.dev/docs/api/hono#fetch}
|
|
1134
1170
|
*
|
|
1135
1171
|
* @param {Request} request - request Object of request
|
|
1136
|
-
* @param {Env}
|
|
1137
|
-
* @param {ExecutionContext} - context of execution
|
|
1172
|
+
* @param {Env} env - env Object
|
|
1173
|
+
* @param {ExecutionContext} executionCtx - context of execution
|
|
1138
1174
|
* @returns {Response | Promise<Response>} response of request
|
|
1139
1175
|
*
|
|
1140
1176
|
*/
|
|
@@ -1425,7 +1461,7 @@ var Hono = (_a3 = class {
|
|
|
1425
1461
|
})();
|
|
1426
1462
|
}, _a3);
|
|
1427
1463
|
|
|
1428
|
-
// ../node_modules/.bun/hono@4.
|
|
1464
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/matcher.js
|
|
1429
1465
|
var emptyParam = [];
|
|
1430
1466
|
function match(method, path) {
|
|
1431
1467
|
const matchers = this.buildAllMatchers();
|
|
@@ -1446,7 +1482,7 @@ function match(method, path) {
|
|
|
1446
1482
|
return match2(method, path);
|
|
1447
1483
|
}
|
|
1448
1484
|
|
|
1449
|
-
// ../node_modules/.bun/hono@4.
|
|
1485
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/node.js
|
|
1450
1486
|
var LABEL_REG_EXP_STR = "[^/]+";
|
|
1451
1487
|
var ONLY_WILDCARD_REG_EXP_STR = ".*";
|
|
1452
1488
|
var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
|
|
@@ -1460,7 +1496,7 @@ function compareKey(a, b) {
|
|
|
1460
1496
|
return 1;
|
|
1461
1497
|
}
|
|
1462
1498
|
if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
|
|
1463
|
-
return 1;
|
|
1499
|
+
return b === TAIL_WILDCARD_REG_EXP_STR ? -1 : 1;
|
|
1464
1500
|
} else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
|
|
1465
1501
|
return -1;
|
|
1466
1502
|
}
|
|
@@ -1474,77 +1510,76 @@ function compareKey(a, b) {
|
|
|
1474
1510
|
var _index, _varIndex, _children, _a4;
|
|
1475
1511
|
var Node = (_a4 = class {
|
|
1476
1512
|
constructor() {
|
|
1513
|
+
// handler index of a dynamic path, or -1 for a static path terminal
|
|
1477
1514
|
chunkOWW5GUSB_js.__privateAdd(this, _index);
|
|
1478
1515
|
chunkOWW5GUSB_js.__privateAdd(this, _varIndex);
|
|
1479
1516
|
chunkOWW5GUSB_js.__privateAdd(this, _children, /* @__PURE__ */ Object.create(null));
|
|
1480
1517
|
}
|
|
1481
|
-
insert(tokens, index, paramMap, context,
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
}
|
|
1502
|
-
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
|
1503
|
-
if (/\((?!\?:)/.test(regexpStr)) {
|
|
1504
|
-
throw PATH_ERROR;
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
node = chunkOWW5GUSB_js.__privateGet(this, _children)[regexpStr];
|
|
1508
|
-
if (!node) {
|
|
1509
|
-
if (Object.keys(chunkOWW5GUSB_js.__privateGet(this, _children)).some(
|
|
1510
|
-
(k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
|
|
1511
|
-
)) {
|
|
1512
|
-
throw PATH_ERROR;
|
|
1518
|
+
insert(tokens, index, paramMap, context, isStatic) {
|
|
1519
|
+
let node = this;
|
|
1520
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
1521
|
+
const token = tokens[i];
|
|
1522
|
+
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(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
|
1523
|
+
let nextNode;
|
|
1524
|
+
if (pattern) {
|
|
1525
|
+
const name = pattern[1];
|
|
1526
|
+
let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
|
|
1527
|
+
if (name && pattern[2]) {
|
|
1528
|
+
if (regexpStr === ".*") {
|
|
1529
|
+
throw PATH_ERROR;
|
|
1530
|
+
}
|
|
1531
|
+
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
|
1532
|
+
if (/\((?!\?:)/.test(regexpStr)) {
|
|
1533
|
+
throw PATH_ERROR;
|
|
1534
|
+
}
|
|
1535
|
+
if (regexpStr.length === 1 && regExpMetaChars.has(regexpStr)) {
|
|
1536
|
+
throw PATH_ERROR;
|
|
1537
|
+
}
|
|
1513
1538
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1539
|
+
nextNode = chunkOWW5GUSB_js.__privateGet(node, _children)[regexpStr];
|
|
1540
|
+
if (!nextNode) {
|
|
1541
|
+
if (regexpStr !== ONLY_WILDCARD_REG_EXP_STR && regexpStr !== TAIL_WILDCARD_REG_EXP_STR) {
|
|
1542
|
+
for (const k in chunkOWW5GUSB_js.__privateGet(node, _children)) {
|
|
1543
|
+
if (
|
|
1544
|
+
// a single-char pattern coexists with single-char literals as a literal does
|
|
1545
|
+
(regexpStr.length > 1 || k.length > 1) && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
|
|
1546
|
+
) {
|
|
1547
|
+
throw PATH_ERROR;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
nextNode = chunkOWW5GUSB_js.__privateGet(node, _children)[regexpStr] = new _a4();
|
|
1516
1552
|
}
|
|
1517
|
-
node = chunkOWW5GUSB_js.__privateGet(this, _children)[regexpStr] = new _a4();
|
|
1518
1553
|
if (name !== "") {
|
|
1519
|
-
chunkOWW5GUSB_js.__privateSet(
|
|
1520
|
-
|
|
1521
|
-
}
|
|
1522
|
-
if (!pathErrorCheckOnly && name !== "") {
|
|
1523
|
-
paramMap.push([name, chunkOWW5GUSB_js.__privateGet(node, _varIndex)]);
|
|
1524
|
-
}
|
|
1525
|
-
} else {
|
|
1526
|
-
node = chunkOWW5GUSB_js.__privateGet(this, _children)[token];
|
|
1527
|
-
if (!node) {
|
|
1528
|
-
if (Object.keys(chunkOWW5GUSB_js.__privateGet(this, _children)).some(
|
|
1529
|
-
(k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
|
|
1530
|
-
)) {
|
|
1531
|
-
throw PATH_ERROR;
|
|
1554
|
+
chunkOWW5GUSB_js.__privateGet(nextNode, _varIndex) ?? chunkOWW5GUSB_js.__privateSet(nextNode, _varIndex, context.varIndex++);
|
|
1555
|
+
paramMap.push([name, chunkOWW5GUSB_js.__privateGet(nextNode, _varIndex)]);
|
|
1532
1556
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1557
|
+
} else {
|
|
1558
|
+
nextNode = chunkOWW5GUSB_js.__privateGet(node, _children)[token];
|
|
1559
|
+
if (!nextNode) {
|
|
1560
|
+
for (const k in chunkOWW5GUSB_js.__privateGet(node, _children)) {
|
|
1561
|
+
if (k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR) {
|
|
1562
|
+
throw PATH_ERROR;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
nextNode = chunkOWW5GUSB_js.__privateGet(node, _children)[token] = new _a4();
|
|
1535
1566
|
}
|
|
1536
|
-
node = chunkOWW5GUSB_js.__privateGet(this, _children)[token] = new _a4();
|
|
1537
1567
|
}
|
|
1568
|
+
node = nextNode;
|
|
1569
|
+
}
|
|
1570
|
+
if (chunkOWW5GUSB_js.__privateGet(node, _index) !== void 0) {
|
|
1571
|
+
throw PATH_ERROR;
|
|
1538
1572
|
}
|
|
1539
|
-
|
|
1573
|
+
chunkOWW5GUSB_js.__privateSet(node, _index, isStatic ? -1 : index);
|
|
1540
1574
|
}
|
|
1541
1575
|
buildRegExpStr() {
|
|
1542
1576
|
const childKeys = Object.keys(chunkOWW5GUSB_js.__privateGet(this, _children)).sort(compareKey);
|
|
1543
1577
|
const strList = childKeys.map((k) => {
|
|
1544
1578
|
const c = chunkOWW5GUSB_js.__privateGet(this, _children)[k];
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1579
|
+
const childStr = c.buildRegExpStr();
|
|
1580
|
+
return childStr === "" ? "" : (typeof chunkOWW5GUSB_js.__privateGet(c, _varIndex) === "number" ? `(${k})@${chunkOWW5GUSB_js.__privateGet(c, _varIndex)}` : regExpMetaChars.has(k) ? `\\${k}` : k) + childStr;
|
|
1581
|
+
}).filter(Boolean);
|
|
1582
|
+
if (typeof chunkOWW5GUSB_js.__privateGet(this, _index) === "number" && chunkOWW5GUSB_js.__privateGet(this, _index) !== -1) {
|
|
1548
1583
|
strList.unshift(`#${chunkOWW5GUSB_js.__privateGet(this, _index)}`);
|
|
1549
1584
|
}
|
|
1550
1585
|
if (strList.length === 0) {
|
|
@@ -1557,19 +1592,27 @@ var Node = (_a4 = class {
|
|
|
1557
1592
|
}
|
|
1558
1593
|
}, _index = new WeakMap(), _varIndex = new WeakMap(), _children = new WeakMap(), _a4);
|
|
1559
1594
|
|
|
1560
|
-
// ../node_modules/.bun/hono@4.
|
|
1561
|
-
var _context, _root, _a5;
|
|
1595
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/trie.js
|
|
1596
|
+
var _context, _root, _index2, _a5;
|
|
1562
1597
|
var Trie = (_a5 = class {
|
|
1563
1598
|
constructor() {
|
|
1564
1599
|
chunkOWW5GUSB_js.__privateAdd(this, _context, { varIndex: 0 });
|
|
1565
1600
|
chunkOWW5GUSB_js.__privateAdd(this, _root, new Node());
|
|
1601
|
+
chunkOWW5GUSB_js.__privateAdd(this, _index2, 0);
|
|
1602
|
+
// dynamic path -> [handler index, param assoc]; static paths are not registered
|
|
1603
|
+
chunkOWW5GUSB_js.__publicField(this, "paths", /* @__PURE__ */ Object.create(null));
|
|
1566
1604
|
}
|
|
1567
|
-
insert(path,
|
|
1605
|
+
insert(path, isStatic) {
|
|
1606
|
+
if (isStatic) {
|
|
1607
|
+
chunkOWW5GUSB_js.__privateGet(this, _root).insert(path.split(""), 0, [], chunkOWW5GUSB_js.__privateGet(this, _context), true);
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1568
1610
|
const paramAssoc = [];
|
|
1569
1611
|
const groups = [];
|
|
1612
|
+
let markedPath = path;
|
|
1570
1613
|
for (let i = 0; ; ) {
|
|
1571
1614
|
let replaced = false;
|
|
1572
|
-
|
|
1615
|
+
markedPath = markedPath.replace(/\{[^}]+\}/g, (m) => {
|
|
1573
1616
|
const mark = `@\\${i}`;
|
|
1574
1617
|
groups[i] = [mark, m];
|
|
1575
1618
|
i++;
|
|
@@ -1580,7 +1623,7 @@ var Trie = (_a5 = class {
|
|
|
1580
1623
|
break;
|
|
1581
1624
|
}
|
|
1582
1625
|
}
|
|
1583
|
-
const tokens =
|
|
1626
|
+
const tokens = markedPath.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
|
|
1584
1627
|
for (let i = groups.length - 1; i >= 0; i--) {
|
|
1585
1628
|
const [mark] = groups[i];
|
|
1586
1629
|
for (let j = tokens.length - 1; j >= 0; j--) {
|
|
@@ -1590,8 +1633,8 @@ var Trie = (_a5 = class {
|
|
|
1590
1633
|
}
|
|
1591
1634
|
}
|
|
1592
1635
|
}
|
|
1593
|
-
chunkOWW5GUSB_js.__privateGet(this, _root).insert(tokens,
|
|
1594
|
-
|
|
1636
|
+
chunkOWW5GUSB_js.__privateGet(this, _root).insert(tokens, chunkOWW5GUSB_js.__privateGet(this, _index2), paramAssoc, chunkOWW5GUSB_js.__privateGet(this, _context), false);
|
|
1637
|
+
this.paths[path] = [chunkOWW5GUSB_js.__privateWrapper(this, _index2)._++, paramAssoc];
|
|
1595
1638
|
}
|
|
1596
1639
|
buildRegExp() {
|
|
1597
1640
|
let regexp = chunkOWW5GUSB_js.__privateGet(this, _root).buildRegExpStr();
|
|
@@ -1614,10 +1657,9 @@ var Trie = (_a5 = class {
|
|
|
1614
1657
|
});
|
|
1615
1658
|
return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
|
|
1616
1659
|
}
|
|
1617
|
-
}, _context = new WeakMap(), _root = new WeakMap(), _a5);
|
|
1660
|
+
}, _context = new WeakMap(), _root = new WeakMap(), _index2 = new WeakMap(), _a5);
|
|
1618
1661
|
|
|
1619
|
-
// ../node_modules/.bun/hono@4.
|
|
1620
|
-
var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
|
|
1662
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/reg-exp-router/router.js
|
|
1621
1663
|
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
1622
1664
|
function buildWildcardRegExp(path) {
|
|
1623
1665
|
return wildcardRegExpCache[path] ?? (wildcardRegExpCache[path] = new RegExp(
|
|
@@ -1630,63 +1672,6 @@ function buildWildcardRegExp(path) {
|
|
|
1630
1672
|
function clearWildcardRegExpCache() {
|
|
1631
1673
|
wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
1632
1674
|
}
|
|
1633
|
-
function buildMatcherFromPreprocessedRoutes(routes) {
|
|
1634
|
-
const trie = new Trie();
|
|
1635
|
-
const handlerData = [];
|
|
1636
|
-
if (routes.length === 0) {
|
|
1637
|
-
return nullMatcher;
|
|
1638
|
-
}
|
|
1639
|
-
const routesWithStaticPathFlag = routes.map(
|
|
1640
|
-
(route) => [!/\*|\/:/.test(route[0]), ...route]
|
|
1641
|
-
).sort(
|
|
1642
|
-
([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
|
|
1643
|
-
);
|
|
1644
|
-
const staticMap = /* @__PURE__ */ Object.create(null);
|
|
1645
|
-
for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
|
|
1646
|
-
const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
|
|
1647
|
-
if (pathErrorCheckOnly) {
|
|
1648
|
-
staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
|
|
1649
|
-
} else {
|
|
1650
|
-
j++;
|
|
1651
|
-
}
|
|
1652
|
-
let paramAssoc;
|
|
1653
|
-
try {
|
|
1654
|
-
paramAssoc = trie.insert(path, j, pathErrorCheckOnly);
|
|
1655
|
-
} catch (e) {
|
|
1656
|
-
throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
|
|
1657
|
-
}
|
|
1658
|
-
if (pathErrorCheckOnly) {
|
|
1659
|
-
continue;
|
|
1660
|
-
}
|
|
1661
|
-
handlerData[j] = handlers.map(([h, paramCount]) => {
|
|
1662
|
-
const paramIndexMap = /* @__PURE__ */ Object.create(null);
|
|
1663
|
-
paramCount -= 1;
|
|
1664
|
-
for (; paramCount >= 0; paramCount--) {
|
|
1665
|
-
const [key, value] = paramAssoc[paramCount];
|
|
1666
|
-
paramIndexMap[key] = value;
|
|
1667
|
-
}
|
|
1668
|
-
return [h, paramIndexMap];
|
|
1669
|
-
});
|
|
1670
|
-
}
|
|
1671
|
-
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
1672
|
-
for (let i = 0, len = handlerData.length; i < len; i++) {
|
|
1673
|
-
for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
|
|
1674
|
-
const map = handlerData[i][j]?.[1];
|
|
1675
|
-
if (!map) {
|
|
1676
|
-
continue;
|
|
1677
|
-
}
|
|
1678
|
-
const keys = Object.keys(map);
|
|
1679
|
-
for (let k = 0, len3 = keys.length; k < len3; k++) {
|
|
1680
|
-
map[keys[k]] = paramReplacementMap[map[keys[k]]];
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
const handlerMap = [];
|
|
1685
|
-
for (const i in indexReplacementMap) {
|
|
1686
|
-
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
1687
|
-
}
|
|
1688
|
-
return [regexp, handlerMap, staticMap];
|
|
1689
|
-
}
|
|
1690
1675
|
function findMiddleware(middleware, path) {
|
|
1691
1676
|
if (!middleware) {
|
|
1692
1677
|
return void 0;
|
|
@@ -1698,29 +1683,32 @@ function findMiddleware(middleware, path) {
|
|
|
1698
1683
|
}
|
|
1699
1684
|
return void 0;
|
|
1700
1685
|
}
|
|
1701
|
-
var _middleware, _routes, _RegExpRouter_instances, buildMatcher_fn, _a6;
|
|
1686
|
+
var _middleware, _routes, _tries, _RegExpRouter_instances, insertPath_fn, buildMatcher_fn, _a6;
|
|
1702
1687
|
var RegExpRouter = (_a6 = class {
|
|
1703
1688
|
constructor() {
|
|
1704
1689
|
chunkOWW5GUSB_js.__privateAdd(this, _RegExpRouter_instances);
|
|
1705
1690
|
chunkOWW5GUSB_js.__publicField(this, "name", "RegExpRouter");
|
|
1706
1691
|
chunkOWW5GUSB_js.__privateAdd(this, _middleware);
|
|
1707
1692
|
chunkOWW5GUSB_js.__privateAdd(this, _routes);
|
|
1693
|
+
chunkOWW5GUSB_js.__privateAdd(this, _tries);
|
|
1708
1694
|
chunkOWW5GUSB_js.__publicField(this, "match", match);
|
|
1709
1695
|
chunkOWW5GUSB_js.__privateSet(this, _middleware, { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) });
|
|
1710
1696
|
chunkOWW5GUSB_js.__privateSet(this, _routes, { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) });
|
|
1697
|
+
chunkOWW5GUSB_js.__privateSet(this, _tries, { [METHOD_NAME_ALL]: new Trie() });
|
|
1711
1698
|
}
|
|
1712
1699
|
add(method, path, handler) {
|
|
1713
|
-
var _a10;
|
|
1714
1700
|
const middleware = chunkOWW5GUSB_js.__privateGet(this, _middleware);
|
|
1715
1701
|
const routes = chunkOWW5GUSB_js.__privateGet(this, _routes);
|
|
1716
1702
|
if (!middleware || !routes) {
|
|
1717
1703
|
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
|
1718
1704
|
}
|
|
1719
1705
|
if (!middleware[method]) {
|
|
1706
|
+
chunkOWW5GUSB_js.__privateGet(this, _tries)[method] = new Trie();
|
|
1720
1707
|
[middleware, routes].forEach((handlerMap) => {
|
|
1721
1708
|
handlerMap[method] = /* @__PURE__ */ Object.create(null);
|
|
1722
1709
|
Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
|
|
1723
1710
|
handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
|
|
1711
|
+
chunkOWW5GUSB_js.__privateMethod(this, _RegExpRouter_instances, insertPath_fn).call(this, method, p);
|
|
1724
1712
|
});
|
|
1725
1713
|
});
|
|
1726
1714
|
}
|
|
@@ -1730,14 +1718,12 @@ var RegExpRouter = (_a6 = class {
|
|
|
1730
1718
|
const paramCount = (path.match(/\/:/g) || []).length;
|
|
1731
1719
|
if (/\*$/.test(path)) {
|
|
1732
1720
|
const re = buildWildcardRegExp(path);
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
(_a10 = middleware[method])[path] || (_a10[path] = findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || []);
|
|
1740
|
-
}
|
|
1721
|
+
Object.keys(middleware).forEach((m) => {
|
|
1722
|
+
if ((method === METHOD_NAME_ALL || method === m) && !middleware[m][path]) {
|
|
1723
|
+
chunkOWW5GUSB_js.__privateMethod(this, _RegExpRouter_instances, insertPath_fn).call(this, m, path);
|
|
1724
|
+
middleware[m][path] = findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
|
|
1725
|
+
}
|
|
1726
|
+
});
|
|
1741
1727
|
Object.keys(middleware).forEach((m) => {
|
|
1742
1728
|
if (method === METHOD_NAME_ALL || method === m) {
|
|
1743
1729
|
Object.keys(middleware[m]).forEach((p) => {
|
|
@@ -1758,11 +1744,13 @@ var RegExpRouter = (_a6 = class {
|
|
|
1758
1744
|
for (let i = 0, len = paths.length; i < len; i++) {
|
|
1759
1745
|
const path2 = paths[i];
|
|
1760
1746
|
Object.keys(routes).forEach((m) => {
|
|
1761
|
-
var _a11;
|
|
1762
1747
|
if (method === METHOD_NAME_ALL || method === m) {
|
|
1763
|
-
(
|
|
1764
|
-
|
|
1765
|
-
|
|
1748
|
+
if (!routes[m][path2]) {
|
|
1749
|
+
chunkOWW5GUSB_js.__privateMethod(this, _RegExpRouter_instances, insertPath_fn).call(this, m, path2);
|
|
1750
|
+
routes[m][path2] = [
|
|
1751
|
+
...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
|
|
1752
|
+
];
|
|
1753
|
+
}
|
|
1766
1754
|
routes[m][path2].push([handler, paramCount - len + i + 1]);
|
|
1767
1755
|
}
|
|
1768
1756
|
});
|
|
@@ -1773,32 +1761,63 @@ var RegExpRouter = (_a6 = class {
|
|
|
1773
1761
|
Object.keys(chunkOWW5GUSB_js.__privateGet(this, _routes)).concat(Object.keys(chunkOWW5GUSB_js.__privateGet(this, _middleware))).forEach((method) => {
|
|
1774
1762
|
matchers[method] || (matchers[method] = chunkOWW5GUSB_js.__privateMethod(this, _RegExpRouter_instances, buildMatcher_fn).call(this, method));
|
|
1775
1763
|
});
|
|
1776
|
-
chunkOWW5GUSB_js.__privateSet(this, _middleware, chunkOWW5GUSB_js.__privateSet(this, _routes, void 0));
|
|
1764
|
+
chunkOWW5GUSB_js.__privateSet(this, _middleware, chunkOWW5GUSB_js.__privateSet(this, _routes, chunkOWW5GUSB_js.__privateSet(this, _tries, void 0)));
|
|
1777
1765
|
clearWildcardRegExpCache();
|
|
1778
1766
|
return matchers;
|
|
1779
1767
|
}
|
|
1780
|
-
}, _middleware = new WeakMap(), _routes = new WeakMap(), _RegExpRouter_instances = new WeakSet(),
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1768
|
+
}, _middleware = new WeakMap(), _routes = new WeakMap(), _tries = new WeakMap(), _RegExpRouter_instances = new WeakSet(), insertPath_fn = function(method, path) {
|
|
1769
|
+
try {
|
|
1770
|
+
chunkOWW5GUSB_js.__privateGet(this, _tries)[method].insert(path, !/\*|\/:/.test(path));
|
|
1771
|
+
} catch (e) {
|
|
1772
|
+
throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
|
|
1773
|
+
}
|
|
1774
|
+
}, buildMatcher_fn = function(method) {
|
|
1775
|
+
const middleware = chunkOWW5GUSB_js.__privateGet(this, _middleware)[method];
|
|
1776
|
+
const routes = chunkOWW5GUSB_js.__privateGet(this, _routes)[method];
|
|
1777
|
+
const trie = chunkOWW5GUSB_js.__privateGet(this, _tries)[method];
|
|
1778
|
+
const staticMap = /* @__PURE__ */ Object.create(null);
|
|
1779
|
+
const handlerData = [];
|
|
1780
|
+
[middleware, routes].forEach((r) => {
|
|
1781
|
+
for (const path in r) {
|
|
1782
|
+
const handlers = r[path];
|
|
1783
|
+
const pathData = trie.paths[path];
|
|
1784
|
+
if (!pathData) {
|
|
1785
|
+
staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
|
|
1786
|
+
continue;
|
|
1787
|
+
}
|
|
1788
|
+
const paramAssoc = pathData[1];
|
|
1789
|
+
handlerData[pathData[0]] = handlers.map(([h, paramCount]) => {
|
|
1790
|
+
const paramIndexMap = /* @__PURE__ */ Object.create(null);
|
|
1791
|
+
paramCount -= 1;
|
|
1792
|
+
for (; paramCount >= 0; paramCount--) {
|
|
1793
|
+
const [key, value] = paramAssoc[paramCount];
|
|
1794
|
+
paramIndexMap[key] = value;
|
|
1795
|
+
}
|
|
1796
|
+
return [h, paramIndexMap];
|
|
1797
|
+
});
|
|
1792
1798
|
}
|
|
1793
1799
|
});
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1800
|
+
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
1801
|
+
for (let i = 0, len = handlerData.length; i < len; i++) {
|
|
1802
|
+
for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
|
|
1803
|
+
const map = handlerData[i][j]?.[1];
|
|
1804
|
+
if (!map) {
|
|
1805
|
+
continue;
|
|
1806
|
+
}
|
|
1807
|
+
const keys = Object.keys(map);
|
|
1808
|
+
for (let k = 0, len3 = keys.length; k < len3; k++) {
|
|
1809
|
+
map[keys[k]] = paramReplacementMap[map[keys[k]]];
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
const handlerMap = [];
|
|
1814
|
+
for (const i in indexReplacementMap) {
|
|
1815
|
+
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
1798
1816
|
}
|
|
1817
|
+
return [regexp, handlerMap, staticMap];
|
|
1799
1818
|
}, _a6);
|
|
1800
1819
|
|
|
1801
|
-
// ../node_modules/.bun/hono@4.
|
|
1820
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/smart-router/router.js
|
|
1802
1821
|
var _routers, _routes2, _a7;
|
|
1803
1822
|
var SmartRouter = (_a7 = class {
|
|
1804
1823
|
constructor(init) {
|
|
@@ -1854,7 +1873,7 @@ var SmartRouter = (_a7 = class {
|
|
|
1854
1873
|
}
|
|
1855
1874
|
}, _routers = new WeakMap(), _routes2 = new WeakMap(), _a7);
|
|
1856
1875
|
|
|
1857
|
-
// ../node_modules/.bun/hono@4.
|
|
1876
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/trie-router/node.js
|
|
1858
1877
|
var emptyParams = /* @__PURE__ */ Object.create(null);
|
|
1859
1878
|
var hasChildren = (children) => {
|
|
1860
1879
|
for (const _ in children) {
|
|
@@ -1971,9 +1990,12 @@ var Node2 = (_a8 = class {
|
|
|
1971
1990
|
if (m) {
|
|
1972
1991
|
params[name] = m[0];
|
|
1973
1992
|
chunkOWW5GUSB_js.__privateMethod(this, __Node_instances, pushHandlerSets_fn).call(this, handlerSets, child, method, chunkOWW5GUSB_js.__privateGet(node, _params), params);
|
|
1993
|
+
if (m[0].length === restPathString.length && chunkOWW5GUSB_js.__privateGet(child, _children2)["*"]) {
|
|
1994
|
+
chunkOWW5GUSB_js.__privateMethod(this, __Node_instances, pushHandlerSets_fn).call(this, handlerSets, chunkOWW5GUSB_js.__privateGet(child, _children2)["*"], method, chunkOWW5GUSB_js.__privateGet(node, _params), params);
|
|
1995
|
+
}
|
|
1974
1996
|
if (hasChildren(chunkOWW5GUSB_js.__privateGet(child, _children2))) {
|
|
1975
1997
|
chunkOWW5GUSB_js.__privateSet(child, _params, params);
|
|
1976
|
-
const componentCount = m[0].match(/\//)?.length ?? 0;
|
|
1998
|
+
const componentCount = m[0].match(/\//g)?.length ?? 0;
|
|
1977
1999
|
const targetCurNodes = curNodesQueue[componentCount] || (curNodesQueue[componentCount] = []);
|
|
1978
2000
|
targetCurNodes.push(child);
|
|
1979
2001
|
}
|
|
@@ -2024,7 +2046,7 @@ var Node2 = (_a8 = class {
|
|
|
2024
2046
|
}
|
|
2025
2047
|
}, _a8);
|
|
2026
2048
|
|
|
2027
|
-
// ../node_modules/.bun/hono@4.
|
|
2049
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/router/trie-router/router.js
|
|
2028
2050
|
var _node, _a9;
|
|
2029
2051
|
var TrieRouter = (_a9 = class {
|
|
2030
2052
|
constructor() {
|
|
@@ -2047,7 +2069,7 @@ var TrieRouter = (_a9 = class {
|
|
|
2047
2069
|
}
|
|
2048
2070
|
}, _node = new WeakMap(), _a9);
|
|
2049
2071
|
|
|
2050
|
-
// ../node_modules/.bun/hono@4.
|
|
2072
|
+
// ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/hono.js
|
|
2051
2073
|
var Hono2 = class extends Hono {
|
|
2052
2074
|
/**
|
|
2053
2075
|
* Creates an instance of the Hono class.
|
|
@@ -2078,8 +2100,8 @@ var MockError = class extends Error {
|
|
|
2078
2100
|
};
|
|
2079
2101
|
}
|
|
2080
2102
|
};
|
|
2081
|
-
var notFound = (msg) => new MockError(
|
|
2082
|
-
var validation = (msg, ctx) => new MockError(
|
|
2103
|
+
var notFound = (msg) => new MockError(chunkSFUJMS5E_js.ErrorCode.NOT_FOUND, msg, 404);
|
|
2104
|
+
var validation = (msg, ctx) => new MockError(chunkSFUJMS5E_js.ErrorCode.VALIDATION_ERROR, msg, 400, ctx);
|
|
2083
2105
|
|
|
2084
2106
|
// src/mock/routes/_helpers.ts
|
|
2085
2107
|
function authMiddleware(deps) {
|
|
@@ -2092,7 +2114,7 @@ function authMiddleware(deps) {
|
|
|
2092
2114
|
await next();
|
|
2093
2115
|
};
|
|
2094
2116
|
}
|
|
2095
|
-
var IDEMPOTENT_PATH_RE = /\/(cart\/items|cart\/coupons|checkout|payments\/authorization|auth\/(request-otp|verify-otp|profile|logout))(\/|$)/;
|
|
2117
|
+
var IDEMPOTENT_PATH_RE = /\/(cart\/items|cart\/coupons|checkout|purchase-intents|payments\/authorization|auth\/(request-otp|verify-otp|profile|logout))(\/|$)/;
|
|
2096
2118
|
var IDEMPOTENCY_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2097
2119
|
function idempotencyMiddleware(deps) {
|
|
2098
2120
|
return async (c, next) => {
|
|
@@ -2102,7 +2124,8 @@ function idempotencyMiddleware(deps) {
|
|
|
2102
2124
|
const key = c.req.header("idempotency-key") ?? c.req.header("Idempotency-Key");
|
|
2103
2125
|
if (!key || key.length > 200) return next();
|
|
2104
2126
|
const session = c.var.session;
|
|
2105
|
-
const
|
|
2127
|
+
const routeScope = c.req.path.includes("/purchase-intents") ? `:${c.req.path}` : "";
|
|
2128
|
+
const recordId = `${session.id}${routeScope}:${key}`;
|
|
2106
2129
|
const existing = deps.registry.idempotency.get(recordId);
|
|
2107
2130
|
if (existing) {
|
|
2108
2131
|
const expiresAt = Date.parse(existing.expires_at);
|
|
@@ -2176,6 +2199,21 @@ function getQueryNum(c, key) {
|
|
|
2176
2199
|
}
|
|
2177
2200
|
|
|
2178
2201
|
// src/mock/routes/v1.ts
|
|
2202
|
+
var PURCHASE_INTENT_ROUTE = {
|
|
2203
|
+
COLLECTION: "/purchase-intents",
|
|
2204
|
+
MEMBER: "/purchase-intents/:intent_id",
|
|
2205
|
+
REFRESH: "/purchase-intents/:intent_id/refresh",
|
|
2206
|
+
CONFIRM: "/purchase-intents/:intent_id/confirm",
|
|
2207
|
+
ACTION: "/purchase-intents/:intent_id/attempts/:attempt_id/actions"
|
|
2208
|
+
};
|
|
2209
|
+
var PURCHASE_INTENT_ROUTE_PARAM = {
|
|
2210
|
+
INTENT_ID: "intent_id",
|
|
2211
|
+
ATTEMPT_ID: "attempt_id"
|
|
2212
|
+
};
|
|
2213
|
+
var PAYMENT_ROUTE = {
|
|
2214
|
+
COLLECTION_OPTIONS: "/payments/collection-options",
|
|
2215
|
+
AUTHORIZATION: "/payments/authorization"
|
|
2216
|
+
};
|
|
2179
2217
|
function buildV1(deps) {
|
|
2180
2218
|
const app = new Hono2();
|
|
2181
2219
|
app.use("*", chaosMiddleware(deps));
|
|
@@ -2437,6 +2475,36 @@ function buildV1(deps) {
|
|
|
2437
2475
|
"/catalogue/quotes/:quote_id/refresh",
|
|
2438
2476
|
(c) => tryRoute(c, () => deps.catalogue.refreshQuote(c.req.param("quote_id")))
|
|
2439
2477
|
);
|
|
2478
|
+
app.get("/reviews/summary", (c) => {
|
|
2479
|
+
const productId = c.req.query("product_id");
|
|
2480
|
+
if (productId !== void 0 && (productId.length === 0 || productId.trim() !== productId)) {
|
|
2481
|
+
return fail(c, validation("product_id must be a non-empty canonical identifier"));
|
|
2482
|
+
}
|
|
2483
|
+
const response = {
|
|
2484
|
+
data: {
|
|
2485
|
+
ratings: {
|
|
2486
|
+
product_id: productId ?? null,
|
|
2487
|
+
review_count: 0,
|
|
2488
|
+
rating_sum: 0,
|
|
2489
|
+
average_rating: null,
|
|
2490
|
+
distribution: { one: 0, two: 0, three: 0, four: 0, five: 0 }
|
|
2491
|
+
},
|
|
2492
|
+
trust_chips: {
|
|
2493
|
+
on_time_delivery_percent: null,
|
|
2494
|
+
delivery_sample_size: 0,
|
|
2495
|
+
average_first_response_seconds: null,
|
|
2496
|
+
support_sample_size: 0
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
};
|
|
2500
|
+
return c.json(response);
|
|
2501
|
+
});
|
|
2502
|
+
app.get("/reviews", (c) => {
|
|
2503
|
+
const response = {
|
|
2504
|
+
data: { items: [], next_cursor: null }
|
|
2505
|
+
};
|
|
2506
|
+
return c.json(response);
|
|
2507
|
+
});
|
|
2440
2508
|
app.get("/cart", (c) => tryRoute(c, () => deps.cart.toUICart(deps.cart.get(c.var.session))));
|
|
2441
2509
|
app.delete("/cart", (c) => tryRoute(c, () => deps.cart.clear(c.var.session)));
|
|
2442
2510
|
app.get("/cart/items", (c) => tryRoute(c, () => deps.cart.getItems(c.var.session)));
|
|
@@ -2518,28 +2586,81 @@ function buildV1(deps) {
|
|
|
2518
2586
|
"/subscriptions/:subscription_id/skip",
|
|
2519
2587
|
(c) => tryRoute(c, () => deps.subscriptions.skipNext(c.req.param("subscription_id")))
|
|
2520
2588
|
);
|
|
2521
|
-
app.get(
|
|
2589
|
+
app.get(PAYMENT_ROUTE.COLLECTION_OPTIONS, async (c) => {
|
|
2522
2590
|
const currency = c.req.query("currency")?.trim().toUpperCase();
|
|
2523
2591
|
if (!currency || !/^[A-Z]{3}$/.test(currency)) {
|
|
2524
2592
|
return fail(c, validation("currency must be a canonical three-letter code"));
|
|
2525
2593
|
}
|
|
2526
2594
|
return tryRoute(c, () => ({
|
|
2527
2595
|
presentment_currency: currency,
|
|
2528
|
-
options: currency ===
|
|
2529
|
-
{ method:
|
|
2530
|
-
{
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2596
|
+
options: currency === chunkEV2EVOYS_js.DEFAULT_CURRENCY ? [
|
|
2597
|
+
{ method: chunkEV2EVOYS_js.PAYMENT_METHOD.CARD, network: null },
|
|
2598
|
+
{
|
|
2599
|
+
method: chunkEV2EVOYS_js.PAYMENT_METHOD.MOBILE_MONEY,
|
|
2600
|
+
network: chunkSFUJMS5E_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.MTN
|
|
2601
|
+
},
|
|
2602
|
+
{
|
|
2603
|
+
method: chunkEV2EVOYS_js.PAYMENT_METHOD.MOBILE_MONEY,
|
|
2604
|
+
network: chunkSFUJMS5E_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.TELECEL
|
|
2605
|
+
},
|
|
2606
|
+
{
|
|
2607
|
+
method: chunkEV2EVOYS_js.PAYMENT_METHOD.MOBILE_MONEY,
|
|
2608
|
+
network: chunkSFUJMS5E_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.AIRTEL
|
|
2609
|
+
}
|
|
2610
|
+
] : currency === "USD" ? [{ method: chunkEV2EVOYS_js.PAYMENT_METHOD.CARD, network: null }] : []
|
|
2534
2611
|
}));
|
|
2535
2612
|
});
|
|
2536
|
-
app.post(
|
|
2613
|
+
app.post(PURCHASE_INTENT_ROUTE.COLLECTION, async (c) => {
|
|
2614
|
+
const body = await c.req.json().catch(() => ({}));
|
|
2615
|
+
return tryRoute(c, () => deps.purchaseIntents.mint(c.var.session, body));
|
|
2616
|
+
});
|
|
2617
|
+
app.get(
|
|
2618
|
+
PURCHASE_INTENT_ROUTE.MEMBER,
|
|
2619
|
+
(c) => tryRoute(
|
|
2620
|
+
c,
|
|
2621
|
+
() => deps.purchaseIntents.get(
|
|
2622
|
+
c.var.session,
|
|
2623
|
+
c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID)
|
|
2624
|
+
)
|
|
2625
|
+
)
|
|
2626
|
+
);
|
|
2627
|
+
app.post(PURCHASE_INTENT_ROUTE.REFRESH, async (c) => {
|
|
2628
|
+
const body = await c.req.json().catch(() => ({}));
|
|
2629
|
+
return tryRoute(
|
|
2630
|
+
c,
|
|
2631
|
+
() => deps.purchaseIntents.refresh(
|
|
2632
|
+
c.var.session,
|
|
2633
|
+
c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID),
|
|
2634
|
+
body.expected_intent_revision
|
|
2635
|
+
)
|
|
2636
|
+
);
|
|
2637
|
+
});
|
|
2638
|
+
app.post(PURCHASE_INTENT_ROUTE.CONFIRM, async (c) => {
|
|
2639
|
+
const body = await c.req.json().catch(() => ({}));
|
|
2640
|
+
return tryRoute(
|
|
2641
|
+
c,
|
|
2642
|
+
() => deps.purchaseIntents.confirm(
|
|
2643
|
+
c.var.session,
|
|
2644
|
+
c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID),
|
|
2645
|
+
body
|
|
2646
|
+
)
|
|
2647
|
+
);
|
|
2648
|
+
});
|
|
2649
|
+
app.post(PURCHASE_INTENT_ROUTE.ACTION, async (c) => {
|
|
2537
2650
|
const body = await c.req.json().catch(() => ({}));
|
|
2538
|
-
return tryRoute(
|
|
2651
|
+
return tryRoute(
|
|
2652
|
+
c,
|
|
2653
|
+
() => deps.purchaseIntents.submitAction(
|
|
2654
|
+
c.var.session,
|
|
2655
|
+
c.req.param(PURCHASE_INTENT_ROUTE_PARAM.INTENT_ID),
|
|
2656
|
+
c.req.param(PURCHASE_INTENT_ROUTE_PARAM.ATTEMPT_ID),
|
|
2657
|
+
body
|
|
2658
|
+
)
|
|
2659
|
+
);
|
|
2539
2660
|
});
|
|
2540
|
-
app.post(
|
|
2661
|
+
app.post(PAYMENT_ROUTE.AUTHORIZATION, async (c) => {
|
|
2541
2662
|
const body = await c.req.json().catch(() => ({}));
|
|
2542
|
-
return tryRoute(c, () => deps.
|
|
2663
|
+
return tryRoute(c, () => deps.payments.authorize(body));
|
|
2543
2664
|
});
|
|
2544
2665
|
app.get("/auth/status", (c) => tryRoute(c, () => deps.auth.status(c.var.session.token)));
|
|
2545
2666
|
app.post("/auth/request-otp", async (c) => {
|
|
@@ -2845,6 +2966,7 @@ function createStateRegistry() {
|
|
|
2845
2966
|
collections: createMemoryStore(),
|
|
2846
2967
|
carts: createMemoryStore(),
|
|
2847
2968
|
orders: createMemoryStore(),
|
|
2969
|
+
purchaseIntents: createMemoryStore(),
|
|
2848
2970
|
subscriptions: createMemoryStore(),
|
|
2849
2971
|
bookings: createMemoryStore(),
|
|
2850
2972
|
services: createMemoryStore(),
|
|
@@ -2994,9 +3116,9 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
2994
3116
|
// injected into the HTML page served by the mock. Edit this file directly \u2014
|
|
2995
3117
|
// type-check via tsgo + the IframeToParentMessage shape from the SDK.
|
|
2996
3118
|
(function () {
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3119
|
+
const TYPE = window.__CIMPLIFY_MOCK_ELEMENT__;
|
|
3120
|
+
const DEFAULT_BUSINESS = window.__CIMPLIFY_MOCK_BUSINESS__;
|
|
3121
|
+
const MSG = {
|
|
3000
3122
|
INIT: "init", SET_TOKEN: "set_token", SET_CART: "set_cart", GET_DATA: "get_data",
|
|
3001
3123
|
REFRESH_TOKEN: "refresh_token", LOGOUT: "logout",
|
|
3002
3124
|
PROCESS_CHECKOUT: "process_checkout", ABORT_CHECKOUT: "abort_checkout",
|
|
@@ -3009,12 +3131,36 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3009
3131
|
CHECKOUT_STATUS: "checkout_status", CHECKOUT_COMPLETE: "checkout_complete",
|
|
3010
3132
|
ORDER_TYPE_CHANGED: "order_type_changed", REQUEST_SUBMIT: "request_submit"
|
|
3011
3133
|
};
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3134
|
+
const PURCHASE_INTENT = {
|
|
3135
|
+
PATH: "/api/v1/purchase-intents",
|
|
3136
|
+
ORDER_CREATED: "order_created",
|
|
3137
|
+
CARD_POPUP_REQUIRED: "card_popup_required",
|
|
3138
|
+
AUTHORIZATION_REQUIRED: "authorization_required",
|
|
3139
|
+
ELIGIBLE: "eligible"
|
|
3140
|
+
};
|
|
3141
|
+
const CHECKOUT_STATUS = {
|
|
3142
|
+
PROCESSING: "processing",
|
|
3143
|
+
SUCCESS: "success",
|
|
3144
|
+
FAILED: "failed"
|
|
3145
|
+
};
|
|
3146
|
+
const CHECKOUT_ERROR = { FAILED: "CHECKOUT_FAILED" };
|
|
3147
|
+
const ORDER_STATUS = { CONFIRMED: "confirmed" };
|
|
3148
|
+
const TENDER = {
|
|
3149
|
+
CARD: "card",
|
|
3150
|
+
MOBILE_MONEY: "mobile_money",
|
|
3151
|
+
AUTHORITY_TRANSIENT: "transient",
|
|
3152
|
+
MTN: "mtn"
|
|
3153
|
+
};
|
|
3154
|
+
const PAYMENT_PROVIDER = { PAYSTACK: "paystack" };
|
|
3155
|
+
const SOURCE_KIND = { CART: "cart" };
|
|
3156
|
+
const AUTHORIZATION = { OTP: "otp" };
|
|
3157
|
+
const EXACT_ZERO_MONEY = /^[+-]?0+(?:\\.0+)?(?:[eE][+-]?\\d+)?$/;
|
|
3158
|
+
const qs = new URLSearchParams(location.search);
|
|
3159
|
+
const AUTO = qs.get("auto") === "true";
|
|
3160
|
+
const DEMO_OTP = qs.get("otp") || "123456";
|
|
3161
|
+
const ORIGIN = qs.get("origin") || "*";
|
|
3162
|
+
const NONCE = qs.get("nonce");
|
|
3163
|
+
const state = {
|
|
3018
3164
|
businessId: DEFAULT_BUSINESS,
|
|
3019
3165
|
token: null,
|
|
3020
3166
|
cart: null,
|
|
@@ -3025,15 +3171,33 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3025
3171
|
contact: null,
|
|
3026
3172
|
pendingOtp: null
|
|
3027
3173
|
};
|
|
3028
|
-
|
|
3029
|
-
|
|
3174
|
+
const content = document.getElementById("content");
|
|
3175
|
+
const title = document.getElementById("title");
|
|
3030
3176
|
|
|
3031
3177
|
function send(msg) {
|
|
3032
3178
|
if (NONCE) msg.nonce = NONCE;
|
|
3033
3179
|
parent.postMessage(msg, ORIGIN);
|
|
3034
3180
|
}
|
|
3181
|
+
function isExactlyZeroMoney(value) {
|
|
3182
|
+
return typeof value === "number"
|
|
3183
|
+
? Object.is(value, 0) || Object.is(value, -0)
|
|
3184
|
+
: EXACT_ZERO_MONEY.test(String(value).trim());
|
|
3185
|
+
}
|
|
3035
3186
|
function reportHeight() { send({ type: MSG.HEIGHT_CHANGE, height: document.documentElement.scrollHeight }); }
|
|
3036
3187
|
function ready() { send({ type: MSG.READY, height: document.documentElement.scrollHeight }); }
|
|
3188
|
+
function responseWithBody(response) {
|
|
3189
|
+
return response.json().then(function (body) {
|
|
3190
|
+
return { status: response.status, body: body };
|
|
3191
|
+
});
|
|
3192
|
+
}
|
|
3193
|
+
function assertSuccessfulResponse(response, fallbackMessage) {
|
|
3194
|
+
if (response.status >= 400) {
|
|
3195
|
+
throw new Error(
|
|
3196
|
+
(response.body && response.body.error && response.body.error.message) || fallbackMessage
|
|
3197
|
+
);
|
|
3198
|
+
}
|
|
3199
|
+
return response.body;
|
|
3200
|
+
}
|
|
3037
3201
|
|
|
3038
3202
|
function defaultAddress() {
|
|
3039
3203
|
return {
|
|
@@ -3043,9 +3207,20 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3043
3207
|
};
|
|
3044
3208
|
}
|
|
3045
3209
|
function defaultPayment(type) {
|
|
3046
|
-
if (type ===
|
|
3047
|
-
|
|
3048
|
-
|
|
3210
|
+
if (type === TENDER.CARD) {
|
|
3211
|
+
return {
|
|
3212
|
+
type: TENDER.CARD,
|
|
3213
|
+
provider: PAYMENT_PROVIDER.PAYSTACK,
|
|
3214
|
+
last_four: "4242",
|
|
3215
|
+
label: "Visa \u2022\u2022\u2022\u2022 4242"
|
|
3216
|
+
};
|
|
3217
|
+
}
|
|
3218
|
+
return {
|
|
3219
|
+
type: TENDER.MOBILE_MONEY,
|
|
3220
|
+
provider: TENDER.MTN,
|
|
3221
|
+
phone_number: "+233244000000",
|
|
3222
|
+
label: "MTN Mobile Money"
|
|
3223
|
+
};
|
|
3049
3224
|
}
|
|
3050
3225
|
|
|
3051
3226
|
function renderAuth() {
|
|
@@ -3070,12 +3245,12 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3070
3245
|
' <div class="option" data-key="lagos">5 Allen Ave, Ikeja, Lagos</div>' +
|
|
3071
3246
|
'</div>' +
|
|
3072
3247
|
'<button id="confirm">Use this address</button>';
|
|
3073
|
-
|
|
3248
|
+
const options = {
|
|
3074
3249
|
"default": defaultAddress(),
|
|
3075
3250
|
"east-legon": { street_address: "8 Ring Road", city: "Accra", region: "Greater Accra", country: "GH", latitude: 5.65, longitude: -0.16 },
|
|
3076
3251
|
"lagos": { street_address: "5 Allen Avenue", city: "Lagos", region: "Lagos", country: "NG", latitude: 6.5244, longitude: 3.3792 }
|
|
3077
3252
|
};
|
|
3078
|
-
|
|
3253
|
+
let picked = "default";
|
|
3079
3254
|
Array.prototype.forEach.call(document.querySelectorAll(".option"), function (el) {
|
|
3080
3255
|
el.onclick = function () {
|
|
3081
3256
|
picked = el.getAttribute("data-key");
|
|
@@ -3098,10 +3273,9 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3098
3273
|
'<div class="options" id="pay-options">' +
|
|
3099
3274
|
' <div class="option selected" data-method="mobile_money">\u{1F4F1} MTN Mobile Money</div>' +
|
|
3100
3275
|
' <div class="option" data-method="card">\u{1F4B3} Card (Paystack)</div>' +
|
|
3101
|
-
' <div class="option" data-method="cash">\u{1F4B5} Cash on delivery</div>' +
|
|
3102
3276
|
'</div>' +
|
|
3103
3277
|
'<button id="confirm">Use this method</button>';
|
|
3104
|
-
|
|
3278
|
+
let picked = TENDER.MOBILE_MONEY;
|
|
3105
3279
|
Array.prototype.forEach.call(document.querySelectorAll(".option"), function (el) {
|
|
3106
3280
|
el.onclick = function () {
|
|
3107
3281
|
picked = el.getAttribute("data-method");
|
|
@@ -3145,7 +3319,6 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3145
3319
|
'</div>' +
|
|
3146
3320
|
'<label>Payment method</label>' +
|
|
3147
3321
|
'<select id="pay-method">' +
|
|
3148
|
-
' <option value="cash">Cash</option>' +
|
|
3149
3322
|
' <option value="mobile_money">Mobile Money (MTN)</option>' +
|
|
3150
3323
|
' <option value="card">Card (Paystack)</option>' +
|
|
3151
3324
|
'</select>' +
|
|
@@ -3162,65 +3335,139 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3162
3335
|
}
|
|
3163
3336
|
|
|
3164
3337
|
function runCheckout() {
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3338
|
+
const statusEl = document.getElementById("status");
|
|
3339
|
+
const errEl = document.getElementById("err");
|
|
3340
|
+
const resultEl = document.getElementById("result");
|
|
3168
3341
|
if (errEl) errEl.textContent = "";
|
|
3169
3342
|
if (!state.cart) { errEl.textContent = "No cart provided"; return; }
|
|
3170
|
-
|
|
3343
|
+
const customer = {
|
|
3171
3344
|
name: document.getElementById("cust-name").value.trim() || "Customer",
|
|
3172
3345
|
email: document.getElementById("cust-email").value.trim() || "noemail@example.com",
|
|
3173
3346
|
phone: document.getElementById("cust-phone").value.trim() || "+233000000000",
|
|
3174
3347
|
save_details: false
|
|
3175
3348
|
};
|
|
3176
|
-
|
|
3177
|
-
|
|
3349
|
+
const paymentMethod = document.getElementById("pay-method").value;
|
|
3350
|
+
const orderType = document.getElementById("order-type").value;
|
|
3178
3351
|
statusEl.textContent = "Processing\u2026";
|
|
3179
|
-
send({ type: MSG.CHECKOUT_STATUS, status:
|
|
3352
|
+
send({ type: MSG.CHECKOUT_STATUS, status: CHECKOUT_STATUS.PROCESSING, context: {} });
|
|
3180
3353
|
|
|
3181
|
-
|
|
3354
|
+
const headers = { "content-type": "application/json" };
|
|
3182
3355
|
if (state.token) headers["x-session-token"] = state.token;
|
|
3183
3356
|
|
|
3184
|
-
|
|
3357
|
+
const preference = paymentMethod === TENDER.MOBILE_MONEY
|
|
3358
|
+
? {
|
|
3359
|
+
method_kind: TENDER.MOBILE_MONEY,
|
|
3360
|
+
authority: {
|
|
3361
|
+
authority_kind: TENDER.AUTHORITY_TRANSIENT,
|
|
3362
|
+
phone_number: customer.phone,
|
|
3363
|
+
network: TENDER.MTN
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
: { method_kind: TENDER.CARD };
|
|
3367
|
+
const intentKey = "mock-element:" + state.cart.id;
|
|
3368
|
+
fetch(PURCHASE_INTENT.PATH, {
|
|
3185
3369
|
method: "POST",
|
|
3186
3370
|
headers: headers,
|
|
3187
3371
|
body: JSON.stringify({
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3372
|
+
client_intent_key: intentKey,
|
|
3373
|
+
source: { kind: SOURCE_KIND.CART, cart_id: state.cart.id },
|
|
3374
|
+
checkout: {
|
|
3375
|
+
customer: customer,
|
|
3376
|
+
order_type: orderType,
|
|
3377
|
+
address_info: state.address || {},
|
|
3378
|
+
tender_preference: preference
|
|
3379
|
+
}
|
|
3193
3380
|
})
|
|
3194
3381
|
})
|
|
3195
|
-
.then(
|
|
3382
|
+
.then(responseWithBody)
|
|
3196
3383
|
.then(function (resp) {
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3384
|
+
const intent = assertSuccessfulResponse(resp, "Intent creation failed");
|
|
3385
|
+
const terms = intent.current_terms;
|
|
3386
|
+
const option = terms && terms.payment_options && terms.payment_options.filter(function (candidate) {
|
|
3387
|
+
return candidate.status === PURCHASE_INTENT.ELIGIBLE && candidate.method_kind === preference.method_kind;
|
|
3388
|
+
})[0];
|
|
3389
|
+
if (!terms || (!option && !isExactlyZeroMoney(terms.money.rail_amount))) {
|
|
3390
|
+
throw new Error("No eligible payment option");
|
|
3391
|
+
}
|
|
3392
|
+
const confirmationPath = PURCHASE_INTENT.PATH + "/" + encodeURIComponent(intent.id) + "/confirm";
|
|
3393
|
+
const confirmationBody = JSON.stringify({
|
|
3394
|
+
accepted_intent_revision: terms.intent_revision,
|
|
3395
|
+
accepted_terms_version: terms.terms_version,
|
|
3396
|
+
accepted_due_now: terms.money.due_now,
|
|
3397
|
+
accepted_customer_debit_amount: option
|
|
3398
|
+
? option.customer_debit_amount
|
|
3399
|
+
: terms.money.rail_amount,
|
|
3400
|
+
currency: terms.money.currency,
|
|
3401
|
+
payment_option_id: option ? option.id : null,
|
|
3402
|
+
idempotency_key: "mock-confirm:" + intent.id
|
|
3403
|
+
});
|
|
3404
|
+
function confirmIntent() {
|
|
3405
|
+
return fetch(confirmationPath, {
|
|
3406
|
+
method: "POST",
|
|
3407
|
+
headers: headers,
|
|
3408
|
+
body: confirmationBody
|
|
3409
|
+
})
|
|
3410
|
+
.then(responseWithBody)
|
|
3411
|
+
.then(function (response) {
|
|
3412
|
+
return assertSuccessfulResponse(response, "Intent confirmation failed");
|
|
3413
|
+
});
|
|
3414
|
+
}
|
|
3415
|
+
|
|
3416
|
+
return confirmIntent().then(function (outcome) {
|
|
3417
|
+
// This mock has no external provider window. Replaying the exact
|
|
3418
|
+
// idempotent confirmation models the provider-approved callback.
|
|
3419
|
+
return outcome.status === PURCHASE_INTENT.CARD_POPUP_REQUIRED
|
|
3420
|
+
? confirmIntent()
|
|
3421
|
+
: outcome;
|
|
3422
|
+
});
|
|
3423
|
+
})
|
|
3424
|
+
.then(function (outcome) {
|
|
3425
|
+
if (outcome.status !== PURCHASE_INTENT.AUTHORIZATION_REQUIRED) return outcome;
|
|
3426
|
+
return fetch(
|
|
3427
|
+
PURCHASE_INTENT.PATH + "/" + encodeURIComponent(outcome.intent_id) +
|
|
3428
|
+
"/attempts/" + encodeURIComponent(outcome.attempt_id) + "/actions",
|
|
3429
|
+
{
|
|
3430
|
+
method: "POST",
|
|
3431
|
+
headers: headers,
|
|
3432
|
+
body: JSON.stringify({ authorization: { type: AUTHORIZATION.OTP, value: DEMO_OTP } })
|
|
3433
|
+
}
|
|
3434
|
+
)
|
|
3435
|
+
.then(responseWithBody)
|
|
3436
|
+
.then(function (response) {
|
|
3437
|
+
return assertSuccessfulResponse(response, "Authorization failed");
|
|
3438
|
+
});
|
|
3439
|
+
})
|
|
3440
|
+
.then(function (outcome) {
|
|
3441
|
+
if (outcome.status !== PURCHASE_INTENT.ORDER_CREATED) {
|
|
3442
|
+
throw new Error("Checkout requires " + outcome.status.replace(/_/g, " "));
|
|
3203
3443
|
}
|
|
3204
|
-
|
|
3205
|
-
|
|
3444
|
+
send({
|
|
3445
|
+
type: MSG.CHECKOUT_STATUS,
|
|
3446
|
+
status: CHECKOUT_STATUS.SUCCESS,
|
|
3447
|
+
context: { order_id: outcome.order_id }
|
|
3448
|
+
});
|
|
3206
3449
|
send({
|
|
3207
3450
|
type: MSG.CHECKOUT_COMPLETE,
|
|
3208
3451
|
success: true,
|
|
3209
3452
|
order: {
|
|
3210
|
-
id:
|
|
3211
|
-
order_number:
|
|
3212
|
-
status:
|
|
3453
|
+
id: outcome.order_id,
|
|
3454
|
+
order_number: outcome.order_number || outcome.order_id,
|
|
3455
|
+
status: ORDER_STATUS.CONFIRMED,
|
|
3213
3456
|
total: (state.cart && state.cart.total_price) || "0.00",
|
|
3214
3457
|
currency: (state.cart && state.cart.currency) || "GHS"
|
|
3215
3458
|
}
|
|
3216
3459
|
});
|
|
3217
|
-
statusEl.textContent = "Success \u2014 order " +
|
|
3460
|
+
statusEl.textContent = "Success \u2014 order " + outcome.order_id;
|
|
3218
3461
|
resultEl.style.display = "block";
|
|
3219
|
-
resultEl.textContent = JSON.stringify(
|
|
3462
|
+
resultEl.textContent = JSON.stringify(outcome, null, 2);
|
|
3220
3463
|
})
|
|
3221
3464
|
.catch(function (e) {
|
|
3222
|
-
send({
|
|
3223
|
-
|
|
3465
|
+
send({
|
|
3466
|
+
type: MSG.CHECKOUT_COMPLETE,
|
|
3467
|
+
success: false,
|
|
3468
|
+
error: { code: CHECKOUT_ERROR.FAILED, message: String(e), recoverable: true }
|
|
3469
|
+
});
|
|
3470
|
+
statusEl.textContent = "Failed";
|
|
3224
3471
|
errEl.textContent = String(e);
|
|
3225
3472
|
});
|
|
3226
3473
|
}
|
|
@@ -3237,7 +3484,7 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3237
3484
|
break;
|
|
3238
3485
|
case MSG.SET_CART:
|
|
3239
3486
|
state.cart = msg.cart;
|
|
3240
|
-
|
|
3487
|
+
const s = document.getElementById("status");
|
|
3241
3488
|
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");
|
|
3242
3489
|
reportHeight();
|
|
3243
3490
|
break;
|
|
@@ -3261,7 +3508,7 @@ var ELEMENT_HANDLER_JS = `/* eslint-disable */
|
|
|
3261
3508
|
}
|
|
3262
3509
|
break;
|
|
3263
3510
|
case MSG.ABORT_CHECKOUT:
|
|
3264
|
-
send({ type: MSG.CHECKOUT_STATUS, status:
|
|
3511
|
+
send({ type: MSG.CHECKOUT_STATUS, status: CHECKOUT_STATUS.FAILED, context: {} });
|
|
3265
3512
|
break;
|
|
3266
3513
|
}
|
|
3267
3514
|
}
|
|
@@ -3332,9 +3579,10 @@ function buildLink(deps) {
|
|
|
3332
3579
|
app.post("/auth/request-otp", async (c) => {
|
|
3333
3580
|
const body = await c.req.json().catch(() => ({}));
|
|
3334
3581
|
return tryRoute(c, () => {
|
|
3335
|
-
deps.auth.requestOtp(body.contact ?? "");
|
|
3582
|
+
const challenge = deps.auth.requestOtp(body.contact ?? "");
|
|
3336
3583
|
return {
|
|
3337
3584
|
success: true,
|
|
3585
|
+
challenge_id: challenge.otp_id,
|
|
3338
3586
|
message: `OTP sent to ${body.contact ?? "contact"}`,
|
|
3339
3587
|
expires_in: 300,
|
|
3340
3588
|
is_new_account: false
|
|
@@ -3344,7 +3592,11 @@ function buildLink(deps) {
|
|
|
3344
3592
|
app.post("/auth/verify-otp", async (c) => {
|
|
3345
3593
|
const body = await c.req.json().catch(() => ({}));
|
|
3346
3594
|
return tryRoute(c, () => {
|
|
3347
|
-
const session = deps.auth.verifyOtp(
|
|
3595
|
+
const session = deps.auth.verifyOtp(
|
|
3596
|
+
body.contact ?? "",
|
|
3597
|
+
body.otp_code ?? "",
|
|
3598
|
+
body.challenge_id
|
|
3599
|
+
);
|
|
3348
3600
|
c.header("x-session-token", session.token);
|
|
3349
3601
|
const customer = deps.link.ensureCustomer(session.customer_id ?? session.id, {
|
|
3350
3602
|
email: body.contact?.includes("@") ? body.contact : void 0,
|
|
@@ -3438,10 +3690,7 @@ function buildLink(deps) {
|
|
|
3438
3690
|
};
|
|
3439
3691
|
});
|
|
3440
3692
|
});
|
|
3441
|
-
app.get(
|
|
3442
|
-
"/preferences",
|
|
3443
|
-
(c) => tryRoute(c, () => deps.link.getPreferences(customerId(c)))
|
|
3444
|
-
);
|
|
3693
|
+
app.get("/preferences", (c) => tryRoute(c, () => deps.link.getPreferences(customerId(c))));
|
|
3445
3694
|
app.post("/preferences", async (c) => {
|
|
3446
3695
|
const body = await c.req.json().catch(() => ({}));
|
|
3447
3696
|
return tryRoute(c, () => {
|
|
@@ -3873,6 +4122,7 @@ function createAuthService(opts) {
|
|
|
3873
4122
|
token: id,
|
|
3874
4123
|
business_id: options.defaultBusinessId,
|
|
3875
4124
|
is_authenticated: authenticated,
|
|
4125
|
+
account_id: authenticated ? ids.raw("account") : void 0,
|
|
3876
4126
|
customer_id: authenticated ? ids.customer() : void 0,
|
|
3877
4127
|
customer_name: profile?.name,
|
|
3878
4128
|
customer_email: profile?.email,
|
|
@@ -3918,9 +4168,16 @@ function createAuthService(opts) {
|
|
|
3918
4168
|
code_hint: options.mode === "permissive" ? code : void 0
|
|
3919
4169
|
};
|
|
3920
4170
|
},
|
|
3921
|
-
verifyOtp(contact, code) {
|
|
3922
|
-
|
|
3923
|
-
|
|
4171
|
+
verifyOtp(contact, code, challengeId) {
|
|
4172
|
+
let otp = challengeId ? registry.otps.get(challengeId) : void 0;
|
|
4173
|
+
if (!challengeId) {
|
|
4174
|
+
const matching = registry.otps.list((o) => o.contact === contact);
|
|
4175
|
+
otp = matching[matching.length - 1];
|
|
4176
|
+
}
|
|
4177
|
+
if (challengeId) {
|
|
4178
|
+
if (!otp) throw new Error("No OTP challenge found");
|
|
4179
|
+
if (otp.contact !== contact) throw new Error("OTP challenge does not match contact");
|
|
4180
|
+
}
|
|
3924
4181
|
if (options.mode === "strict") {
|
|
3925
4182
|
if (!otp) throw new Error("No OTP requested");
|
|
3926
4183
|
if (otp.code !== code && code !== options.defaultOtp) throw new Error("Invalid OTP");
|
|
@@ -3948,7 +4205,7 @@ function createAuthService(opts) {
|
|
|
3948
4205
|
if (!s) return { is_authenticated: false, user_type: "guest" };
|
|
3949
4206
|
return {
|
|
3950
4207
|
is_authenticated: s.is_authenticated,
|
|
3951
|
-
account_id: s.
|
|
4208
|
+
account_id: s.account_id,
|
|
3952
4209
|
user_type: s.is_authenticated ? "customer" : "guest",
|
|
3953
4210
|
session_expires_at: s.expires_at ? Math.floor(new Date(s.expires_at).getTime() / 1e3) : void 0,
|
|
3954
4211
|
session: s
|
|
@@ -5246,88 +5503,10 @@ function createCartService(opts) {
|
|
|
5246
5503
|
};
|
|
5247
5504
|
}
|
|
5248
5505
|
|
|
5249
|
-
// src/mock/domain/
|
|
5250
|
-
function
|
|
5251
|
-
const { registry, clock,
|
|
5506
|
+
// src/mock/domain/payment.ts
|
|
5507
|
+
function createPaymentService(options) {
|
|
5508
|
+
const { registry, clock, bus } = options;
|
|
5252
5509
|
return {
|
|
5253
|
-
process(session, body) {
|
|
5254
|
-
if (!body.cart_id) throw validation("cart_id required");
|
|
5255
|
-
const c = registry.carts.get(body.cart_id);
|
|
5256
|
-
if (!c) throw notFound(`Cart ${body.cart_id} not found`);
|
|
5257
|
-
if (c.items.length === 0) throw validation("Cart is empty", { code: "CART_EMPTY" });
|
|
5258
|
-
const orderId = ids.order();
|
|
5259
|
-
const orderNumber = ids.orderNumber();
|
|
5260
|
-
const paymentId = ids.payment();
|
|
5261
|
-
const reference = ids.payment();
|
|
5262
|
-
const requiresAuth = body.payment_method === "mobile_money";
|
|
5263
|
-
const isCard = body.payment_method === "card" || body.payment_method === "stripe";
|
|
5264
|
-
const cardProvider = body.payment_method === "stripe" || body.pay_currency?.toUpperCase() === "USD" ? "stripe" : "paystack";
|
|
5265
|
-
const order = {
|
|
5266
|
-
id: orderId,
|
|
5267
|
-
business_id: c.business_id,
|
|
5268
|
-
user_friendly_id: orderNumber,
|
|
5269
|
-
channel: c.channel,
|
|
5270
|
-
status: requiresAuth ? "pending" : "confirmed",
|
|
5271
|
-
payment_state: requiresAuth ? "not_paid" : "paid",
|
|
5272
|
-
order_type: body.order_type,
|
|
5273
|
-
customer_id: session.customer_id,
|
|
5274
|
-
customer_name: body.customer.name,
|
|
5275
|
-
customer_email: body.customer.email,
|
|
5276
|
-
customer_phone: body.customer.phone,
|
|
5277
|
-
delivery_address: body.address_info?.street_address,
|
|
5278
|
-
delivery_fee: c.delivery_fee,
|
|
5279
|
-
subtotal: c.subtotal,
|
|
5280
|
-
tax_amount: c.tax_amount,
|
|
5281
|
-
service_charge: c.service_charge,
|
|
5282
|
-
total_discounts: c.total_discounts,
|
|
5283
|
-
total_price: c.total_price,
|
|
5284
|
-
currency: c.currency,
|
|
5285
|
-
items: c.items,
|
|
5286
|
-
applied_discount_ids: c.applied_discount_ids,
|
|
5287
|
-
applied_discount_codes: c.applied_discount_codes,
|
|
5288
|
-
payment_id: paymentId,
|
|
5289
|
-
payment_reference: reference,
|
|
5290
|
-
metadata: body.metadata,
|
|
5291
|
-
created_at: clock.iso(),
|
|
5292
|
-
updated_at: clock.iso()
|
|
5293
|
-
};
|
|
5294
|
-
registry.orders.put(orderId, order);
|
|
5295
|
-
registry.carts.put(c.id, { ...c, status: "converted", updated_at: clock.iso() });
|
|
5296
|
-
bus.emit("order.created", { order_id: orderId, order_number: orderNumber }, c.business_id);
|
|
5297
|
-
if (!requiresAuth) {
|
|
5298
|
-
bus.emit("order.payment.captured", { order_id: orderId, reference }, c.business_id);
|
|
5299
|
-
bus.emit("order.confirmed", { order_id: orderId }, c.business_id);
|
|
5300
|
-
}
|
|
5301
|
-
const billToken = `bt_${reference.slice(-12)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
5302
|
-
const result = {
|
|
5303
|
-
order_id: orderId,
|
|
5304
|
-
order_number: orderNumber,
|
|
5305
|
-
payment_id: paymentId,
|
|
5306
|
-
payment_status: requiresAuth || isCard ? "pending" : "succeeded",
|
|
5307
|
-
payment_reference: reference,
|
|
5308
|
-
requires_authorization: requiresAuth,
|
|
5309
|
-
authorization_type: requiresAuth ? "otp" : void 0,
|
|
5310
|
-
next_action: requiresAuth ? {
|
|
5311
|
-
type: "authorization",
|
|
5312
|
-
authorization_type: "otp",
|
|
5313
|
-
display_text: "Approve on your mobile money app"
|
|
5314
|
-
} : { type: "none" },
|
|
5315
|
-
provider: isCard ? cardProvider : body.payment_method,
|
|
5316
|
-
bill_token: billToken
|
|
5317
|
-
};
|
|
5318
|
-
if (isCard) {
|
|
5319
|
-
const proc = globalThis.process;
|
|
5320
|
-
result.client_secret = cardProvider === "stripe" ? `pi_${orderId.slice(-12)}_secret_${Math.random().toString(36).slice(2, 18)}` : `access_${reference}`;
|
|
5321
|
-
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";
|
|
5322
|
-
result.next_action = {
|
|
5323
|
-
type: "card_popup",
|
|
5324
|
-
provider: cardProvider,
|
|
5325
|
-
client_secret: result.client_secret,
|
|
5326
|
-
public_key: result.public_key
|
|
5327
|
-
};
|
|
5328
|
-
}
|
|
5329
|
-
return result;
|
|
5330
|
-
},
|
|
5331
5510
|
authorize(body) {
|
|
5332
5511
|
if (!body.payment_id?.trim()) throw validation("payment_id required");
|
|
5333
5512
|
if (!body.authorization) throw validation("authorization required");
|
|
@@ -5338,7 +5517,7 @@ function createCheckoutService(opts) {
|
|
|
5338
5517
|
const updated = {
|
|
5339
5518
|
...order,
|
|
5340
5519
|
payment_state: "paid",
|
|
5341
|
-
status:
|
|
5520
|
+
status: chunkEV2EVOYS_js.CHECKOUT_ORDER_RESULT_STATUS.CONFIRMED,
|
|
5342
5521
|
updated_at: clock.iso()
|
|
5343
5522
|
};
|
|
5344
5523
|
registry.orders.put(order.id, updated);
|
|
@@ -5349,14 +5528,542 @@ function createCheckoutService(opts) {
|
|
|
5349
5528
|
order_number: order.user_friendly_id,
|
|
5350
5529
|
payment_id: body.payment_id,
|
|
5351
5530
|
payment_reference: order.payment_reference,
|
|
5352
|
-
payment_status:
|
|
5531
|
+
payment_status: chunkSFUJMS5E_js.LEGACY_CHECKOUT_PAYMENT_STATUS.SUCCEEDED,
|
|
5353
5532
|
requires_authorization: false,
|
|
5354
|
-
next_action: { type:
|
|
5533
|
+
next_action: { type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.NONE }
|
|
5355
5534
|
};
|
|
5356
5535
|
}
|
|
5357
5536
|
};
|
|
5358
5537
|
}
|
|
5359
5538
|
|
|
5539
|
+
// src/mock/domain/purchase-intent.ts
|
|
5540
|
+
var INTENT_LIFETIME_MS = 15 * 60 * 1e3;
|
|
5541
|
+
var ZERO_MONEY = "0.00";
|
|
5542
|
+
var PURCHASE_INTENT_MOBILE_MONEY_NETWORKS = new Set(
|
|
5543
|
+
Object.values(chunkSFUJMS5E_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK)
|
|
5544
|
+
);
|
|
5545
|
+
var MOCK_PURCHASE_INTENT = {
|
|
5546
|
+
OWNER_KIND: { ACCOUNT: "account", STOREFRONT_SESSION: "storefront_session" },
|
|
5547
|
+
CART_STATUS: { ACTIVE: "active", CONVERTED: "converted" },
|
|
5548
|
+
ORDER_STATUS: { PENDING: "pending", CONFIRMED: "confirmed" },
|
|
5549
|
+
PAYMENT_STATE: { NOT_PAID: "not_paid", PAID: "paid" },
|
|
5550
|
+
EVENT: {
|
|
5551
|
+
ORDER_CREATED: "order.created",
|
|
5552
|
+
PAYMENT_CAPTURED: "order.payment.captured",
|
|
5553
|
+
ORDER_CONFIRMED: "order.confirmed"
|
|
5554
|
+
},
|
|
5555
|
+
ID_PREFIX: { INTENT: "pi", ATTEMPT: "attempt" },
|
|
5556
|
+
DEFAULT_LOCATION_ID: "mock-location",
|
|
5557
|
+
MOCK_PAYSTACK_PUBLIC_KEY: "pk_test_mock_paystack",
|
|
5558
|
+
COMPLIANCE: {
|
|
5559
|
+
POLICY_NAME: "mock-storefront-commerce"
|
|
5560
|
+
}
|
|
5561
|
+
};
|
|
5562
|
+
var DECIMAL_WIRE_VALUE = /^([+-]?)(\d+)(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
|
|
5563
|
+
function isExactlyZero(value) {
|
|
5564
|
+
if (typeof value === "number") return Object.is(value, 0) || Object.is(value, -0);
|
|
5565
|
+
const match2 = DECIMAL_WIRE_VALUE.exec(value.trim());
|
|
5566
|
+
return Boolean(match2 && [...match2[2], ...match2[3] ?? ""].every((digit) => digit === "0"));
|
|
5567
|
+
}
|
|
5568
|
+
function sameDecimal(left, right) {
|
|
5569
|
+
const canonical = (value) => {
|
|
5570
|
+
const wire = typeof value === "number" ? String(value) : value.trim();
|
|
5571
|
+
const match2 = DECIMAL_WIRE_VALUE.exec(wire);
|
|
5572
|
+
if (!match2) return null;
|
|
5573
|
+
let digits = `${match2[2]}${match2[3] ?? ""}`.replace(/^0+/, "");
|
|
5574
|
+
if (!digits) return "0";
|
|
5575
|
+
let scale = BigInt((match2[3] ?? "").length) - BigInt(match2[4] ?? "0");
|
|
5576
|
+
while (digits.endsWith("0")) {
|
|
5577
|
+
digits = digits.slice(0, -1);
|
|
5578
|
+
scale -= 1n;
|
|
5579
|
+
}
|
|
5580
|
+
const sign = match2[1] === "-" ? "-" : "";
|
|
5581
|
+
return `${sign}${digits}:${scale}`;
|
|
5582
|
+
};
|
|
5583
|
+
const normalizedLeft = canonical(left);
|
|
5584
|
+
return normalizedLeft !== null && normalizedLeft === canonical(right);
|
|
5585
|
+
}
|
|
5586
|
+
function wireMoney(value) {
|
|
5587
|
+
return typeof value === "string" ? value.trim() : String(value);
|
|
5588
|
+
}
|
|
5589
|
+
function decimal(value) {
|
|
5590
|
+
return wireMoney(value.toFixed(2));
|
|
5591
|
+
}
|
|
5592
|
+
function paymentOptions(intentId, currency, amount, expiresAt) {
|
|
5593
|
+
const normalizedCurrency = chunkSFUJMS5E_js.currencyCode(currency);
|
|
5594
|
+
const normalizedAmount = wireMoney(amount);
|
|
5595
|
+
return [
|
|
5596
|
+
{
|
|
5597
|
+
id: `${intentId}:${chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.CARD}`,
|
|
5598
|
+
rank: 0,
|
|
5599
|
+
method_kind: chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.CARD,
|
|
5600
|
+
collection_mode: chunkSFUJMS5E_js.PAYMENT_COLLECTION_MODE.CREDENTIAL_CHARGE,
|
|
5601
|
+
provider: chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_PROVIDER.PAYSTACK,
|
|
5602
|
+
principal_amount: normalizedAmount,
|
|
5603
|
+
fee_amount: wireMoney(ZERO_MONEY),
|
|
5604
|
+
customer_debit_amount: normalizedAmount,
|
|
5605
|
+
currency: normalizedCurrency,
|
|
5606
|
+
status: chunkSFUJMS5E_js.PAYMENT_OPTION_STATUS.ELIGIBLE,
|
|
5607
|
+
expected_next_action: chunkSFUJMS5E_js.PAYMENT_OPTION_NEXT_ACTION.PROVIDER_APPROVAL,
|
|
5608
|
+
expires_at: expiresAt
|
|
5609
|
+
},
|
|
5610
|
+
{
|
|
5611
|
+
id: `${intentId}:${chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY}`,
|
|
5612
|
+
rank: 1,
|
|
5613
|
+
method_kind: chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY,
|
|
5614
|
+
collection_mode: chunkSFUJMS5E_js.PAYMENT_COLLECTION_MODE.REQUEST_TO_PAY,
|
|
5615
|
+
provider: chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_PROVIDER.PAYSTACK,
|
|
5616
|
+
principal_amount: normalizedAmount,
|
|
5617
|
+
fee_amount: wireMoney(ZERO_MONEY),
|
|
5618
|
+
customer_debit_amount: normalizedAmount,
|
|
5619
|
+
currency: normalizedCurrency,
|
|
5620
|
+
status: chunkSFUJMS5E_js.PAYMENT_OPTION_STATUS.ELIGIBLE,
|
|
5621
|
+
expected_next_action: chunkSFUJMS5E_js.PAYMENT_OPTION_NEXT_ACTION.PROVIDER_APPROVAL,
|
|
5622
|
+
expires_at: expiresAt
|
|
5623
|
+
}
|
|
5624
|
+
];
|
|
5625
|
+
}
|
|
5626
|
+
function termsForCart(input) {
|
|
5627
|
+
const total = wireMoney(input.total);
|
|
5628
|
+
return {
|
|
5629
|
+
id: `${input.intentId}:terms:${input.version}`,
|
|
5630
|
+
intent_revision: input.revision,
|
|
5631
|
+
terms_version: input.version,
|
|
5632
|
+
terms_digest: `mock:${input.intentId}:${input.revision}:${input.version}`,
|
|
5633
|
+
money: {
|
|
5634
|
+
currency: chunkSFUJMS5E_js.currencyCode(input.currency),
|
|
5635
|
+
subtotal: wireMoney(input.subtotal),
|
|
5636
|
+
discount_total: wireMoney(input.discount),
|
|
5637
|
+
tax_total: wireMoney(input.tax),
|
|
5638
|
+
delivery_total: wireMoney(input.delivery),
|
|
5639
|
+
statutory_total: wireMoney(ZERO_MONEY),
|
|
5640
|
+
total_obligation: total,
|
|
5641
|
+
due_now: total,
|
|
5642
|
+
rail_amount: total,
|
|
5643
|
+
store_credit_consumed: wireMoney(ZERO_MONEY),
|
|
5644
|
+
voucher_credit_consumed: wireMoney(ZERO_MONEY)
|
|
5645
|
+
},
|
|
5646
|
+
material: {
|
|
5647
|
+
line_digest: `mock-lines:${input.intentId}`,
|
|
5648
|
+
destination_digest: `mock-destination:${input.intentId}`,
|
|
5649
|
+
delivery_promise_digest: `mock-delivery:${input.intentId}`,
|
|
5650
|
+
entitlement_digest: `mock-entitlement:${input.intentId}`,
|
|
5651
|
+
cancellation_terms_digest: `mock-cancellation:${input.intentId}`
|
|
5652
|
+
},
|
|
5653
|
+
compliance: {
|
|
5654
|
+
policy_name: MOCK_PURCHASE_INTENT.COMPLIANCE.POLICY_NAME,
|
|
5655
|
+
policy_version: 1,
|
|
5656
|
+
lane: chunkSFUJMS5E_js.CHECKOUT_COMPLIANCE_LANE.NATIVE,
|
|
5657
|
+
reason_code: chunkSFUJMS5E_js.CHECKOUT_COMPLIANCE_REASON.PHYSICAL_GOODS_NATIVE,
|
|
5658
|
+
evidence_digest: `mock-compliance:${input.intentId}`
|
|
5659
|
+
},
|
|
5660
|
+
payment_options: isExactlyZero(input.total) ? [] : paymentOptions(input.intentId, input.currency, input.total, input.validUntil),
|
|
5661
|
+
valid_until: input.validUntil,
|
|
5662
|
+
created_at: input.now
|
|
5663
|
+
};
|
|
5664
|
+
}
|
|
5665
|
+
function intentView(intent) {
|
|
5666
|
+
const {
|
|
5667
|
+
intent_owner: _owner,
|
|
5668
|
+
mint_request: _request,
|
|
5669
|
+
last_confirmation: _confirmation,
|
|
5670
|
+
...view
|
|
5671
|
+
} = intent;
|
|
5672
|
+
return view;
|
|
5673
|
+
}
|
|
5674
|
+
function purchasingPrincipal(session) {
|
|
5675
|
+
if (!session.is_authenticated) {
|
|
5676
|
+
return { kind: chunkSFUJMS5E_js.PURCHASING_PRINCIPAL_KIND.GUEST };
|
|
5677
|
+
}
|
|
5678
|
+
if (!session.account_id) throw validation("Authenticated mock session has no account authority");
|
|
5679
|
+
return {
|
|
5680
|
+
kind: chunkSFUJMS5E_js.PURCHASING_PRINCIPAL_KIND.ACCOUNT,
|
|
5681
|
+
account_id: session.account_id
|
|
5682
|
+
};
|
|
5683
|
+
}
|
|
5684
|
+
function assertSupportedTenderPreference(request) {
|
|
5685
|
+
if (request.source.kind !== chunkSFUJMS5E_js.PURCHASE_INTENT_SOURCE_KIND.CART) return;
|
|
5686
|
+
const checkout = request.checkout;
|
|
5687
|
+
if (!checkout) throw validation("Cart checkout input is required");
|
|
5688
|
+
const preference = checkout.tender_preference;
|
|
5689
|
+
if (preference?.method_kind !== chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY || preference.authority.authority_kind !== chunkSFUJMS5E_js.MOBILE_MONEY_TENDER_AUTHORITY_KIND.TRANSIENT) {
|
|
5690
|
+
return;
|
|
5691
|
+
}
|
|
5692
|
+
if (!PURCHASE_INTENT_MOBILE_MONEY_NETWORKS.has(preference.authority.network)) {
|
|
5693
|
+
throw validation("Mobile Money network is not available for PurchaseIntent checkout");
|
|
5694
|
+
}
|
|
5695
|
+
}
|
|
5696
|
+
function intentOwner(session) {
|
|
5697
|
+
if (!session.is_authenticated) {
|
|
5698
|
+
return { kind: MOCK_PURCHASE_INTENT.OWNER_KIND.STOREFRONT_SESSION, id: session.id };
|
|
5699
|
+
}
|
|
5700
|
+
if (!session.account_id) throw validation("Authenticated mock session has no account authority");
|
|
5701
|
+
return { kind: MOCK_PURCHASE_INTENT.OWNER_KIND.ACCOUNT, id: session.account_id };
|
|
5702
|
+
}
|
|
5703
|
+
function createPurchaseIntentMockService(options) {
|
|
5704
|
+
const { registry, clock, ids, bus } = options;
|
|
5705
|
+
function stored(session, intentId) {
|
|
5706
|
+
const intent = registry.purchaseIntents.get(intentId);
|
|
5707
|
+
if (!intent) throw notFound(`Purchase intent ${intentId} not found`);
|
|
5708
|
+
const owner = intentOwner(session);
|
|
5709
|
+
if (intent.intent_owner.kind !== owner.kind || intent.intent_owner.id !== owner.id) {
|
|
5710
|
+
throw notFound(`Purchase intent ${intentId} not found`);
|
|
5711
|
+
}
|
|
5712
|
+
return intent;
|
|
5713
|
+
}
|
|
5714
|
+
function completeProviderOrder(intent, order, attemptId) {
|
|
5715
|
+
const updated = {
|
|
5716
|
+
...order,
|
|
5717
|
+
payment_state: MOCK_PURCHASE_INTENT.PAYMENT_STATE.PAID,
|
|
5718
|
+
status: MOCK_PURCHASE_INTENT.ORDER_STATUS.CONFIRMED,
|
|
5719
|
+
updated_at: clock.iso()
|
|
5720
|
+
};
|
|
5721
|
+
registry.orders.put(order.id, updated);
|
|
5722
|
+
bus.emit(
|
|
5723
|
+
MOCK_PURCHASE_INTENT.EVENT.PAYMENT_CAPTURED,
|
|
5724
|
+
{ order_id: order.id, reference: order.payment_reference },
|
|
5725
|
+
order.business_id
|
|
5726
|
+
);
|
|
5727
|
+
bus.emit(MOCK_PURCHASE_INTENT.EVENT.ORDER_CONFIRMED, { order_id: order.id }, order.business_id);
|
|
5728
|
+
const completed = {
|
|
5729
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED,
|
|
5730
|
+
intent_id: intent.id,
|
|
5731
|
+
attempt_id: attemptId,
|
|
5732
|
+
order_id: order.id,
|
|
5733
|
+
order_number: order.user_friendly_id,
|
|
5734
|
+
payment_id: order.payment_id
|
|
5735
|
+
};
|
|
5736
|
+
registry.purchaseIntents.put(intent.id, {
|
|
5737
|
+
...intent,
|
|
5738
|
+
updated_at: clock.iso(),
|
|
5739
|
+
last_confirmation: completed
|
|
5740
|
+
});
|
|
5741
|
+
return completed;
|
|
5742
|
+
}
|
|
5743
|
+
return {
|
|
5744
|
+
mint(session, request) {
|
|
5745
|
+
if (!request.client_intent_key.trim()) throw validation("client_intent_key required");
|
|
5746
|
+
if (request.source.kind !== chunkSFUJMS5E_js.PURCHASE_INTENT_SOURCE_KIND.CART) {
|
|
5747
|
+
throw validation("The mock currently prepares cart purchase intents only");
|
|
5748
|
+
}
|
|
5749
|
+
const checkoutInput = request.checkout;
|
|
5750
|
+
if (!checkoutInput) throw validation("Cart checkout input is required");
|
|
5751
|
+
assertSupportedTenderPreference(request);
|
|
5752
|
+
const cart = registry.carts.get(request.source.cart_id);
|
|
5753
|
+
if (!cart) throw notFound(`Cart ${request.source.cart_id} not found`);
|
|
5754
|
+
if (cart.items.length === 0) {
|
|
5755
|
+
throw validation("Cart is empty", { code: chunkSFUJMS5E_js.ErrorCode.CART_EMPTY });
|
|
5756
|
+
}
|
|
5757
|
+
const principal = purchasingPrincipal(session);
|
|
5758
|
+
const owner = intentOwner(session);
|
|
5759
|
+
const existing = registry.purchaseIntents.list(
|
|
5760
|
+
(candidate) => candidate.mint_request.client_intent_key === request.client_intent_key && candidate.intent_owner.kind === owner.kind && candidate.intent_owner.id === owner.id
|
|
5761
|
+
)[0];
|
|
5762
|
+
if (existing) return intentView(existing);
|
|
5763
|
+
const now = clock.iso();
|
|
5764
|
+
const expiresAt = new Date(clock.nowMs() + INTENT_LIFETIME_MS).toISOString();
|
|
5765
|
+
const intentId = ids.raw(MOCK_PURCHASE_INTENT.ID_PREFIX.INTENT);
|
|
5766
|
+
const terms = termsForCart({
|
|
5767
|
+
intentId,
|
|
5768
|
+
revision: 1,
|
|
5769
|
+
version: 1,
|
|
5770
|
+
currency: cart.currency,
|
|
5771
|
+
subtotal: cart.subtotal,
|
|
5772
|
+
discount: cart.total_discounts,
|
|
5773
|
+
tax: cart.tax_amount,
|
|
5774
|
+
delivery: cart.delivery_fee,
|
|
5775
|
+
total: cart.total_price,
|
|
5776
|
+
now,
|
|
5777
|
+
validUntil: expiresAt
|
|
5778
|
+
});
|
|
5779
|
+
const intent = {
|
|
5780
|
+
id: intentId,
|
|
5781
|
+
seller_business_id: cart.business_id,
|
|
5782
|
+
principal,
|
|
5783
|
+
revision: 1,
|
|
5784
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_STATUS.OPEN,
|
|
5785
|
+
source: {
|
|
5786
|
+
kind: chunkSFUJMS5E_js.PURCHASE_INTENT_SOURCE_KIND.CART,
|
|
5787
|
+
source_id: cart.id,
|
|
5788
|
+
source_version: cart.updated_at,
|
|
5789
|
+
seller_business_id: cart.business_id,
|
|
5790
|
+
subject: {
|
|
5791
|
+
kind: chunkSFUJMS5E_js.PURCHASING_PRINCIPAL_KIND.BUSINESS,
|
|
5792
|
+
business_id: cart.business_id
|
|
5793
|
+
},
|
|
5794
|
+
binding_digest: `mock-cart:${cart.id}:${cart.updated_at}`
|
|
5795
|
+
},
|
|
5796
|
+
lines: cart.items.map((line, ordinal) => ({
|
|
5797
|
+
id: line.id,
|
|
5798
|
+
ordinal,
|
|
5799
|
+
sellable: {
|
|
5800
|
+
kind: line.variant_id ? chunkSFUJMS5E_js.PURCHASE_INTENT_SELLABLE_KIND.VARIANT : chunkSFUJMS5E_js.PURCHASE_INTENT_SELLABLE_KIND.PRODUCT,
|
|
5801
|
+
product_id: line.item_id,
|
|
5802
|
+
variant_id: line.variant_id,
|
|
5803
|
+
location_id: checkoutInput.location_id || MOCK_PURCHASE_INTENT.DEFAULT_LOCATION_ID
|
|
5804
|
+
},
|
|
5805
|
+
quantity: line.quantity,
|
|
5806
|
+
configuration: {
|
|
5807
|
+
kind: chunkSFUJMS5E_js.PURCHASE_INTENT_LINE_CONFIGURATION_KIND.SIMPLE,
|
|
5808
|
+
variant_id: line.variant_id,
|
|
5809
|
+
customer_inputs: line.customer_inputs
|
|
5810
|
+
}
|
|
5811
|
+
})),
|
|
5812
|
+
line_pricing: cart.items.map((line) => {
|
|
5813
|
+
const unitPrice = Number(line.price) + Number(line.add_ons_price);
|
|
5814
|
+
const lineSubtotal = unitPrice * line.quantity - Number(line.item_discount_amount);
|
|
5815
|
+
return {
|
|
5816
|
+
intent_line_id: line.id,
|
|
5817
|
+
quantity: line.quantity,
|
|
5818
|
+
unit_price: decimal(unitPrice),
|
|
5819
|
+
line_subtotal: decimal(lineSubtotal),
|
|
5820
|
+
currency: chunkSFUJMS5E_js.currencyCode(cart.currency)
|
|
5821
|
+
};
|
|
5822
|
+
}),
|
|
5823
|
+
current_terms: terms,
|
|
5824
|
+
expires_at: expiresAt,
|
|
5825
|
+
created_at: now,
|
|
5826
|
+
updated_at: now,
|
|
5827
|
+
intent_owner: owner,
|
|
5828
|
+
mint_request: request
|
|
5829
|
+
};
|
|
5830
|
+
registry.purchaseIntents.put(intentId, intent);
|
|
5831
|
+
return intentView(intent);
|
|
5832
|
+
},
|
|
5833
|
+
get(session, intentId) {
|
|
5834
|
+
return intentView(stored(session, intentId));
|
|
5835
|
+
},
|
|
5836
|
+
refresh(session, intentId, expectedRevision) {
|
|
5837
|
+
const intent = stored(session, intentId);
|
|
5838
|
+
if (intent.revision !== expectedRevision) {
|
|
5839
|
+
throw validation("expected_intent_revision does not match current intent revision");
|
|
5840
|
+
}
|
|
5841
|
+
if (!intent.current_terms) throw validation("Purchase intent has no current terms");
|
|
5842
|
+
const previous = intent.current_terms;
|
|
5843
|
+
const nextDelivery = Number(previous.money.delivery_total) + 1;
|
|
5844
|
+
const nextTotal = Number(previous.money.total_obligation) + 1;
|
|
5845
|
+
const now = clock.iso();
|
|
5846
|
+
const replacement = termsForCart({
|
|
5847
|
+
intentId,
|
|
5848
|
+
revision: intent.revision,
|
|
5849
|
+
version: previous.terms_version + 1,
|
|
5850
|
+
currency: previous.money.currency,
|
|
5851
|
+
subtotal: String(previous.money.subtotal),
|
|
5852
|
+
discount: String(previous.money.discount_total),
|
|
5853
|
+
tax: String(previous.money.tax_total),
|
|
5854
|
+
delivery: nextDelivery.toFixed(2),
|
|
5855
|
+
total: nextTotal.toFixed(2),
|
|
5856
|
+
now,
|
|
5857
|
+
validUntil: intent.expires_at
|
|
5858
|
+
});
|
|
5859
|
+
const updated = { ...intent, current_terms: replacement, updated_at: now };
|
|
5860
|
+
registry.purchaseIntents.put(intentId, updated);
|
|
5861
|
+
return intentView(updated);
|
|
5862
|
+
},
|
|
5863
|
+
confirm(session, intentId, request) {
|
|
5864
|
+
const intent = stored(session, intentId);
|
|
5865
|
+
if (intent.status === chunkSFUJMS5E_js.PURCHASE_INTENT_STATUS.CONVERTED && intent.last_confirmation) {
|
|
5866
|
+
const orderId2 = "order_id" in intent.last_confirmation ? intent.last_confirmation.order_id : void 0;
|
|
5867
|
+
const order2 = orderId2 ? registry.orders.get(orderId2) : void 0;
|
|
5868
|
+
if (order2?.payment_state === MOCK_PURCHASE_INTENT.PAYMENT_STATE.PAID) {
|
|
5869
|
+
return {
|
|
5870
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED,
|
|
5871
|
+
intent_id: intent.id,
|
|
5872
|
+
attempt_id: "attempt_id" in intent.last_confirmation ? intent.last_confirmation.attempt_id : ids.raw(MOCK_PURCHASE_INTENT.ID_PREFIX.ATTEMPT),
|
|
5873
|
+
order_id: order2.id
|
|
5874
|
+
};
|
|
5875
|
+
}
|
|
5876
|
+
if (order2?.payment_id && intent.last_confirmation.status === chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED) {
|
|
5877
|
+
return completeProviderOrder(intent, order2, intent.last_confirmation.attempt_id);
|
|
5878
|
+
}
|
|
5879
|
+
return intent.last_confirmation;
|
|
5880
|
+
}
|
|
5881
|
+
const terms = intent.current_terms;
|
|
5882
|
+
if (!terms) throw validation("Purchase intent has no current terms");
|
|
5883
|
+
const zeroRail = isExactlyZero(terms.money.rail_amount);
|
|
5884
|
+
const option = request.payment_option_id ? terms.payment_options.find(
|
|
5885
|
+
(candidate) => candidate.id === request.payment_option_id && candidate.status === chunkSFUJMS5E_js.PAYMENT_OPTION_STATUS.ELIGIBLE
|
|
5886
|
+
) : void 0;
|
|
5887
|
+
const acceptedBaseTermsChanged = !sameDecimal(request.accepted_due_now, terms.money.due_now) || request.currency !== terms.money.currency;
|
|
5888
|
+
if (request.accepted_intent_revision !== intent.revision || request.accepted_terms_version !== terms.terms_version || acceptedBaseTermsChanged) {
|
|
5889
|
+
const deltas = acceptedBaseTermsChanged ? [
|
|
5890
|
+
{
|
|
5891
|
+
kind: chunkSFUJMS5E_js.CHECKOUT_TERMS_DELTA_KIND.MONEY,
|
|
5892
|
+
component: chunkSFUJMS5E_js.CHECKOUT_TERMS_COMPONENT.DUE_NOW,
|
|
5893
|
+
accepted: request.accepted_due_now,
|
|
5894
|
+
replacement: terms.money.due_now
|
|
5895
|
+
}
|
|
5896
|
+
] : [
|
|
5897
|
+
{
|
|
5898
|
+
kind: chunkSFUJMS5E_js.CHECKOUT_TERMS_DELTA_KIND.PAYMENT_OPTION,
|
|
5899
|
+
accepted_option_id: request.payment_option_id ?? null,
|
|
5900
|
+
accepted_customer_debit_amount: request.accepted_customer_debit_amount,
|
|
5901
|
+
replacement_option_id: option?.id ?? null,
|
|
5902
|
+
replacement_customer_debit_amount: option?.customer_debit_amount ?? null
|
|
5903
|
+
}
|
|
5904
|
+
];
|
|
5905
|
+
return {
|
|
5906
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED,
|
|
5907
|
+
intent_id: intent.id,
|
|
5908
|
+
replacement: terms,
|
|
5909
|
+
deltas
|
|
5910
|
+
};
|
|
5911
|
+
}
|
|
5912
|
+
if (!zeroRail && !option || zeroRail && request.payment_option_id != null) {
|
|
5913
|
+
return {
|
|
5914
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.SELECTION_UNAVAILABLE,
|
|
5915
|
+
intent_id: intent.id,
|
|
5916
|
+
lines: intent.lines.map((line) => ({
|
|
5917
|
+
line_id: line.id,
|
|
5918
|
+
reason: chunkSFUJMS5E_js.CHECKOUT_INVALIDATION_REASON.PAYMENT_OPTION_CHANGED
|
|
5919
|
+
}))
|
|
5920
|
+
};
|
|
5921
|
+
}
|
|
5922
|
+
const acceptedCustomerDebitMatches = zeroRail ? isExactlyZero(request.accepted_customer_debit_amount) : Boolean(
|
|
5923
|
+
option && sameDecimal(request.accepted_customer_debit_amount, option.customer_debit_amount)
|
|
5924
|
+
);
|
|
5925
|
+
if (!acceptedCustomerDebitMatches) {
|
|
5926
|
+
return {
|
|
5927
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED,
|
|
5928
|
+
intent_id: intent.id,
|
|
5929
|
+
replacement: terms,
|
|
5930
|
+
deltas: [
|
|
5931
|
+
{
|
|
5932
|
+
kind: chunkSFUJMS5E_js.CHECKOUT_TERMS_DELTA_KIND.PAYMENT_OPTION,
|
|
5933
|
+
accepted_option_id: request.payment_option_id ?? null,
|
|
5934
|
+
accepted_customer_debit_amount: request.accepted_customer_debit_amount,
|
|
5935
|
+
replacement_option_id: option?.id ?? null,
|
|
5936
|
+
replacement_customer_debit_amount: option?.customer_debit_amount ?? null
|
|
5937
|
+
}
|
|
5938
|
+
]
|
|
5939
|
+
};
|
|
5940
|
+
}
|
|
5941
|
+
if (intent.mint_request.source.kind !== chunkSFUJMS5E_js.PURCHASE_INTENT_SOURCE_KIND.CART) {
|
|
5942
|
+
throw validation("The mock currently confirms cart purchase intents only");
|
|
5943
|
+
}
|
|
5944
|
+
const checkoutInput = intent.mint_request.checkout;
|
|
5945
|
+
if (!checkoutInput) throw validation("Cart checkout input is required");
|
|
5946
|
+
const cart = registry.carts.get(intent.mint_request.source.cart_id);
|
|
5947
|
+
if (!cart || cart.status !== MOCK_PURCHASE_INTENT.CART_STATUS.ACTIVE) {
|
|
5948
|
+
return { status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.SOURCE_UNAVAILABLE, intent_id: intent.id };
|
|
5949
|
+
}
|
|
5950
|
+
const attemptId = ids.raw(MOCK_PURCHASE_INTENT.ID_PREFIX.ATTEMPT);
|
|
5951
|
+
const orderId = ids.order();
|
|
5952
|
+
const orderNumber = ids.orderNumber();
|
|
5953
|
+
const paymentId = zeroRail ? void 0 : ids.payment();
|
|
5954
|
+
const paymentReference = zeroRail ? void 0 : ids.payment();
|
|
5955
|
+
const needsProvider = option?.method_kind === chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.CARD || option?.method_kind === chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY;
|
|
5956
|
+
const paid = zeroRail;
|
|
5957
|
+
const order = {
|
|
5958
|
+
id: orderId,
|
|
5959
|
+
business_id: cart.business_id,
|
|
5960
|
+
user_friendly_id: orderNumber,
|
|
5961
|
+
channel: cart.channel,
|
|
5962
|
+
status: paid ? MOCK_PURCHASE_INTENT.ORDER_STATUS.CONFIRMED : MOCK_PURCHASE_INTENT.ORDER_STATUS.PENDING,
|
|
5963
|
+
payment_state: paid ? MOCK_PURCHASE_INTENT.PAYMENT_STATE.PAID : MOCK_PURCHASE_INTENT.PAYMENT_STATE.NOT_PAID,
|
|
5964
|
+
order_type: checkoutInput.order_type,
|
|
5965
|
+
customer_id: session.customer_id,
|
|
5966
|
+
customer_name: checkoutInput.customer.name,
|
|
5967
|
+
customer_email: checkoutInput.customer.email,
|
|
5968
|
+
customer_phone: checkoutInput.customer.phone,
|
|
5969
|
+
delivery_address: checkoutInput.address_info.street_address,
|
|
5970
|
+
delivery_fee: cart.delivery_fee,
|
|
5971
|
+
subtotal: cart.subtotal,
|
|
5972
|
+
tax_amount: cart.tax_amount,
|
|
5973
|
+
service_charge: cart.service_charge,
|
|
5974
|
+
total_discounts: cart.total_discounts,
|
|
5975
|
+
total_price: cart.total_price,
|
|
5976
|
+
currency: cart.currency,
|
|
5977
|
+
items: cart.items,
|
|
5978
|
+
applied_discount_ids: cart.applied_discount_ids,
|
|
5979
|
+
applied_discount_codes: cart.applied_discount_codes,
|
|
5980
|
+
payment_id: paymentId,
|
|
5981
|
+
payment_reference: paymentReference,
|
|
5982
|
+
metadata: checkoutInput.metadata,
|
|
5983
|
+
created_at: clock.iso(),
|
|
5984
|
+
updated_at: clock.iso()
|
|
5985
|
+
};
|
|
5986
|
+
registry.orders.put(orderId, order);
|
|
5987
|
+
registry.carts.put(cart.id, {
|
|
5988
|
+
...cart,
|
|
5989
|
+
status: MOCK_PURCHASE_INTENT.CART_STATUS.CONVERTED,
|
|
5990
|
+
updated_at: clock.iso()
|
|
5991
|
+
});
|
|
5992
|
+
bus.emit(
|
|
5993
|
+
MOCK_PURCHASE_INTENT.EVENT.ORDER_CREATED,
|
|
5994
|
+
{ order_id: orderId, order_number: orderNumber },
|
|
5995
|
+
cart.business_id
|
|
5996
|
+
);
|
|
5997
|
+
if (paid) {
|
|
5998
|
+
if (paymentReference) {
|
|
5999
|
+
bus.emit(
|
|
6000
|
+
MOCK_PURCHASE_INTENT.EVENT.PAYMENT_CAPTURED,
|
|
6001
|
+
{ order_id: orderId, reference: paymentReference },
|
|
6002
|
+
cart.business_id
|
|
6003
|
+
);
|
|
6004
|
+
}
|
|
6005
|
+
bus.emit(
|
|
6006
|
+
MOCK_PURCHASE_INTENT.EVENT.ORDER_CONFIRMED,
|
|
6007
|
+
{ order_id: orderId },
|
|
6008
|
+
cart.business_id
|
|
6009
|
+
);
|
|
6010
|
+
}
|
|
6011
|
+
let confirmation;
|
|
6012
|
+
if (option?.method_kind === chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY) {
|
|
6013
|
+
confirmation = {
|
|
6014
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED,
|
|
6015
|
+
intent_id: intent.id,
|
|
6016
|
+
attempt_id: attemptId,
|
|
6017
|
+
order_id: orderId,
|
|
6018
|
+
authorization_type: chunkEV2EVOYS_js.AUTHORIZATION_TYPE.OTP,
|
|
6019
|
+
display_text: "Approve on your mobile money app"
|
|
6020
|
+
};
|
|
6021
|
+
} else if (option?.method_kind === chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_METHOD.CARD) {
|
|
6022
|
+
confirmation = {
|
|
6023
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED,
|
|
6024
|
+
intent_id: intent.id,
|
|
6025
|
+
attempt_id: attemptId,
|
|
6026
|
+
order_id: orderId,
|
|
6027
|
+
provider: chunkSFUJMS5E_js.PURCHASE_INTENT_PAYMENT_PROVIDER.PAYSTACK,
|
|
6028
|
+
client_secret: `access_${paymentReference}`,
|
|
6029
|
+
public_key: MOCK_PURCHASE_INTENT.MOCK_PAYSTACK_PUBLIC_KEY
|
|
6030
|
+
};
|
|
6031
|
+
} else {
|
|
6032
|
+
confirmation = {
|
|
6033
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED,
|
|
6034
|
+
intent_id: intent.id,
|
|
6035
|
+
attempt_id: attemptId,
|
|
6036
|
+
order_id: orderId
|
|
6037
|
+
};
|
|
6038
|
+
}
|
|
6039
|
+
if (needsProvider && !paymentId) {
|
|
6040
|
+
throw validation("Provider-backed purchase intent has no payment authority");
|
|
6041
|
+
}
|
|
6042
|
+
registry.purchaseIntents.put(intent.id, {
|
|
6043
|
+
...intent,
|
|
6044
|
+
status: chunkSFUJMS5E_js.PURCHASE_INTENT_STATUS.CONVERTED,
|
|
6045
|
+
converted_order_id: orderId,
|
|
6046
|
+
updated_at: clock.iso(),
|
|
6047
|
+
last_confirmation: confirmation
|
|
6048
|
+
});
|
|
6049
|
+
return confirmation;
|
|
6050
|
+
},
|
|
6051
|
+
submitAction(session, intentId, attemptId, request) {
|
|
6052
|
+
const intent = stored(session, intentId);
|
|
6053
|
+
const previous = intent.last_confirmation;
|
|
6054
|
+
if (!previous || previous.status !== chunkSFUJMS5E_js.PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED || previous.attempt_id !== attemptId) {
|
|
6055
|
+
throw validation("Purchase-intent attempt is not awaiting authorization");
|
|
6056
|
+
}
|
|
6057
|
+
if (!request.authorization) throw validation("authorization required");
|
|
6058
|
+
const order = registry.orders.get(previous.order_id);
|
|
6059
|
+
if (!order || !order.payment_id) {
|
|
6060
|
+
throw notFound(`Purchase-intent attempt ${attemptId} not found`);
|
|
6061
|
+
}
|
|
6062
|
+
return completeProviderOrder(intent, order, attemptId);
|
|
6063
|
+
}
|
|
6064
|
+
};
|
|
6065
|
+
}
|
|
6066
|
+
|
|
5360
6067
|
// src/mock/domain/orders.ts
|
|
5361
6068
|
function createOrderService(opts) {
|
|
5362
6069
|
const { registry, clock, bus } = opts;
|
|
@@ -5735,6 +6442,7 @@ function createDeliveryService() {
|
|
|
5735
6442
|
rate_id: "dlvrt_mock_standard",
|
|
5736
6443
|
name: "Standard",
|
|
5737
6444
|
fee: standardFree ? money(0) : money(15),
|
|
6445
|
+
fee_status: "priced",
|
|
5738
6446
|
currency: "GHS",
|
|
5739
6447
|
free_delivery_applied: standardFree,
|
|
5740
6448
|
free_over_amount: money(200),
|
|
@@ -5748,6 +6456,7 @@ function createDeliveryService() {
|
|
|
5748
6456
|
name: "Express",
|
|
5749
6457
|
description: "Delivered within the hour",
|
|
5750
6458
|
fee: money(25),
|
|
6459
|
+
fee_status: "priced",
|
|
5751
6460
|
currency: "GHS",
|
|
5752
6461
|
free_delivery_applied: false,
|
|
5753
6462
|
eta_min_minutes: 30,
|
|
@@ -10644,7 +11353,7 @@ var ID_PREFIX = {
|
|
|
10644
11353
|
product: "prod_",
|
|
10645
11354
|
service: "svc_"
|
|
10646
11355
|
};
|
|
10647
|
-
var
|
|
11356
|
+
var DEFAULT_CURRENCY2 = "GHS";
|
|
10648
11357
|
function slugify(value) {
|
|
10649
11358
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
10650
11359
|
}
|
|
@@ -10679,7 +11388,7 @@ function makeSeedContext(registry) {
|
|
|
10679
11388
|
const business = {
|
|
10680
11389
|
business_type: "other",
|
|
10681
11390
|
email: `hello@${handle}.test`,
|
|
10682
|
-
default_currency:
|
|
11391
|
+
default_currency: DEFAULT_CURRENCY2,
|
|
10683
11392
|
default_offers_table_service: false,
|
|
10684
11393
|
default_accepts_online_orders: true,
|
|
10685
11394
|
status: "active",
|
|
@@ -10858,7 +11567,8 @@ function createDeps(options = {}) {
|
|
|
10858
11567
|
const inventory = createInventoryService({ registry });
|
|
10859
11568
|
const cart = createCartService({ registry, clock, ids, bus, inventory });
|
|
10860
11569
|
const orders = createOrderService({ registry, clock, bus });
|
|
10861
|
-
const
|
|
11570
|
+
const payments = createPaymentService({ registry, clock, bus });
|
|
11571
|
+
const purchaseIntents = createPurchaseIntentMockService({ registry, clock, ids, bus });
|
|
10862
11572
|
const subscriptions = createSubscriptionService({ registry, clock, bus });
|
|
10863
11573
|
const scheduling = createSchedulingService({ registry, clock, bus });
|
|
10864
11574
|
const fx = createFxService({ registry, clock, ids });
|
|
@@ -10879,7 +11589,8 @@ function createDeps(options = {}) {
|
|
|
10879
11589
|
business,
|
|
10880
11590
|
catalogue,
|
|
10881
11591
|
cart,
|
|
10882
|
-
|
|
11592
|
+
payments,
|
|
11593
|
+
purchaseIntents,
|
|
10883
11594
|
orders,
|
|
10884
11595
|
subscriptions,
|
|
10885
11596
|
scheduling,
|