@cimplify/sdk 0.104.0 → 0.105.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-BuLcOWLv.d.ts → catalogue-D1jkpGcr.d.ts} +415 -763
- package/dist/{client-D5AoobFc.d.mts → catalogue-DjutZ0FC.d.mts} +415 -763
- package/dist/{payment-g0HFkEDU.d.mts → checkout-XoV4HNg2.d.mts} +4156 -1498
- package/dist/{payment-g0HFkEDU.d.ts → checkout-XoV4HNg2.d.ts} +4156 -1498
- package/dist/{chunk-GOHSXBKW.mjs → chunk-33VCYWVL.mjs} +25 -1
- package/dist/{chunk-OKADBZAI.mjs → chunk-37ZZCE7P.mjs} +808 -574
- package/dist/{chunk-5BDYDZ4U.js → chunk-3IMPJEUI.js} +892 -657
- package/dist/{chunk-YVAEY3VC.js → chunk-7PMMV5X4.js} +1040 -364
- package/dist/{chunk-H3RATH4B.mjs → chunk-AVXA4F6G.js} +293 -2
- package/dist/{chunk-CNN7Z2IP.js → chunk-EV2EVOYS.js} +27 -0
- package/dist/{chunk-4BKOKHE3.js → chunk-NJYR6GGM.mjs} +244 -19
- package/dist/{chunk-DYIAX3WI.mjs → chunk-NYDVVNZI.mjs} +11 -2
- package/dist/{chunk-E4K2VQDD.js → chunk-PDTXSUHZ.js} +559 -16
- package/dist/{chunk-2WPVUIHX.mjs → chunk-Q5HX7LVE.mjs} +1036 -360
- package/dist/{chunk-5RT4HYMP.mjs → chunk-TINYV5E2.mjs} +542 -15
- package/dist/{chunk-7PDEX54K.js → chunk-UYFTOIFW.js} +13 -3
- package/dist/{chunk-OCCNG6MO.mjs → chunk-X7RPMALQ.mjs} +1310 -722
- package/dist/{chunk-IQFFSKE2.js → chunk-XHVQDEVO.js} +1345 -746
- package/dist/{client-BVNWjk6W.d.ts → client-BBZj15JJ.d.ts} +2 -2
- package/dist/{client-fM716k7G.d.mts → client-CZ8MjJ_o.d.mts} +2 -2
- package/dist/index-CZjNWbQf.d.ts +8 -0
- package/dist/index-DNxWfRHF.d.mts +8 -0
- package/dist/{index-BtcoqrY1.d.ts → index-DRMBo26v.d.mts} +9 -4
- package/dist/{index-D7Tf3v7c.d.mts → index-DweR60Cv.d.ts} +9 -4
- package/dist/index.d.mts +31 -14
- package/dist/index.d.ts +31 -14
- package/dist/index.js +325 -133
- package/dist/index.mjs +6 -6
- package/dist/mock/cli.mjs +1450 -386
- package/dist/mock/library.js +1176 -352
- package/dist/mock/library.mjs +1176 -352
- package/dist/mock/msw.js +1176 -352
- package/dist/mock/msw.mjs +1176 -352
- package/dist/{price-BLIeAb8K.d.ts → price-CUGIYRtD.d.mts} +1 -1
- package/dist/{price-Czq_cTC_.d.mts → price-De-sxcuj.d.ts} +1 -1
- package/dist/react.d.mts +10 -5
- package/dist/react.d.ts +10 -5
- package/dist/react.js +227 -197
- package/dist/react.mjs +90 -60
- package/dist/{server-DKK_D-PP.d.ts → server-Byr4d0hL.d.mts} +31 -57
- package/dist/{server-BkVhOIwn.d.mts → server-C_RIDnHU.d.ts} +31 -57
- package/dist/server.d.mts +3 -4
- package/dist/server.d.ts +3 -4
- package/dist/server.js +11 -11
- package/dist/server.mjs +5 -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 +2478 -14
- package/dist/testing.d.ts +2478 -14
- package/dist/testing.js +167 -89
- package/dist/testing.mjs +24 -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/order-history.json +1 -1
- package/registry/order-summary.json +1 -1
- package/dist/link-D9iSVxt5.d.mts +0 -308
- package/dist/link-D9iSVxt5.d.ts +0 -308
|
@@ -1,8 +1,335 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkXREIZ56K_js = require('./chunk-XREIZ56K.js');
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var chunkXHVQDEVO_js = require('./chunk-XHVQDEVO.js');
|
|
5
|
+
var chunkAVXA4F6G_js = require('./chunk-AVXA4F6G.js');
|
|
6
|
+
|
|
7
|
+
// src/types/observability.ts
|
|
8
|
+
var SESSION_CHANGE_SOURCE = {
|
|
9
|
+
RESPONSE: "response",
|
|
10
|
+
MANUAL: "manual",
|
|
11
|
+
CLEAR: "clear"
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// src/utils/purchase-intent-resolver.ts
|
|
15
|
+
var DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
16
|
+
var DEFAULT_MAX_POLL_ATTEMPTS = 60;
|
|
17
|
+
var DEFAULT_MAX_ACTION_STEPS = 4;
|
|
18
|
+
var DEFAULT_MAX_TERMS_REVIEW_STEPS = 4;
|
|
19
|
+
function nonnegativeInteger(value, fallback) {
|
|
20
|
+
if (value === void 0 || !Number.isFinite(value)) return fallback;
|
|
21
|
+
return Math.max(0, Math.floor(value));
|
|
22
|
+
}
|
|
23
|
+
function abortError() {
|
|
24
|
+
const error = new Error("Purchase-intent resolution was cancelled.");
|
|
25
|
+
error.name = "AbortError";
|
|
26
|
+
return error;
|
|
27
|
+
}
|
|
28
|
+
async function abortableWait(milliseconds, signal) {
|
|
29
|
+
if (signal?.aborted) throw abortError();
|
|
30
|
+
if (milliseconds <= 0) return;
|
|
31
|
+
await new Promise((resolve, reject) => {
|
|
32
|
+
const timer = setTimeout(() => {
|
|
33
|
+
signal?.removeEventListener("abort", onAbort);
|
|
34
|
+
resolve();
|
|
35
|
+
}, milliseconds);
|
|
36
|
+
const onAbort = () => {
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
reject(abortError());
|
|
39
|
+
};
|
|
40
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
var PurchaseIntentResolver = class {
|
|
44
|
+
constructor(dependencies) {
|
|
45
|
+
this.confirmation = dependencies.confirmation;
|
|
46
|
+
this.wait = dependencies.wait ?? abortableWait;
|
|
47
|
+
}
|
|
48
|
+
async resolve(intentId, options) {
|
|
49
|
+
const pollIntervalMs = nonnegativeInteger(
|
|
50
|
+
options.pollIntervalMs,
|
|
51
|
+
DEFAULT_POLL_INTERVAL_MS
|
|
52
|
+
);
|
|
53
|
+
const maxPollAttempts = nonnegativeInteger(
|
|
54
|
+
options.maxPollAttempts,
|
|
55
|
+
DEFAULT_MAX_POLL_ATTEMPTS
|
|
56
|
+
);
|
|
57
|
+
const maxActionSteps = nonnegativeInteger(options.maxActionSteps, DEFAULT_MAX_ACTION_STEPS);
|
|
58
|
+
const maxTermsReviewSteps = nonnegativeInteger(
|
|
59
|
+
options.maxTermsReviewSteps,
|
|
60
|
+
DEFAULT_MAX_TERMS_REVIEW_STEPS
|
|
61
|
+
);
|
|
62
|
+
let request = options.confirmation;
|
|
63
|
+
let pollAttempts = 0;
|
|
64
|
+
let actionSteps = 0;
|
|
65
|
+
let termsReviewSteps = 0;
|
|
66
|
+
this.ensureActive(options.signal);
|
|
67
|
+
this.notify(options, chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLVE_STATUS.CONFIRMING);
|
|
68
|
+
let responseResult = options.initialResponse ? chunkXHVQDEVO_js.ok(options.initialResponse) : await this.confirmation.confirm(intentId, request, { signal: options.signal });
|
|
69
|
+
while (responseResult.ok) {
|
|
70
|
+
this.ensureActive(options.signal);
|
|
71
|
+
const response = responseResult.value;
|
|
72
|
+
switch (response.status) {
|
|
73
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED:
|
|
74
|
+
this.notify(options, chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLVE_STATUS.COMPLETED, response);
|
|
75
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.COMPLETED, response });
|
|
76
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.PAYMENT_FAILED:
|
|
77
|
+
this.notify(options, chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLVE_STATUS.FAILED, response);
|
|
78
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.FAILED, response });
|
|
79
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.PAYMENT_OUTCOME_UNKNOWN:
|
|
80
|
+
this.notify(options, chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLVE_STATUS.OUTCOME_UNKNOWN, response);
|
|
81
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.OUTCOME_UNKNOWN, response });
|
|
82
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.COLLECTION_PROCESSING:
|
|
83
|
+
if (pollAttempts >= maxPollAttempts) {
|
|
84
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.TIMED_OUT, response });
|
|
85
|
+
}
|
|
86
|
+
pollAttempts += 1;
|
|
87
|
+
this.notify(options, chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLVE_STATUS.POLLING, response);
|
|
88
|
+
await this.wait(pollIntervalMs, options.signal);
|
|
89
|
+
responseResult = await this.confirmation.confirm(intentId, request, {
|
|
90
|
+
signal: options.signal
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.REDIRECT_REQUIRED:
|
|
94
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED:
|
|
95
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED: {
|
|
96
|
+
this.notify(options, chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLVE_STATUS.AWAITING_ACTION, response);
|
|
97
|
+
if (!options.onActionRequired || actionSteps >= maxActionSteps) {
|
|
98
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.ACTION_REQUIRED, response });
|
|
99
|
+
}
|
|
100
|
+
actionSteps += 1;
|
|
101
|
+
const decision = await options.onActionRequired(response);
|
|
102
|
+
if (decision === chunkAVXA4F6G_js.PURCHASE_INTENT_ACTION_DECISION.STOP) {
|
|
103
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.ACTION_REQUIRED, response });
|
|
104
|
+
}
|
|
105
|
+
if (typeof decision === "object" && decision.kind === chunkAVXA4F6G_js.PURCHASE_INTENT_ACTION_DECISION.SUBMIT) {
|
|
106
|
+
if (!this.confirmation.submitAction) {
|
|
107
|
+
return chunkXHVQDEVO_js.err(
|
|
108
|
+
new chunkAVXA4F6G_js.CimplifyError(
|
|
109
|
+
chunkAVXA4F6G_js.PURCHASE_INTENT_ERROR_CODE.ACTION_UNSUPPORTED,
|
|
110
|
+
"This confirmation transport cannot submit purchase-intent actions.",
|
|
111
|
+
false
|
|
112
|
+
)
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
responseResult = await this.confirmation.submitAction(
|
|
116
|
+
intentId,
|
|
117
|
+
response.attempt_id,
|
|
118
|
+
decision.request,
|
|
119
|
+
{ signal: options.signal }
|
|
120
|
+
);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (decision !== chunkAVXA4F6G_js.PURCHASE_INTENT_ACTION_DECISION.CONTINUE) {
|
|
124
|
+
return chunkXHVQDEVO_js.err(
|
|
125
|
+
new chunkAVXA4F6G_js.CimplifyError(
|
|
126
|
+
chunkAVXA4F6G_js.PURCHASE_INTENT_ERROR_CODE.ACTION_UNSUPPORTED,
|
|
127
|
+
"The action callback returned an unsupported decision.",
|
|
128
|
+
false
|
|
129
|
+
)
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
await this.wait(pollIntervalMs, options.signal);
|
|
133
|
+
responseResult = await this.confirmation.confirm(intentId, request, {
|
|
134
|
+
signal: options.signal
|
|
135
|
+
});
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED: {
|
|
139
|
+
this.notify(options, chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLVE_STATUS.REVIEWING_TERMS, response);
|
|
140
|
+
if (!options.onTermsChanged || termsReviewSteps >= maxTermsReviewSteps) {
|
|
141
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.REVIEW_REQUIRED, response });
|
|
142
|
+
}
|
|
143
|
+
termsReviewSteps += 1;
|
|
144
|
+
const replacementRequest = await options.onTermsChanged(response);
|
|
145
|
+
if (!replacementRequest) {
|
|
146
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.REVIEW_REQUIRED, response });
|
|
147
|
+
}
|
|
148
|
+
request = replacementRequest;
|
|
149
|
+
responseResult = await this.confirmation.confirm(intentId, request, {
|
|
150
|
+
signal: options.signal
|
|
151
|
+
});
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.SELECTION_UNAVAILABLE:
|
|
155
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.OFFER_ENDED:
|
|
156
|
+
case chunkAVXA4F6G_js.PURCHASE_INTENT_CONFIRM_STATUS.SOURCE_UNAVAILABLE:
|
|
157
|
+
return chunkXHVQDEVO_js.ok({ kind: chunkAVXA4F6G_js.PURCHASE_INTENT_RESOLUTION_KIND.REVIEW_REQUIRED, response });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return responseResult;
|
|
161
|
+
}
|
|
162
|
+
ensureActive(signal) {
|
|
163
|
+
if (signal?.aborted) throw abortError();
|
|
164
|
+
}
|
|
165
|
+
notify(options, status, response) {
|
|
166
|
+
try {
|
|
167
|
+
options.onStatusChange?.(status, response);
|
|
168
|
+
} catch {
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// src/purchase-intent.ts
|
|
174
|
+
var PURCHASE_INTENT_ROUTE = {
|
|
175
|
+
DIRECT_COLLECTION: "/api/v1/purchase-intents",
|
|
176
|
+
HOSTED_SESSION_COLLECTION: "/v1/checkout/sessions",
|
|
177
|
+
PREPARE: "prepare",
|
|
178
|
+
REFRESH: "refresh",
|
|
179
|
+
CONFIRM: "confirm",
|
|
180
|
+
REPLAY: "replay",
|
|
181
|
+
ATTEMPTS: "attempts",
|
|
182
|
+
ACTIONS: "actions"
|
|
183
|
+
};
|
|
184
|
+
function directIntentPath(intentId) {
|
|
185
|
+
const normalized = intentId.trim();
|
|
186
|
+
if (!normalized) throw new TypeError("intentId must not be empty");
|
|
187
|
+
return `${PURCHASE_INTENT_ROUTE.DIRECT_COLLECTION}/${encodeURIComponent(normalized)}`;
|
|
188
|
+
}
|
|
189
|
+
function hostedSessionPath(sessionId) {
|
|
190
|
+
const normalized = sessionId.trim();
|
|
191
|
+
if (!normalized) throw new TypeError("sessionId must not be empty");
|
|
192
|
+
return `${PURCHASE_INTENT_ROUTE.HOSTED_SESSION_COLLECTION}/${encodeURIComponent(normalized)}`;
|
|
193
|
+
}
|
|
194
|
+
var PurchaseIntentService = class {
|
|
195
|
+
constructor(transport) {
|
|
196
|
+
this.transport = transport;
|
|
197
|
+
this.resolver = new PurchaseIntentResolver({ confirmation: this });
|
|
198
|
+
}
|
|
199
|
+
mint(request, options) {
|
|
200
|
+
return chunkXHVQDEVO_js.safe(
|
|
201
|
+
this.transport.post(PURCHASE_INTENT_ROUTE.DIRECT_COLLECTION, request, {
|
|
202
|
+
idempotencyKey: request.client_intent_key,
|
|
203
|
+
signal: options?.signal,
|
|
204
|
+
timeoutMs: options?.timeoutMs
|
|
205
|
+
})
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
get(intentId, options) {
|
|
209
|
+
return chunkXHVQDEVO_js.safe(
|
|
210
|
+
this.transport.get(this.intentPath(intentId), {
|
|
211
|
+
signal: options?.signal,
|
|
212
|
+
timeoutMs: options?.timeoutMs
|
|
213
|
+
})
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
refresh(intentId, expectedRevision, options) {
|
|
217
|
+
const request = {
|
|
218
|
+
expected_intent_revision: expectedRevision
|
|
219
|
+
};
|
|
220
|
+
return chunkXHVQDEVO_js.safe(
|
|
221
|
+
this.transport.post(
|
|
222
|
+
`${this.intentPath(intentId)}/${PURCHASE_INTENT_ROUTE.REFRESH}`,
|
|
223
|
+
request,
|
|
224
|
+
{
|
|
225
|
+
signal: options?.signal,
|
|
226
|
+
timeoutMs: options?.timeoutMs
|
|
227
|
+
}
|
|
228
|
+
)
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
confirm(intentId, request, options) {
|
|
232
|
+
return chunkXHVQDEVO_js.safe(
|
|
233
|
+
this.transport.post(
|
|
234
|
+
`${this.intentPath(intentId)}/${PURCHASE_INTENT_ROUTE.CONFIRM}`,
|
|
235
|
+
request,
|
|
236
|
+
{
|
|
237
|
+
idempotencyKey: request.idempotency_key,
|
|
238
|
+
signal: options?.signal,
|
|
239
|
+
timeoutMs: options?.timeoutMs
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
submitAction(intentId, attemptId, request, options) {
|
|
245
|
+
const normalizedAttemptId = attemptId.trim();
|
|
246
|
+
if (!normalizedAttemptId) throw new TypeError("attemptId must not be empty");
|
|
247
|
+
return chunkXHVQDEVO_js.safe(
|
|
248
|
+
this.transport.post(
|
|
249
|
+
`${this.intentPath(intentId)}/${PURCHASE_INTENT_ROUTE.ATTEMPTS}/${encodeURIComponent(normalizedAttemptId)}/${PURCHASE_INTENT_ROUTE.ACTIONS}`,
|
|
250
|
+
request,
|
|
251
|
+
{
|
|
252
|
+
signal: options?.signal,
|
|
253
|
+
timeoutMs: options?.timeoutMs
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
resolve(intentId, options) {
|
|
259
|
+
return this.resolver.resolve(intentId, options);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Bind subsequent preparation/confirmation to one hosted checkout-session
|
|
263
|
+
* owner. The session ID is a route authority, not an intent-owner rewrite.
|
|
264
|
+
*/
|
|
265
|
+
forHostedSession(sessionId) {
|
|
266
|
+
return new HostedPurchaseIntentService(this.transport, sessionId);
|
|
267
|
+
}
|
|
268
|
+
intentPath(intentId) {
|
|
269
|
+
return directIntentPath(intentId);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
var HostedPurchaseIntentService = class {
|
|
273
|
+
constructor(transport, sessionId) {
|
|
274
|
+
this.transport = transport;
|
|
275
|
+
this.sessionPath = hostedSessionPath(sessionId);
|
|
276
|
+
this.resolver = new PurchaseIntentResolver({ confirmation: this });
|
|
277
|
+
}
|
|
278
|
+
prepare(request, options) {
|
|
279
|
+
return chunkXHVQDEVO_js.safe(
|
|
280
|
+
this.transport.post(
|
|
281
|
+
`${this.sessionPath}/${PURCHASE_INTENT_ROUTE.PREPARE}`,
|
|
282
|
+
request,
|
|
283
|
+
{
|
|
284
|
+
idempotencyKey: request.idempotency_key,
|
|
285
|
+
signal: options?.signal,
|
|
286
|
+
timeoutMs: options?.timeoutMs
|
|
287
|
+
}
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
confirm(_intentId, request, options) {
|
|
292
|
+
return chunkXHVQDEVO_js.safe(
|
|
293
|
+
this.transport.post(
|
|
294
|
+
`${this.sessionPath}/${PURCHASE_INTENT_ROUTE.CONFIRM}`,
|
|
295
|
+
request,
|
|
296
|
+
{
|
|
297
|
+
idempotencyKey: request.idempotency_key,
|
|
298
|
+
signal: options?.signal,
|
|
299
|
+
timeoutMs: options?.timeoutMs
|
|
300
|
+
}
|
|
301
|
+
)
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
replay(options) {
|
|
305
|
+
return chunkXHVQDEVO_js.safe(
|
|
306
|
+
this.transport.get(
|
|
307
|
+
`${this.sessionPath}/${PURCHASE_INTENT_ROUTE.REPLAY}`,
|
|
308
|
+
{
|
|
309
|
+
signal: options?.signal,
|
|
310
|
+
timeoutMs: options?.timeoutMs
|
|
311
|
+
}
|
|
312
|
+
)
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
submitAction(_intentId, attemptId, request, options) {
|
|
316
|
+
const normalized = attemptId.trim();
|
|
317
|
+
if (!normalized) throw new TypeError("attemptId must not be empty");
|
|
318
|
+
return chunkXHVQDEVO_js.safe(
|
|
319
|
+
this.transport.post(
|
|
320
|
+
`${this.sessionPath}/${PURCHASE_INTENT_ROUTE.ATTEMPTS}/${encodeURIComponent(normalized)}/${PURCHASE_INTENT_ROUTE.ACTIONS}`,
|
|
321
|
+
request,
|
|
322
|
+
{
|
|
323
|
+
signal: options?.signal,
|
|
324
|
+
timeoutMs: options?.timeoutMs
|
|
325
|
+
}
|
|
326
|
+
)
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
resolve(intentId, options) {
|
|
330
|
+
return this.resolver.resolve(intentId, options);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
6
333
|
|
|
7
334
|
// src/store-credit.ts
|
|
8
335
|
var StoreCreditQueries = class {
|
|
@@ -14,18 +341,19 @@ var StoreCreditQueries = class {
|
|
|
14
341
|
* currency. Requires a signed-in customer; returns an error otherwise.
|
|
15
342
|
*/
|
|
16
343
|
async balance() {
|
|
17
|
-
return
|
|
344
|
+
return chunkXHVQDEVO_js.safe(this.client.get("/api/v1/store-credit/balance"));
|
|
18
345
|
}
|
|
19
346
|
};
|
|
20
347
|
|
|
21
348
|
// src/internal/analytics-session.ts
|
|
22
349
|
var ANALYTICS_SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
23
|
-
var
|
|
24
|
-
var ANALYTICS_SESSION_STATE_VERSION =
|
|
350
|
+
var ANALYTICS_SESSION_STORAGE_KEY_PREFIX = "cimplify_analytics_session:v2:";
|
|
351
|
+
var ANALYTICS_SESSION_STATE_VERSION = 2;
|
|
25
352
|
var MICROSECONDS_PER_MILLISECOND = 1e3;
|
|
26
353
|
var MICROSECONDS_PER_SECOND = 1e6;
|
|
27
354
|
var AnalyticsSessionCoordinator = class {
|
|
28
|
-
constructor() {
|
|
355
|
+
constructor(identity) {
|
|
356
|
+
this.identity = identity;
|
|
29
357
|
this.fallbackState = null;
|
|
30
358
|
}
|
|
31
359
|
beginEvent(nowMs = Date.now()) {
|
|
@@ -63,7 +391,7 @@ var AnalyticsSessionCoordinator = class {
|
|
|
63
391
|
reset() {
|
|
64
392
|
this.fallbackState = null;
|
|
65
393
|
try {
|
|
66
|
-
sessionStorage.removeItem(
|
|
394
|
+
sessionStorage.removeItem(this.storageKey());
|
|
67
395
|
} catch {
|
|
68
396
|
}
|
|
69
397
|
}
|
|
@@ -73,11 +401,11 @@ var AnalyticsSessionCoordinator = class {
|
|
|
73
401
|
}
|
|
74
402
|
read() {
|
|
75
403
|
try {
|
|
76
|
-
const serialized = sessionStorage.getItem(
|
|
404
|
+
const serialized = sessionStorage.getItem(this.storageKey());
|
|
77
405
|
if (!serialized) return this.fallbackState;
|
|
78
406
|
const state = JSON.parse(serialized);
|
|
79
407
|
if (!isPersistedSession(state)) {
|
|
80
|
-
sessionStorage.removeItem(
|
|
408
|
+
sessionStorage.removeItem(this.storageKey());
|
|
81
409
|
return this.fallbackState;
|
|
82
410
|
}
|
|
83
411
|
this.fallbackState = state;
|
|
@@ -89,10 +417,13 @@ var AnalyticsSessionCoordinator = class {
|
|
|
89
417
|
write(state) {
|
|
90
418
|
this.fallbackState = state;
|
|
91
419
|
try {
|
|
92
|
-
sessionStorage.setItem(
|
|
420
|
+
sessionStorage.setItem(this.storageKey(), JSON.stringify(state));
|
|
93
421
|
} catch {
|
|
94
422
|
}
|
|
95
423
|
}
|
|
424
|
+
storageKey() {
|
|
425
|
+
return `${ANALYTICS_SESSION_STORAGE_KEY_PREFIX}${encodeURIComponent(this.identity)}`;
|
|
426
|
+
}
|
|
96
427
|
};
|
|
97
428
|
function newSession(nowMs) {
|
|
98
429
|
return {
|
|
@@ -159,11 +490,127 @@ function generateSessionId() {
|
|
|
159
490
|
|
|
160
491
|
// src/activity.ts
|
|
161
492
|
var VISITOR_ID_STORAGE_KEY = "cimplify_visitor_id";
|
|
493
|
+
var ACTIVITY_RETRY_POLICY = {
|
|
494
|
+
maxRetries: 1,
|
|
495
|
+
jitterRatio: 0.2
|
|
496
|
+
};
|
|
497
|
+
var PAGE_VIEW_TRACKER_KEY = /* @__PURE__ */ Symbol.for("@cimplify/sdk.page-view-tracker-hub");
|
|
498
|
+
var PAGE_VIEW_TRACKER_VERSION = 2;
|
|
499
|
+
function trackerHost() {
|
|
500
|
+
return window;
|
|
501
|
+
}
|
|
502
|
+
function currentWindowTrackerHub() {
|
|
503
|
+
const candidate = trackerHost()[PAGE_VIEW_TRACKER_KEY];
|
|
504
|
+
return candidate?.version === PAGE_VIEW_TRACKER_VERSION && candidate.registrations instanceof Map && typeof candidate.recordAll === "function" ? candidate : null;
|
|
505
|
+
}
|
|
506
|
+
function weakReference(target) {
|
|
507
|
+
const WeakReference = globalThis.WeakRef;
|
|
508
|
+
if (WeakReference) return new WeakReference(target);
|
|
509
|
+
return { deref: () => target };
|
|
510
|
+
}
|
|
511
|
+
function latestLiveOwner(registration) {
|
|
512
|
+
let latest = null;
|
|
513
|
+
for (const [token, reference] of registration.owners) {
|
|
514
|
+
const owner = reference.deref();
|
|
515
|
+
if (!owner || owner.released) {
|
|
516
|
+
registration.owners.delete(token);
|
|
517
|
+
} else {
|
|
518
|
+
latest = owner;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return latest;
|
|
522
|
+
}
|
|
523
|
+
function recordRegistration(registration, path) {
|
|
524
|
+
if (path === registration.lastPath) return;
|
|
525
|
+
const owner = registration.activeOwner && !registration.activeOwner.released ? registration.activeOwner : latestLiveOwner(registration);
|
|
526
|
+
if (!owner) return;
|
|
527
|
+
registration.activeOwner = owner;
|
|
528
|
+
registration.lastPath = path;
|
|
529
|
+
owner.recorder(path);
|
|
530
|
+
}
|
|
531
|
+
function createWindowTrackerHub() {
|
|
532
|
+
const originalPushState = window.history.pushState;
|
|
533
|
+
const originalReplaceState = window.history.replaceState;
|
|
534
|
+
const hub = {
|
|
535
|
+
version: PAGE_VIEW_TRACKER_VERSION,
|
|
536
|
+
registrations: /* @__PURE__ */ new Map(),
|
|
537
|
+
originalPushState,
|
|
538
|
+
originalReplaceState
|
|
539
|
+
};
|
|
540
|
+
hub.recordAll = () => {
|
|
541
|
+
const path = window.location.pathname;
|
|
542
|
+
for (const registration of hub.registrations.values()) {
|
|
543
|
+
recordRegistration(registration, path);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
hub.patchedPushState = function(...args) {
|
|
547
|
+
originalPushState.apply(this, args);
|
|
548
|
+
hub.recordAll();
|
|
549
|
+
};
|
|
550
|
+
hub.patchedReplaceState = function(...args) {
|
|
551
|
+
originalReplaceState.apply(this, args);
|
|
552
|
+
hub.recordAll();
|
|
553
|
+
};
|
|
554
|
+
hub.popstateListener = () => hub.recordAll();
|
|
555
|
+
window.history.pushState = hub.patchedPushState;
|
|
556
|
+
window.history.replaceState = hub.patchedReplaceState;
|
|
557
|
+
window.addEventListener("popstate", hub.popstateListener);
|
|
558
|
+
trackerHost()[PAGE_VIEW_TRACKER_KEY] = hub;
|
|
559
|
+
return hub;
|
|
560
|
+
}
|
|
561
|
+
function pageViewTrackerIdentity(client) {
|
|
562
|
+
return JSON.stringify([client.getBaseUrl(), client.getPublicKey().trim()]);
|
|
563
|
+
}
|
|
564
|
+
function acquireWindowPageViewTracker(identity, recorder) {
|
|
565
|
+
const hub = currentWindowTrackerHub() ?? createWindowTrackerHub();
|
|
566
|
+
let registration = hub.registrations.get(identity);
|
|
567
|
+
const isNewIdentity = !registration;
|
|
568
|
+
if (!registration) {
|
|
569
|
+
registration = { owners: /* @__PURE__ */ new Map(), activeOwner: null, lastPath: null };
|
|
570
|
+
hub.registrations.set(identity, registration);
|
|
571
|
+
}
|
|
572
|
+
const owner = {
|
|
573
|
+
token: Symbol(identity),
|
|
574
|
+
recorder,
|
|
575
|
+
released: false
|
|
576
|
+
};
|
|
577
|
+
registration.owners.set(owner.token, weakReference(owner));
|
|
578
|
+
registration.activeOwner = owner;
|
|
579
|
+
if (isNewIdentity) {
|
|
580
|
+
recordRegistration(registration, window.location.pathname);
|
|
581
|
+
}
|
|
582
|
+
let released = false;
|
|
583
|
+
return () => {
|
|
584
|
+
if (released) return;
|
|
585
|
+
released = true;
|
|
586
|
+
owner.released = true;
|
|
587
|
+
registration.owners.delete(owner.token);
|
|
588
|
+
if (registration.activeOwner === owner) {
|
|
589
|
+
registration.activeOwner = latestLiveOwner(registration);
|
|
590
|
+
}
|
|
591
|
+
if (registration.activeOwner) return;
|
|
592
|
+
if (hub.registrations.get(identity) === registration) {
|
|
593
|
+
hub.registrations.delete(identity);
|
|
594
|
+
}
|
|
595
|
+
if (hub.registrations.size !== 0) return;
|
|
596
|
+
window.removeEventListener("popstate", hub.popstateListener);
|
|
597
|
+
if (window.history.pushState === hub.patchedPushState) {
|
|
598
|
+
window.history.pushState = hub.originalPushState;
|
|
599
|
+
}
|
|
600
|
+
if (window.history.replaceState === hub.patchedReplaceState) {
|
|
601
|
+
window.history.replaceState = hub.originalReplaceState;
|
|
602
|
+
}
|
|
603
|
+
if (currentWindowTrackerHub() === hub) {
|
|
604
|
+
delete trackerHost()[PAGE_VIEW_TRACKER_KEY];
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
}
|
|
162
608
|
var ActivityService = class {
|
|
163
609
|
constructor(client) {
|
|
164
610
|
this.client = client;
|
|
165
|
-
this.
|
|
611
|
+
this.localGeneration = 0;
|
|
166
612
|
this.bootstrapRequest = null;
|
|
613
|
+
this.sessions = this.createSessionCoordinator();
|
|
167
614
|
}
|
|
168
615
|
/**
|
|
169
616
|
* Record session start (landing, referrer, UTM, device). Fire-and-forget,
|
|
@@ -173,7 +620,7 @@ var ActivityService = class {
|
|
|
173
620
|
startSession() {
|
|
174
621
|
if (typeof window === "undefined") return;
|
|
175
622
|
const session = this.sessions.beginEvent();
|
|
176
|
-
void this.bootstrapSession(session).catch(() => {
|
|
623
|
+
void this.bootstrapSession(session, false, this.captureGeneration()).catch(() => {
|
|
177
624
|
});
|
|
178
625
|
}
|
|
179
626
|
/** Rebind an existing analytics session after the server authenticates a customer. */
|
|
@@ -181,13 +628,19 @@ var ActivityService = class {
|
|
|
181
628
|
if (typeof window === "undefined") return;
|
|
182
629
|
const session = this.sessions.current();
|
|
183
630
|
if (!session) return;
|
|
184
|
-
void this.bootstrapSession(session, true).catch(() => {
|
|
631
|
+
void this.bootstrapSession(session, true, this.captureGeneration()).catch(() => {
|
|
185
632
|
});
|
|
186
633
|
}
|
|
187
634
|
/** A signed-out browser starts a fresh anonymous analytics session. */
|
|
188
635
|
resetSession() {
|
|
636
|
+
this.invalidatePendingActivity();
|
|
189
637
|
this.sessions.reset();
|
|
190
|
-
|
|
638
|
+
}
|
|
639
|
+
/** Drop the old storefront's analytics state before binding this service to the new one. */
|
|
640
|
+
resetForStorefrontIdentityChange() {
|
|
641
|
+
this.invalidatePendingActivity();
|
|
642
|
+
this.sessions.reset();
|
|
643
|
+
this.sessions = this.createSessionCoordinator();
|
|
191
644
|
}
|
|
192
645
|
buildSessionPayload(session) {
|
|
193
646
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -264,7 +717,7 @@ var ActivityService = class {
|
|
|
264
717
|
this.sendEvents([event]);
|
|
265
718
|
}
|
|
266
719
|
async getState() {
|
|
267
|
-
return
|
|
720
|
+
return chunkXHVQDEVO_js.safe(this.client.get("/api/v1/activity/state"));
|
|
268
721
|
}
|
|
269
722
|
async getRecommendations(options) {
|
|
270
723
|
const params = new URLSearchParams();
|
|
@@ -272,10 +725,10 @@ var ActivityService = class {
|
|
|
272
725
|
if (options?.limit) params.set("limit", String(options.limit));
|
|
273
726
|
const query = params.toString();
|
|
274
727
|
const path = query ? `/api/v1/activity/recommendations?${query}` : "/api/v1/activity/recommendations";
|
|
275
|
-
return
|
|
728
|
+
return chunkXHVQDEVO_js.safe(this.client.get(path));
|
|
276
729
|
}
|
|
277
730
|
async dismissMessage(code) {
|
|
278
|
-
return
|
|
731
|
+
return chunkXHVQDEVO_js.safe(
|
|
279
732
|
this.client.post("/api/v1/activity/messages/dismiss", { code })
|
|
280
733
|
);
|
|
281
734
|
}
|
|
@@ -283,32 +736,12 @@ var ActivityService = class {
|
|
|
283
736
|
autoTrackPageViews() {
|
|
284
737
|
if (typeof window === "undefined") return () => {
|
|
285
738
|
};
|
|
286
|
-
|
|
287
|
-
const record = () => {
|
|
288
|
-
const path = window.location.pathname;
|
|
289
|
-
if (path === lastPath) return;
|
|
290
|
-
lastPath = path;
|
|
739
|
+
return acquireWindowPageViewTracker(pageViewTrackerIdentity(this.client), (path) => {
|
|
291
740
|
try {
|
|
292
741
|
this.trackPageView({ pagePath: path });
|
|
293
742
|
} catch {
|
|
294
743
|
}
|
|
295
|
-
};
|
|
296
|
-
const { pushState, replaceState } = window.history;
|
|
297
|
-
window.history.pushState = function(...args) {
|
|
298
|
-
pushState.apply(this, args);
|
|
299
|
-
record();
|
|
300
|
-
};
|
|
301
|
-
window.history.replaceState = function(...args) {
|
|
302
|
-
replaceState.apply(this, args);
|
|
303
|
-
record();
|
|
304
|
-
};
|
|
305
|
-
window.addEventListener("popstate", record);
|
|
306
|
-
record();
|
|
307
|
-
return () => {
|
|
308
|
-
window.history.pushState = pushState;
|
|
309
|
-
window.history.replaceState = replaceState;
|
|
310
|
-
window.removeEventListener("popstate", record);
|
|
311
|
-
};
|
|
744
|
+
});
|
|
312
745
|
}
|
|
313
746
|
sendEvents(events, session) {
|
|
314
747
|
if (typeof window === "undefined") return;
|
|
@@ -316,29 +749,59 @@ var ActivityService = class {
|
|
|
316
749
|
});
|
|
317
750
|
}
|
|
318
751
|
async postEvents(events, session) {
|
|
319
|
-
|
|
320
|
-
await this.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
events
|
|
324
|
-
|
|
752
|
+
const generation = this.captureGeneration();
|
|
753
|
+
await this.bootstrapSession(session, false, generation);
|
|
754
|
+
if (!this.isCurrentGeneration(generation)) return;
|
|
755
|
+
await this.client.post(
|
|
756
|
+
"/api/v1/activity/events",
|
|
757
|
+
{
|
|
758
|
+
analytics_session_id: session.id,
|
|
759
|
+
occurred_at: session.occurredAt,
|
|
760
|
+
events
|
|
761
|
+
},
|
|
762
|
+
{ retryPolicy: ACTIVITY_RETRY_POLICY }
|
|
763
|
+
);
|
|
325
764
|
}
|
|
326
|
-
bootstrapSession(session, force = false) {
|
|
765
|
+
bootstrapSession(session, force = false, generation = this.captureGeneration()) {
|
|
327
766
|
if (!force && !session.requiresBootstrap) return Promise.resolve();
|
|
328
|
-
if (!force && this.bootstrapRequest?.sessionId === session.id) {
|
|
767
|
+
if (!force && this.bootstrapRequest?.sessionId === session.id && sameActivityGeneration(this.bootstrapRequest.generation, generation)) {
|
|
329
768
|
return this.bootstrapRequest.promise;
|
|
330
769
|
}
|
|
331
|
-
const promise = this.client.post("/api/v1/activity/session", this.buildSessionPayload(session)
|
|
332
|
-
|
|
770
|
+
const promise = this.client.post("/api/v1/activity/session", this.buildSessionPayload(session), {
|
|
771
|
+
retryPolicy: ACTIVITY_RETRY_POLICY
|
|
772
|
+
}).then(() => {
|
|
773
|
+
if (this.isCurrentGeneration(generation)) {
|
|
774
|
+
this.sessions.markBootstrapped(session.id);
|
|
775
|
+
}
|
|
333
776
|
}).finally(() => {
|
|
334
777
|
if (this.bootstrapRequest?.promise === promise) {
|
|
335
778
|
this.bootstrapRequest = null;
|
|
336
779
|
}
|
|
337
780
|
});
|
|
338
|
-
this.bootstrapRequest = { sessionId: session.id, promise };
|
|
781
|
+
this.bootstrapRequest = { sessionId: session.id, generation, promise };
|
|
339
782
|
return promise;
|
|
340
783
|
}
|
|
784
|
+
captureGeneration() {
|
|
785
|
+
return {
|
|
786
|
+
local: this.localGeneration,
|
|
787
|
+
publicKey: this.client.getPublicKeyEpoch(),
|
|
788
|
+
session: this.client.getSessionEpoch()
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
isCurrentGeneration(generation) {
|
|
792
|
+
return sameActivityGeneration(generation, this.captureGeneration());
|
|
793
|
+
}
|
|
794
|
+
invalidatePendingActivity() {
|
|
795
|
+
this.localGeneration += 1;
|
|
796
|
+
this.bootstrapRequest = null;
|
|
797
|
+
}
|
|
798
|
+
createSessionCoordinator() {
|
|
799
|
+
return new AnalyticsSessionCoordinator(pageViewTrackerIdentity(this.client));
|
|
800
|
+
}
|
|
341
801
|
};
|
|
802
|
+
function sameActivityGeneration(left, right) {
|
|
803
|
+
return left.local === right.local && left.publicKey === right.publicKey && left.session === right.session;
|
|
804
|
+
}
|
|
342
805
|
function currentPath() {
|
|
343
806
|
if (typeof window !== "undefined") {
|
|
344
807
|
return window.location.pathname;
|
|
@@ -371,16 +834,16 @@ var SubscriptionService = class {
|
|
|
371
834
|
this.client = client;
|
|
372
835
|
}
|
|
373
836
|
async list() {
|
|
374
|
-
return
|
|
837
|
+
return chunkXHVQDEVO_js.safe(this.client.get("/api/v1/subscriptions"));
|
|
375
838
|
}
|
|
376
839
|
async get(id) {
|
|
377
840
|
const encodedId = encodeURIComponent(id);
|
|
378
|
-
return
|
|
841
|
+
return chunkXHVQDEVO_js.safe(this.client.get(`/api/v1/subscriptions/${encodedId}`));
|
|
379
842
|
}
|
|
380
843
|
async cancel(id, reason, opts) {
|
|
381
844
|
const encodedId = encodeURIComponent(id);
|
|
382
|
-
const idempotencyKey = opts?.idempotencyKey ??
|
|
383
|
-
return
|
|
845
|
+
const idempotencyKey = opts?.idempotencyKey ?? chunkXHVQDEVO_js.generateIdempotencyKey();
|
|
846
|
+
return chunkXHVQDEVO_js.safe(
|
|
384
847
|
this.client.post(
|
|
385
848
|
`/api/v1/subscriptions/${encodedId}/cancel`,
|
|
386
849
|
{ reason },
|
|
@@ -390,20 +853,20 @@ var SubscriptionService = class {
|
|
|
390
853
|
}
|
|
391
854
|
async pause(id) {
|
|
392
855
|
const encodedId = encodeURIComponent(id);
|
|
393
|
-
return
|
|
856
|
+
return chunkXHVQDEVO_js.safe(
|
|
394
857
|
this.client.post(`/api/v1/subscriptions/${encodedId}/pause`)
|
|
395
858
|
);
|
|
396
859
|
}
|
|
397
860
|
async resume(id) {
|
|
398
861
|
const encodedId = encodeURIComponent(id);
|
|
399
|
-
return
|
|
862
|
+
return chunkXHVQDEVO_js.safe(
|
|
400
863
|
this.client.post(`/api/v1/subscriptions/${encodedId}/resume`)
|
|
401
864
|
);
|
|
402
865
|
}
|
|
403
866
|
async skipNextRenewal(id, opts) {
|
|
404
867
|
const encodedId = encodeURIComponent(id);
|
|
405
|
-
const idempotencyKey = opts?.idempotencyKey ??
|
|
406
|
-
return
|
|
868
|
+
const idempotencyKey = opts?.idempotencyKey ?? chunkXHVQDEVO_js.generateIdempotencyKey();
|
|
869
|
+
return chunkXHVQDEVO_js.safe(
|
|
407
870
|
this.client.post(
|
|
408
871
|
`/api/v1/subscriptions/${encodedId}/skip`,
|
|
409
872
|
void 0,
|
|
@@ -419,8 +882,8 @@ var UploadService = class {
|
|
|
419
882
|
this.client = client;
|
|
420
883
|
}
|
|
421
884
|
async init(filename, contentType2, sizeBytes, opts) {
|
|
422
|
-
const idempotencyKey = opts?.idempotencyKey ??
|
|
423
|
-
return
|
|
885
|
+
const idempotencyKey = opts?.idempotencyKey ?? chunkXHVQDEVO_js.generateIdempotencyKey();
|
|
886
|
+
return chunkXHVQDEVO_js.safe(
|
|
424
887
|
this.client.post(
|
|
425
888
|
"/api/v1/uploads/init",
|
|
426
889
|
{
|
|
@@ -433,7 +896,7 @@ var UploadService = class {
|
|
|
433
896
|
);
|
|
434
897
|
}
|
|
435
898
|
async confirm(uploadId) {
|
|
436
|
-
return
|
|
899
|
+
return chunkXHVQDEVO_js.safe(
|
|
437
900
|
this.client.post("/api/v1/uploads/confirm", {
|
|
438
901
|
upload_id: uploadId
|
|
439
902
|
})
|
|
@@ -452,7 +915,7 @@ var UploadService = class {
|
|
|
452
915
|
if (!uploadResponse.ok) {
|
|
453
916
|
return {
|
|
454
917
|
ok: false,
|
|
455
|
-
error: new
|
|
918
|
+
error: new chunkAVXA4F6G_js.CimplifyError(
|
|
456
919
|
"UPLOAD_FAILED",
|
|
457
920
|
`Upload failed with status ${uploadResponse.status}`,
|
|
458
921
|
true
|
|
@@ -462,7 +925,7 @@ var UploadService = class {
|
|
|
462
925
|
} catch (error) {
|
|
463
926
|
return {
|
|
464
927
|
ok: false,
|
|
465
|
-
error: new
|
|
928
|
+
error: new chunkAVXA4F6G_js.CimplifyError(
|
|
466
929
|
"UPLOAD_FAILED",
|
|
467
930
|
error instanceof Error ? error.message : "Upload failed",
|
|
468
931
|
true
|
|
@@ -479,7 +942,7 @@ var PlacesService = class {
|
|
|
479
942
|
this.client = client;
|
|
480
943
|
}
|
|
481
944
|
async autocomplete(input, sessionToken) {
|
|
482
|
-
return
|
|
945
|
+
return chunkXHVQDEVO_js.safe(
|
|
483
946
|
this.client.post("/api/v1/places/autocomplete", {
|
|
484
947
|
input,
|
|
485
948
|
sessionToken
|
|
@@ -487,7 +950,7 @@ var PlacesService = class {
|
|
|
487
950
|
);
|
|
488
951
|
}
|
|
489
952
|
async details(placeId, sessionToken) {
|
|
490
|
-
return
|
|
953
|
+
return chunkXHVQDEVO_js.safe(
|
|
491
954
|
this.client.post("/api/v1/places/details", {
|
|
492
955
|
place_id: placeId,
|
|
493
956
|
sessionToken
|
|
@@ -506,7 +969,7 @@ var DeliveryService = class {
|
|
|
506
969
|
params.set("dropoff_lat", String(dropoffLat));
|
|
507
970
|
params.set("dropoff_lng", String(dropoffLng));
|
|
508
971
|
if (country) params.set("country", country);
|
|
509
|
-
return
|
|
972
|
+
return chunkXHVQDEVO_js.safe(this.client.get(`/api/v1/delivery/fee?${params.toString()}`));
|
|
510
973
|
}
|
|
511
974
|
async getOptions(queryOrLatitude, longitude, legacyOptions) {
|
|
512
975
|
const query = typeof queryOrLatitude === "number" ? {
|
|
@@ -520,7 +983,7 @@ var DeliveryService = class {
|
|
|
520
983
|
if (query.country) params.set("country", query.country);
|
|
521
984
|
if (query.currency) params.set("currency", query.currency);
|
|
522
985
|
if (query.orderValue != null) params.set("order_value", String(query.orderValue));
|
|
523
|
-
return
|
|
986
|
+
return chunkXHVQDEVO_js.safe(
|
|
524
987
|
this.client.get(`/api/v1/delivery/options?${params.toString()}`)
|
|
525
988
|
);
|
|
526
989
|
}
|
|
@@ -692,7 +1155,7 @@ var SupportService = class {
|
|
|
692
1155
|
async claimConversation() {
|
|
693
1156
|
const accessToken = this.client.getAccessToken();
|
|
694
1157
|
if (!accessToken) {
|
|
695
|
-
return
|
|
1158
|
+
return chunkXHVQDEVO_js.err(new chunkAVXA4F6G_js.CimplifyError("not_authenticated", "No access token to claim with"));
|
|
696
1159
|
}
|
|
697
1160
|
if (this.claimInFlight) {
|
|
698
1161
|
if (this.claimInFlightToken === accessToken) return this.claimInFlight;
|
|
@@ -700,12 +1163,12 @@ var SupportService = class {
|
|
|
700
1163
|
return this.claimConversation();
|
|
701
1164
|
}
|
|
702
1165
|
if (this.lastClaimedAccessToken === accessToken) {
|
|
703
|
-
return
|
|
1166
|
+
return chunkXHVQDEVO_js.err(new chunkAVXA4F6G_js.CimplifyError("already_claimed", "Session already claimed for this token"));
|
|
704
1167
|
}
|
|
705
1168
|
const epoch = this.client.getSessionEpoch();
|
|
706
1169
|
this.claimInFlightToken = accessToken;
|
|
707
1170
|
this.claimInFlight = (async () => {
|
|
708
|
-
const result = await
|
|
1171
|
+
const result = await chunkXHVQDEVO_js.safe(
|
|
709
1172
|
this.client.post(
|
|
710
1173
|
"/api/v1/support/conversation/claim",
|
|
711
1174
|
{ access_token: accessToken },
|
|
@@ -714,8 +1177,8 @@ var SupportService = class {
|
|
|
714
1177
|
);
|
|
715
1178
|
if (result.ok) {
|
|
716
1179
|
if (this.client.getSessionEpoch() !== epoch) {
|
|
717
|
-
return
|
|
718
|
-
new
|
|
1180
|
+
return chunkXHVQDEVO_js.err(
|
|
1181
|
+
new chunkAVXA4F6G_js.CimplifyError("session_cleared", "Session was cleared during the claim")
|
|
719
1182
|
);
|
|
720
1183
|
}
|
|
721
1184
|
this.lastClaimedAccessToken = accessToken;
|
|
@@ -745,9 +1208,9 @@ var SupportService = class {
|
|
|
745
1208
|
*/
|
|
746
1209
|
async claimExternalChats() {
|
|
747
1210
|
if (!this.client.getAccessToken()) {
|
|
748
|
-
return
|
|
1211
|
+
return chunkXHVQDEVO_js.err(new chunkAVXA4F6G_js.CimplifyError("not_authenticated", "No access token to claim with"));
|
|
749
1212
|
}
|
|
750
|
-
return
|
|
1213
|
+
return chunkXHVQDEVO_js.safe(
|
|
751
1214
|
(async () => {
|
|
752
1215
|
const businessId = await this.client.resolveBusinessId();
|
|
753
1216
|
return this.client.post("/v1/me/chats/external-claims", {
|
|
@@ -762,26 +1225,26 @@ var SupportService = class {
|
|
|
762
1225
|
* the inbox with empty threads.
|
|
763
1226
|
*/
|
|
764
1227
|
async peekConversation() {
|
|
765
|
-
const result = await
|
|
1228
|
+
const result = await chunkXHVQDEVO_js.safe(
|
|
766
1229
|
this.client.get("/api/v1/support/conversation")
|
|
767
1230
|
);
|
|
768
1231
|
if (!result.ok) return result;
|
|
769
|
-
if (!result.value.conversation) return
|
|
770
|
-
return
|
|
1232
|
+
if (!result.value.conversation) return chunkXHVQDEVO_js.ok(null);
|
|
1233
|
+
return chunkXHVQDEVO_js.ok({
|
|
771
1234
|
conversation: result.value.conversation,
|
|
772
1235
|
messages: chatMessagesFromWire(result.value.messages)
|
|
773
1236
|
});
|
|
774
1237
|
}
|
|
775
1238
|
/** Open (or resume) the customer's widget conversation. */
|
|
776
1239
|
async openConversation(opts) {
|
|
777
|
-
const idempotencyKey = opts?.idempotencyKey ??
|
|
778
|
-
const result = await
|
|
1240
|
+
const idempotencyKey = opts?.idempotencyKey ?? chunkXHVQDEVO_js.generateIdempotencyKey();
|
|
1241
|
+
const result = await chunkXHVQDEVO_js.safe(
|
|
779
1242
|
this.client.post("/api/v1/support/conversation", void 0, {
|
|
780
1243
|
idempotencyKey
|
|
781
1244
|
})
|
|
782
1245
|
);
|
|
783
1246
|
if (!result.ok) return result;
|
|
784
|
-
return
|
|
1247
|
+
return chunkXHVQDEVO_js.ok({
|
|
785
1248
|
conversation: result.value.conversation,
|
|
786
1249
|
messages: chatMessagesFromWire(result.value.messages)
|
|
787
1250
|
});
|
|
@@ -795,8 +1258,8 @@ var SupportService = class {
|
|
|
795
1258
|
* server resolves it thread-scoped and echoes the quote as `reply_to`.
|
|
796
1259
|
*/
|
|
797
1260
|
async sendMessage(content, opts) {
|
|
798
|
-
const idempotencyKey = opts?.idempotencyKey ??
|
|
799
|
-
const result = await
|
|
1261
|
+
const idempotencyKey = opts?.idempotencyKey ?? chunkXHVQDEVO_js.generateIdempotencyKey();
|
|
1262
|
+
const result = await chunkXHVQDEVO_js.safe(
|
|
800
1263
|
this.client.post(
|
|
801
1264
|
"/api/v1/support/conversation/messages",
|
|
802
1265
|
{
|
|
@@ -808,7 +1271,7 @@ var SupportService = class {
|
|
|
808
1271
|
{ idempotencyKey }
|
|
809
1272
|
)
|
|
810
1273
|
);
|
|
811
|
-
return result.ok ?
|
|
1274
|
+
return result.ok ? chunkXHVQDEVO_js.ok(chatMessageFromWire(result.value.message)) : result;
|
|
812
1275
|
}
|
|
813
1276
|
/**
|
|
814
1277
|
* Poll for messages. `after` pages forward (live updates); `before` pages
|
|
@@ -823,25 +1286,25 @@ var SupportService = class {
|
|
|
823
1286
|
if (options.limit) params.set("limit", String(options.limit));
|
|
824
1287
|
const query = params.toString();
|
|
825
1288
|
const path = query ? `/api/v1/support/conversation/messages?${query}` : "/api/v1/support/conversation/messages";
|
|
826
|
-
const result = await
|
|
827
|
-
return result.ok ?
|
|
1289
|
+
const result = await chunkXHVQDEVO_js.safe(this.client.get(path));
|
|
1290
|
+
return result.ok ? chunkXHVQDEVO_js.ok(chatMessagesFromWire(result.value)) : result;
|
|
828
1291
|
}
|
|
829
1292
|
/** React to a message in the active conversation by its `ChatMessage.id`. */
|
|
830
1293
|
async reactToMessage(messageId, emoji) {
|
|
831
|
-
const clientId =
|
|
832
|
-
const result = await
|
|
1294
|
+
const clientId = chunkXHVQDEVO_js.generateIdempotencyKey();
|
|
1295
|
+
const result = await chunkXHVQDEVO_js.safe(
|
|
833
1296
|
this.client.post(
|
|
834
1297
|
`/api/v1/support/conversation/messages/${messageId}/reactions`,
|
|
835
1298
|
{ emoji, client_id: clientId },
|
|
836
1299
|
{ idempotencyKey: clientId }
|
|
837
1300
|
)
|
|
838
1301
|
);
|
|
839
|
-
return result.ok ?
|
|
1302
|
+
return result.ok ? chunkXHVQDEVO_js.ok(chatMessageFromWire(result.value.message)) : result;
|
|
840
1303
|
}
|
|
841
1304
|
/** Ask for a person: flags the thread for the merchant's inbox. */
|
|
842
1305
|
async requestHuman(opts) {
|
|
843
|
-
const idempotencyKey = opts?.idempotencyKey ??
|
|
844
|
-
return
|
|
1306
|
+
const idempotencyKey = opts?.idempotencyKey ?? chunkXHVQDEVO_js.generateIdempotencyKey();
|
|
1307
|
+
return chunkXHVQDEVO_js.safe(
|
|
845
1308
|
this.client.post(
|
|
846
1309
|
"/api/v1/support/conversation/handoff",
|
|
847
1310
|
void 0,
|
|
@@ -851,459 +1314,108 @@ var SupportService = class {
|
|
|
851
1314
|
}
|
|
852
1315
|
};
|
|
853
1316
|
|
|
854
|
-
// src/
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
try {
|
|
861
|
-
const imported = await import('@paystack/inline-js');
|
|
862
|
-
PaystackPop = imported.default;
|
|
863
|
-
} catch {
|
|
864
|
-
return { success: false, error: "PROVIDER_UNAVAILABLE" };
|
|
865
|
-
}
|
|
866
|
-
return new Promise((resolve) => {
|
|
867
|
-
let settled = false;
|
|
868
|
-
let providerStarted = false;
|
|
869
|
-
const resolveOnce = (result) => {
|
|
870
|
-
if (settled) {
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
settled = true;
|
|
874
|
-
if (signal) {
|
|
875
|
-
signal.removeEventListener("abort", onAbort);
|
|
876
|
-
}
|
|
877
|
-
resolve(result);
|
|
878
|
-
};
|
|
879
|
-
const onAbort = () => {
|
|
880
|
-
resolveOnce({
|
|
881
|
-
success: false,
|
|
882
|
-
// Once Paystack owns the transaction, cancellation is ambiguous. The
|
|
883
|
-
// adapter converts this into submitted so Cimplify polling decides.
|
|
884
|
-
error: providerStarted ? "SUBMISSION_UNKNOWN" : "CANCELLED"
|
|
885
|
-
});
|
|
886
|
-
};
|
|
887
|
-
if (signal?.aborted) {
|
|
888
|
-
resolveOnce({ success: false, error: "CANCELLED" });
|
|
889
|
-
return;
|
|
890
|
-
}
|
|
891
|
-
if (signal) {
|
|
892
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
893
|
-
}
|
|
894
|
-
try {
|
|
895
|
-
const popup = new PaystackPop();
|
|
896
|
-
popup.newTransaction({
|
|
897
|
-
key: options.key,
|
|
898
|
-
email: options.email,
|
|
899
|
-
amount: options.amount,
|
|
900
|
-
currency: options.currency,
|
|
901
|
-
reference: options.reference,
|
|
902
|
-
accessCode: options.accessCode,
|
|
903
|
-
onSuccess: (transaction) => {
|
|
904
|
-
resolveOnce({
|
|
905
|
-
success: true,
|
|
906
|
-
reference: transaction.reference ?? options.reference
|
|
907
|
-
});
|
|
908
|
-
},
|
|
909
|
-
onCancel: () => {
|
|
910
|
-
resolveOnce({ success: false, error: "PAYMENT_CANCELLED" });
|
|
911
|
-
},
|
|
912
|
-
onError: (error) => {
|
|
913
|
-
resolveOnce({
|
|
914
|
-
success: false,
|
|
915
|
-
error: error?.message || "PAYMENT_FAILED"
|
|
916
|
-
});
|
|
917
|
-
}
|
|
918
|
-
});
|
|
919
|
-
providerStarted = true;
|
|
920
|
-
} catch {
|
|
921
|
-
resolveOnce({ success: false, error: "POPUP_BLOCKED" });
|
|
922
|
-
}
|
|
923
|
-
});
|
|
1317
|
+
// src/internal/cross-tab-session.ts
|
|
1318
|
+
var CROSS_TAB_SESSION_HUB_KEY = /* @__PURE__ */ Symbol.for("@cimplify/sdk.cross-tab-session-hub");
|
|
1319
|
+
var SESSION_SYNC_STORAGE_KEY = "cimplify_session_sync";
|
|
1320
|
+
var MAX_RECENT_ENVELOPES = 64;
|
|
1321
|
+
function hubHost() {
|
|
1322
|
+
return window;
|
|
924
1323
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
currency: context.currency
|
|
938
|
-
},
|
|
939
|
-
context.signal
|
|
940
|
-
);
|
|
941
|
-
if (result.success) {
|
|
942
|
-
return { status: "submitted", reference: result.reference || context.reference };
|
|
943
|
-
}
|
|
944
|
-
if (result.error === "SUBMISSION_UNKNOWN") {
|
|
945
|
-
return { status: "submitted", reference: context.reference };
|
|
946
|
-
}
|
|
947
|
-
if (!result.error || result.error === "CANCELLED" || result.error === "PAYMENT_CANCELLED") {
|
|
948
|
-
return { status: "cancelled" };
|
|
949
|
-
}
|
|
950
|
-
if (result.error === "POPUP_BLOCKED") {
|
|
951
|
-
return {
|
|
952
|
-
status: "failed",
|
|
953
|
-
code: "POPUP_BLOCKED",
|
|
954
|
-
message: "Unable to open the Paystack payment popup. Please allow popups and try again.",
|
|
955
|
-
recoverable: true
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
if (result.error === "PROVIDER_UNAVAILABLE") {
|
|
959
|
-
return {
|
|
960
|
-
status: "failed",
|
|
961
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
962
|
-
message: "Paystack is unavailable in this environment.",
|
|
963
|
-
recoverable: false
|
|
964
|
-
};
|
|
965
|
-
}
|
|
966
|
-
return {
|
|
967
|
-
status: "failed",
|
|
968
|
-
code: "PAYMENT_FAILED",
|
|
969
|
-
message: result.error || "Paystack payment could not be submitted.",
|
|
970
|
-
recoverable: true
|
|
971
|
-
};
|
|
1324
|
+
function currentHub() {
|
|
1325
|
+
const candidate = hubHost()[CROSS_TAB_SESSION_HUB_KEY];
|
|
1326
|
+
return candidate?.subscribers instanceof Map && candidate.recentEnvelopes instanceof Set && typeof candidate.storageListener === "function" && typeof candidate.dispatch === "function" ? candidate : null;
|
|
1327
|
+
}
|
|
1328
|
+
function subscriberReference(target) {
|
|
1329
|
+
const WeakReference = globalThis.WeakRef;
|
|
1330
|
+
if (WeakReference) return new WeakReference(target);
|
|
1331
|
+
return { deref: () => target };
|
|
1332
|
+
}
|
|
1333
|
+
function pruneSubscribers(hub) {
|
|
1334
|
+
for (const [token, reference] of hub.subscribers) {
|
|
1335
|
+
if (!reference.deref()) hub.subscribers.delete(token);
|
|
972
1336
|
}
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
async function loadStripeFromPeer(publicKey, options) {
|
|
1337
|
+
}
|
|
1338
|
+
function parseSessionSyncPayload(serialized) {
|
|
1339
|
+
if (!serialized) return null;
|
|
977
1340
|
try {
|
|
978
|
-
const
|
|
979
|
-
return
|
|
1341
|
+
const payload = JSON.parse(serialized);
|
|
1342
|
+
return (payload.type === "claimed" || payload.type === "cleared") && typeof payload.token === "string" && payload.token.length > 0 && typeof payload.at === "number" && Number.isFinite(payload.at) && (payload.name === void 0 || payload.name === null || typeof payload.name === "string") ? payload : null;
|
|
980
1343
|
} catch {
|
|
981
1344
|
return null;
|
|
982
1345
|
}
|
|
983
1346
|
}
|
|
984
|
-
function
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
const root = document.createElement("div");
|
|
988
|
-
root.setAttribute("role", "dialog");
|
|
989
|
-
root.setAttribute("aria-modal", "true");
|
|
990
|
-
root.setAttribute("aria-label", "Secure card payment");
|
|
991
|
-
Object.assign(root.style, {
|
|
992
|
-
position: "fixed",
|
|
993
|
-
inset: "0",
|
|
994
|
-
zIndex: "2147483647",
|
|
995
|
-
display: "grid",
|
|
996
|
-
placeItems: "center",
|
|
997
|
-
padding: "16px",
|
|
998
|
-
background: "rgba(15, 23, 42, 0.58)"
|
|
999
|
-
});
|
|
1000
|
-
const form = document.createElement("form");
|
|
1001
|
-
Object.assign(form.style, {
|
|
1002
|
-
width: "min(100%, 480px)",
|
|
1003
|
-
maxHeight: "calc(100vh - 32px)",
|
|
1004
|
-
overflow: "auto",
|
|
1005
|
-
borderRadius: "12px",
|
|
1006
|
-
padding: "24px",
|
|
1007
|
-
background: "#fff",
|
|
1008
|
-
boxShadow: "0 24px 80px rgba(15, 23, 42, 0.32)"
|
|
1009
|
-
});
|
|
1010
|
-
const title = document.createElement("h2");
|
|
1011
|
-
title.textContent = "Complete card payment";
|
|
1012
|
-
Object.assign(title.style, { margin: "0 0 18px", font: "600 18px/1.4 system-ui" });
|
|
1013
|
-
const paymentMount = document.createElement("div");
|
|
1014
|
-
paymentMount.setAttribute("data-cimplify-stripe-payment-element", "");
|
|
1015
|
-
const error = document.createElement("p");
|
|
1016
|
-
error.setAttribute("role", "alert");
|
|
1017
|
-
Object.assign(error.style, {
|
|
1018
|
-
minHeight: "20px",
|
|
1019
|
-
margin: "14px 0 0",
|
|
1020
|
-
color: "#b91c1c",
|
|
1021
|
-
font: "14px/1.4 system-ui"
|
|
1022
|
-
});
|
|
1023
|
-
const actions = document.createElement("div");
|
|
1024
|
-
Object.assign(actions.style, {
|
|
1025
|
-
display: "flex",
|
|
1026
|
-
justifyContent: "flex-end",
|
|
1027
|
-
gap: "10px",
|
|
1028
|
-
marginTop: "18px"
|
|
1029
|
-
});
|
|
1030
|
-
const cancelButton = document.createElement("button");
|
|
1031
|
-
cancelButton.type = "button";
|
|
1032
|
-
cancelButton.textContent = "Cancel";
|
|
1033
|
-
Object.assign(cancelButton.style, {
|
|
1034
|
-
border: "1px solid #cbd5e1",
|
|
1035
|
-
borderRadius: "8px",
|
|
1036
|
-
padding: "10px 16px",
|
|
1037
|
-
background: "#fff",
|
|
1038
|
-
color: "#0f172a",
|
|
1039
|
-
cursor: "pointer"
|
|
1040
|
-
});
|
|
1041
|
-
const submitButton = document.createElement("button");
|
|
1042
|
-
submitButton.type = "submit";
|
|
1043
|
-
submitButton.textContent = "Pay securely";
|
|
1044
|
-
Object.assign(submitButton.style, {
|
|
1045
|
-
border: "0",
|
|
1046
|
-
borderRadius: "8px",
|
|
1047
|
-
padding: "10px 16px",
|
|
1048
|
-
background: "#0f172a",
|
|
1049
|
-
color: "#fff",
|
|
1050
|
-
cursor: "pointer"
|
|
1051
|
-
});
|
|
1052
|
-
actions.append(cancelButton, submitButton);
|
|
1053
|
-
form.append(title, paymentMount, error, actions);
|
|
1054
|
-
root.append(form);
|
|
1055
|
-
document.body.append(root);
|
|
1056
|
-
cancelButton.focus();
|
|
1057
|
-
return { root, form, paymentMount, submitButton, cancelButton, error, previousFocus };
|
|
1347
|
+
function sessionSyncEnvelopeKey(payload) {
|
|
1348
|
+
const name = payload.name === void 0 ? ["missing"] : ["present", payload.name];
|
|
1349
|
+
return JSON.stringify([payload.type, payload.token, name, payload.at]);
|
|
1058
1350
|
}
|
|
1059
|
-
function
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
};
|
|
1068
|
-
}
|
|
1069
|
-
return { status: "failed", code: "PAYMENT_FAILED", message, recoverable: true };
|
|
1351
|
+
function rememberEnvelope(hub, envelope) {
|
|
1352
|
+
if (hub.recentEnvelopes.has(envelope)) return false;
|
|
1353
|
+
hub.recentEnvelopes.add(envelope);
|
|
1354
|
+
if (hub.recentEnvelopes.size > MAX_RECENT_ENVELOPES) {
|
|
1355
|
+
const oldest = hub.recentEnvelopes.values().next().value;
|
|
1356
|
+
if (oldest) hub.recentEnvelopes.delete(oldest);
|
|
1357
|
+
}
|
|
1358
|
+
return true;
|
|
1070
1359
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
if (
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
context.action.public_key,
|
|
1089
|
-
context.action.provider_account_id ? { stripeAccount: context.action.provider_account_id } : void 0
|
|
1090
|
-
);
|
|
1091
|
-
} catch (error) {
|
|
1092
|
-
return {
|
|
1093
|
-
status: "failed",
|
|
1094
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
1095
|
-
message: error instanceof Error ? error.message : "Stripe.js could not be loaded.",
|
|
1096
|
-
recoverable: true
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
if (context.signal?.aborted) {
|
|
1100
|
-
return { status: "cancelled" };
|
|
1101
|
-
}
|
|
1102
|
-
if (!stripe) {
|
|
1103
|
-
return {
|
|
1104
|
-
status: "failed",
|
|
1105
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
1106
|
-
message: "Stripe.js could not be loaded.",
|
|
1107
|
-
recoverable: false
|
|
1108
|
-
};
|
|
1109
|
-
}
|
|
1110
|
-
const modal = createStripeModal();
|
|
1111
|
-
if (!modal) {
|
|
1112
|
-
return {
|
|
1113
|
-
status: "failed",
|
|
1114
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
1115
|
-
message: "Stripe Payment Element could not be mounted.",
|
|
1116
|
-
recoverable: false
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
let paymentElement;
|
|
1120
|
-
let elements;
|
|
1121
|
-
try {
|
|
1122
|
-
elements = stripe.elements({ clientSecret: context.action.client_secret });
|
|
1123
|
-
paymentElement = elements.create("payment");
|
|
1124
|
-
paymentElement.mount(modal.paymentMount);
|
|
1125
|
-
} catch {
|
|
1126
|
-
modal.root.remove();
|
|
1127
|
-
modal.previousFocus?.focus();
|
|
1128
|
-
return {
|
|
1129
|
-
status: "failed",
|
|
1130
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
1131
|
-
message: "Stripe Payment Element could not be initialized.",
|
|
1132
|
-
recoverable: false
|
|
1133
|
-
};
|
|
1360
|
+
function createHub() {
|
|
1361
|
+
const hub = {
|
|
1362
|
+
subscribers: /* @__PURE__ */ new Map(),
|
|
1363
|
+
recentEnvelopes: /* @__PURE__ */ new Set()
|
|
1364
|
+
};
|
|
1365
|
+
hub.dispatch = (payload) => {
|
|
1366
|
+
if (!rememberEnvelope(hub, sessionSyncEnvelopeKey(payload))) return;
|
|
1367
|
+
for (const [token, reference] of hub.subscribers) {
|
|
1368
|
+
const subscriber = reference.deref();
|
|
1369
|
+
if (!subscriber) {
|
|
1370
|
+
hub.subscribers.delete(token);
|
|
1371
|
+
continue;
|
|
1372
|
+
}
|
|
1373
|
+
try {
|
|
1374
|
+
subscriber.notify(payload);
|
|
1375
|
+
} catch {
|
|
1376
|
+
}
|
|
1134
1377
|
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
let confirmationStarted = false;
|
|
1146
|
-
const cleanup = () => {
|
|
1147
|
-
context.signal?.removeEventListener("abort", onAbort);
|
|
1148
|
-
modal.form.removeEventListener("submit", onSubmit);
|
|
1149
|
-
modal.cancelButton.removeEventListener("click", onCancel);
|
|
1150
|
-
if (paymentElement.destroy) paymentElement.destroy();
|
|
1151
|
-
else paymentElement.unmount?.();
|
|
1152
|
-
modal.root.remove();
|
|
1153
|
-
modal.previousFocus?.focus();
|
|
1154
|
-
};
|
|
1155
|
-
const settle = (outcome) => {
|
|
1156
|
-
if (settled) return;
|
|
1157
|
-
settled = true;
|
|
1158
|
-
cleanup();
|
|
1159
|
-
resolve(outcome);
|
|
1160
|
-
};
|
|
1161
|
-
const onAbort = () => {
|
|
1162
|
-
if (confirmationStarted) {
|
|
1163
|
-
settle({ status: "submitted", reference: context.reference });
|
|
1164
|
-
return;
|
|
1165
|
-
}
|
|
1166
|
-
settle({ status: "cancelled" });
|
|
1167
|
-
};
|
|
1168
|
-
const onCancel = () => {
|
|
1169
|
-
if (!confirmationStarted) settle({ status: "cancelled" });
|
|
1170
|
-
};
|
|
1171
|
-
const onSubmit = async (event) => {
|
|
1172
|
-
event.preventDefault();
|
|
1173
|
-
if (submitting || settled) return;
|
|
1174
|
-
submitting = true;
|
|
1175
|
-
modal.submitButton.disabled = true;
|
|
1176
|
-
modal.error.textContent = "";
|
|
1177
|
-
try {
|
|
1178
|
-
const validation = elements.submit ? await elements.submit() : {};
|
|
1179
|
-
if (validation.error) {
|
|
1180
|
-
modal.error.textContent = validation.error.message || "Check your payment details.";
|
|
1181
|
-
submitting = false;
|
|
1182
|
-
modal.submitButton.disabled = false;
|
|
1183
|
-
return;
|
|
1184
|
-
}
|
|
1185
|
-
if (settled || context.signal?.aborted) {
|
|
1186
|
-
settle({ status: "cancelled" });
|
|
1187
|
-
return;
|
|
1188
|
-
}
|
|
1189
|
-
confirmationStarted = true;
|
|
1190
|
-
modal.cancelButton.disabled = true;
|
|
1191
|
-
const confirmation = await stripe.confirmPayment({
|
|
1192
|
-
elements,
|
|
1193
|
-
confirmParams: { return_url: context.returnUrl || window.location.href },
|
|
1194
|
-
redirect: "if_required"
|
|
1195
|
-
});
|
|
1196
|
-
if (settled) return;
|
|
1197
|
-
if (confirmation.error) {
|
|
1198
|
-
settle(stripeFailure(confirmation.error));
|
|
1199
|
-
return;
|
|
1200
|
-
}
|
|
1201
|
-
settle({
|
|
1202
|
-
status: "submitted",
|
|
1203
|
-
reference: confirmation.paymentIntent?.id || context.reference
|
|
1204
|
-
});
|
|
1205
|
-
} catch (error) {
|
|
1206
|
-
if (confirmationStarted) {
|
|
1207
|
-
settle({ status: "submitted", reference: context.reference });
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
settle(
|
|
1211
|
-
stripeFailure({
|
|
1212
|
-
message: error instanceof Error ? error.message : "Stripe confirmation failed."
|
|
1213
|
-
})
|
|
1214
|
-
);
|
|
1215
|
-
}
|
|
1216
|
-
};
|
|
1217
|
-
modal.form.addEventListener("submit", onSubmit);
|
|
1218
|
-
modal.cancelButton.addEventListener("click", onCancel);
|
|
1219
|
-
context.signal?.addEventListener("abort", onAbort, { once: true });
|
|
1220
|
-
paymentElement.on?.("escape", onCancel);
|
|
1221
|
-
paymentElement.on?.("loaderror", (event) => {
|
|
1222
|
-
if (confirmationStarted) return;
|
|
1223
|
-
settle({
|
|
1224
|
-
status: "failed",
|
|
1225
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
1226
|
-
message: event?.error?.message || "Stripe Payment Element failed to load.",
|
|
1227
|
-
recoverable: true
|
|
1228
|
-
});
|
|
1229
|
-
});
|
|
1230
|
-
});
|
|
1231
|
-
}
|
|
1232
|
-
};
|
|
1233
|
-
|
|
1234
|
-
// src/payment-authorization/registry.ts
|
|
1235
|
-
function normalizeProvider(provider) {
|
|
1236
|
-
return typeof provider === "string" ? provider.trim().toLowerCase() : "";
|
|
1378
|
+
};
|
|
1379
|
+
hub.storageListener = (event) => {
|
|
1380
|
+
const storageEvent = event;
|
|
1381
|
+
if (storageEvent.key !== SESSION_SYNC_STORAGE_KEY) return;
|
|
1382
|
+
const payload = parseSessionSyncPayload(storageEvent.newValue);
|
|
1383
|
+
if (payload) hub.dispatch(payload);
|
|
1384
|
+
};
|
|
1385
|
+
window.addEventListener("storage", hub.storageListener);
|
|
1386
|
+
hubHost()[CROSS_TAB_SESSION_HUB_KEY] = hub;
|
|
1387
|
+
return hub;
|
|
1237
1388
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
const provider = normalizeProvider(adapter.provider);
|
|
1247
|
-
if (!provider) {
|
|
1248
|
-
throw new TypeError("Payment authorization adapter provider cannot be empty.");
|
|
1249
|
-
}
|
|
1250
|
-
this.adapters.set(provider, adapter);
|
|
1251
|
-
return this;
|
|
1252
|
-
}
|
|
1253
|
-
unregister(provider) {
|
|
1254
|
-
return this.adapters.delete(normalizeProvider(provider));
|
|
1255
|
-
}
|
|
1256
|
-
get(provider) {
|
|
1257
|
-
return this.adapters.get(normalizeProvider(provider));
|
|
1258
|
-
}
|
|
1259
|
-
supports(provider) {
|
|
1260
|
-
return this.adapters.has(normalizeProvider(provider));
|
|
1261
|
-
}
|
|
1262
|
-
providers() {
|
|
1263
|
-
return [...this.adapters.keys()];
|
|
1264
|
-
}
|
|
1265
|
-
async authorize(action, options) {
|
|
1266
|
-
const provider = normalizeProvider(action.provider);
|
|
1267
|
-
if (!provider) {
|
|
1268
|
-
return {
|
|
1269
|
-
status: "failed",
|
|
1270
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
1271
|
-
message: "Card authorization response did not identify a payment provider.",
|
|
1272
|
-
recoverable: false
|
|
1273
|
-
};
|
|
1274
|
-
}
|
|
1275
|
-
const adapter = this.adapters.get(provider);
|
|
1276
|
-
if (!adapter) {
|
|
1277
|
-
return {
|
|
1278
|
-
status: "failed",
|
|
1279
|
-
code: "PROVIDER_UNAVAILABLE",
|
|
1280
|
-
message: `Card authorization provider '${provider}' is not supported by this SDK client.`,
|
|
1281
|
-
recoverable: false
|
|
1282
|
-
};
|
|
1283
|
-
}
|
|
1284
|
-
try {
|
|
1285
|
-
const normalizedAction = action.provider === provider ? action : { ...action, provider };
|
|
1286
|
-
return await adapter.authorize({ ...options, action: normalizedAction });
|
|
1287
|
-
} catch (error) {
|
|
1288
|
-
return {
|
|
1289
|
-
status: "failed",
|
|
1290
|
-
code: "PAYMENT_FAILED",
|
|
1291
|
-
message: error instanceof Error ? error.message : `Card authorization provider '${provider}' failed unexpectedly.`,
|
|
1292
|
-
recoverable: true
|
|
1293
|
-
};
|
|
1294
|
-
}
|
|
1389
|
+
function publishLocalSessionSync(payload) {
|
|
1390
|
+
if (typeof window === "undefined" || typeof window.addEventListener !== "function") return;
|
|
1391
|
+
(currentHub() ?? createHub()).dispatch(payload);
|
|
1392
|
+
}
|
|
1393
|
+
function subscribeCrossTabSession(notify) {
|
|
1394
|
+
if (typeof window === "undefined" || typeof window.addEventListener !== "function") {
|
|
1395
|
+
return () => {
|
|
1396
|
+
};
|
|
1295
1397
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1398
|
+
const hub = currentHub() ?? createHub();
|
|
1399
|
+
pruneSubscribers(hub);
|
|
1400
|
+
const token = /* @__PURE__ */ Symbol("cross-tab-session-subscriber");
|
|
1401
|
+
const subscriber = { notify };
|
|
1402
|
+
hub.subscribers.set(token, subscriberReference(subscriber));
|
|
1403
|
+
let unsubscribed = false;
|
|
1404
|
+
return () => {
|
|
1405
|
+
if (unsubscribed) return;
|
|
1406
|
+
unsubscribed = true;
|
|
1407
|
+
subscriber.notify = () => {
|
|
1408
|
+
};
|
|
1409
|
+
hub.subscribers.delete(token);
|
|
1410
|
+
pruneSubscribers(hub);
|
|
1411
|
+
if (hub.subscribers.size !== 0) return;
|
|
1412
|
+
window.removeEventListener("storage", hub.storageListener);
|
|
1413
|
+
if (currentHub() === hub) delete hubHost()[CROSS_TAB_SESSION_HUB_KEY];
|
|
1414
|
+
};
|
|
1302
1415
|
}
|
|
1303
1416
|
|
|
1304
1417
|
// src/client.ts
|
|
1305
1418
|
var SESSION_TOKEN_STORAGE_KEY = "cimplify_session_token";
|
|
1306
|
-
var SESSION_SYNC_STORAGE_KEY = "cimplify_session_sync";
|
|
1307
1419
|
var ORDER_TOKEN_PREFIX = "cimplify_ot_";
|
|
1308
1420
|
var SESSION_TOKEN_HEADER = "x-session-token";
|
|
1309
1421
|
var LOCATION_ID_QUERY_PARAMETER = "location_id";
|
|
@@ -1311,8 +1423,37 @@ var ORDER_TOKEN_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
|
1311
1423
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
1312
1424
|
var DEFAULT_MAX_RETRIES = 3;
|
|
1313
1425
|
var DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
1314
|
-
|
|
1315
|
-
|
|
1426
|
+
var MAX_RETRY_AFTER_MS = 3e4;
|
|
1427
|
+
function sleep(ms, signal) {
|
|
1428
|
+
if (signal?.aborted) {
|
|
1429
|
+
return Promise.reject(new chunkAVXA4F6G_js.CimplifyError(chunkAVXA4F6G_js.ErrorCode.CANCELLED, "Request was cancelled.", true));
|
|
1430
|
+
}
|
|
1431
|
+
return new Promise((resolve, reject) => {
|
|
1432
|
+
const timer = setTimeout(() => {
|
|
1433
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1434
|
+
resolve();
|
|
1435
|
+
}, ms);
|
|
1436
|
+
const onAbort = () => {
|
|
1437
|
+
clearTimeout(timer);
|
|
1438
|
+
reject(new chunkAVXA4F6G_js.CimplifyError(chunkAVXA4F6G_js.ErrorCode.CANCELLED, "Request was cancelled.", true));
|
|
1439
|
+
};
|
|
1440
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1443
|
+
function parseRetryAfterMs(value) {
|
|
1444
|
+
if (!value) return null;
|
|
1445
|
+
const seconds = Number(value);
|
|
1446
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
1447
|
+
return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
|
|
1448
|
+
}
|
|
1449
|
+
const retryAt = Date.parse(value);
|
|
1450
|
+
if (!Number.isFinite(retryAt)) return null;
|
|
1451
|
+
return Math.min(Math.max(0, retryAt - Date.now()), MAX_RETRY_AFTER_MS);
|
|
1452
|
+
}
|
|
1453
|
+
function withPositiveJitter(delayMs, jitterRatio = 0) {
|
|
1454
|
+
const boundedRatio = Math.min(Math.max(jitterRatio, 0), 1);
|
|
1455
|
+
if (boundedRatio === 0 || delayMs === 0) return delayMs;
|
|
1456
|
+
return Math.round(delayMs + delayMs * boundedRatio * Math.random());
|
|
1316
1457
|
}
|
|
1317
1458
|
function nextInit(cacheOptions) {
|
|
1318
1459
|
if (!cacheOptions) return {};
|
|
@@ -1352,16 +1493,16 @@ function isRetryable(error) {
|
|
|
1352
1493
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
1353
1494
|
return true;
|
|
1354
1495
|
}
|
|
1355
|
-
if (error instanceof
|
|
1496
|
+
if (error instanceof chunkAVXA4F6G_js.CimplifyError) {
|
|
1356
1497
|
return error.retryable;
|
|
1357
1498
|
}
|
|
1358
1499
|
return false;
|
|
1359
1500
|
}
|
|
1360
1501
|
function toNetworkError(error, isTestMode) {
|
|
1361
1502
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
1362
|
-
return
|
|
1363
|
-
new
|
|
1364
|
-
|
|
1503
|
+
return chunkAVXA4F6G_js.enrichError(
|
|
1504
|
+
new chunkAVXA4F6G_js.CimplifyError(
|
|
1505
|
+
chunkAVXA4F6G_js.ErrorCode.TIMEOUT,
|
|
1365
1506
|
"Request timed out. Please check your connection and try again.",
|
|
1366
1507
|
true
|
|
1367
1508
|
),
|
|
@@ -1369,21 +1510,21 @@ function toNetworkError(error, isTestMode) {
|
|
|
1369
1510
|
);
|
|
1370
1511
|
}
|
|
1371
1512
|
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
1372
|
-
return
|
|
1373
|
-
new
|
|
1374
|
-
|
|
1513
|
+
return chunkAVXA4F6G_js.enrichError(
|
|
1514
|
+
new chunkAVXA4F6G_js.CimplifyError(
|
|
1515
|
+
chunkAVXA4F6G_js.ErrorCode.NETWORK_ERROR,
|
|
1375
1516
|
"Network error. Please check your internet connection.",
|
|
1376
1517
|
true
|
|
1377
1518
|
),
|
|
1378
1519
|
{ isTestMode }
|
|
1379
1520
|
);
|
|
1380
1521
|
}
|
|
1381
|
-
if (error instanceof
|
|
1382
|
-
return
|
|
1522
|
+
if (error instanceof chunkAVXA4F6G_js.CimplifyError) {
|
|
1523
|
+
return chunkAVXA4F6G_js.enrichError(error, { isTestMode });
|
|
1383
1524
|
}
|
|
1384
|
-
return
|
|
1385
|
-
new
|
|
1386
|
-
|
|
1525
|
+
return chunkAVXA4F6G_js.enrichError(
|
|
1526
|
+
new chunkAVXA4F6G_js.CimplifyError(
|
|
1527
|
+
chunkAVXA4F6G_js.ErrorCode.UNKNOWN_ERROR,
|
|
1387
1528
|
error instanceof Error ? error.message : "An unknown error occurred",
|
|
1388
1529
|
false
|
|
1389
1530
|
),
|
|
@@ -1426,6 +1567,9 @@ var CimplifyClient = class {
|
|
|
1426
1567
|
this.businessId = null;
|
|
1427
1568
|
this.businessIdResolvePromise = null;
|
|
1428
1569
|
this.publicKeyEpoch = 0;
|
|
1570
|
+
this.stopCrossTabSessionWatch = null;
|
|
1571
|
+
this.latestSessionSyncAt = Number.NEGATIVE_INFINITY;
|
|
1572
|
+
this.latestSessionSyncOrderKey = null;
|
|
1429
1573
|
this.inflightRequests = /* @__PURE__ */ new Map();
|
|
1430
1574
|
/**
|
|
1431
1575
|
* App-level event channel. Subscribe to surface mutation rollbacks, outbox
|
|
@@ -1444,10 +1588,14 @@ var CimplifyClient = class {
|
|
|
1444
1588
|
this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
1445
1589
|
this.retryDelay = config.retryDelay ?? DEFAULT_RETRY_DELAY_MS;
|
|
1446
1590
|
this.hooks = config.hooks ?? {};
|
|
1447
|
-
this.authorizationAdapters = config.authorizationAdapterRegistry ?? createDefaultPaymentAuthorizationAdapterRegistry();
|
|
1591
|
+
this.authorizationAdapters = config.authorizationAdapterRegistry ?? chunkXHVQDEVO_js.createDefaultPaymentAuthorizationAdapterRegistry();
|
|
1448
1592
|
this.fetchImpl = (config.fetch ?? globalThis.fetch).bind(globalThis);
|
|
1449
1593
|
this.sessionToken = this.loadSessionToken() ?? this.mintSessionToken();
|
|
1450
|
-
this.
|
|
1594
|
+
const persistedSessionSync = this.loadSessionSyncPayload();
|
|
1595
|
+
if (persistedSessionSync) this.observeSessionSync(persistedSessionSync);
|
|
1596
|
+
this.stopCrossTabSessionWatch = subscribeCrossTabSession((payload) => {
|
|
1597
|
+
this.applyCrossTabSession(payload);
|
|
1598
|
+
});
|
|
1451
1599
|
if (!this.publicKey && !config.suppressPublicKeyWarning) {
|
|
1452
1600
|
console.warn(
|
|
1453
1601
|
'[Cimplify] No public key found. Set NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY in your environment, or pass { publicKey: "cpk_..." } to createCimplifyClient().'
|
|
@@ -1474,6 +1622,12 @@ var CimplifyClient = class {
|
|
|
1474
1622
|
this.stopPageViewTracking?.();
|
|
1475
1623
|
this.stopPageViewTracking = null;
|
|
1476
1624
|
}
|
|
1625
|
+
/** Release window-level subscriptions and automatic tracking owned by this client. */
|
|
1626
|
+
destroy() {
|
|
1627
|
+
this.stopTrackingPageViews();
|
|
1628
|
+
this.stopCrossTabSessionWatch?.();
|
|
1629
|
+
this.stopCrossTabSessionWatch = null;
|
|
1630
|
+
}
|
|
1477
1631
|
getAccessToken() {
|
|
1478
1632
|
return this.accessToken;
|
|
1479
1633
|
}
|
|
@@ -1501,7 +1655,7 @@ var CimplifyClient = class {
|
|
|
1501
1655
|
this.hooks.onSessionChange?.({
|
|
1502
1656
|
previousToken: previous,
|
|
1503
1657
|
newToken: token,
|
|
1504
|
-
source:
|
|
1658
|
+
source: SESSION_CHANGE_SOURCE.MANUAL
|
|
1505
1659
|
});
|
|
1506
1660
|
this.events.emit(AUTH_TOKEN_CHANGED, { token });
|
|
1507
1661
|
}
|
|
@@ -1545,7 +1699,7 @@ var CimplifyClient = class {
|
|
|
1545
1699
|
this.hooks.onSessionChange?.({
|
|
1546
1700
|
previousToken: previous,
|
|
1547
1701
|
newToken: null,
|
|
1548
|
-
source:
|
|
1702
|
+
source: SESSION_CHANGE_SOURCE.CLEAR
|
|
1549
1703
|
});
|
|
1550
1704
|
this.events.emit(AUTH_TOKEN_CHANGED, { token: null });
|
|
1551
1705
|
this.events.emit(SESSION_CLEARED, {});
|
|
@@ -1567,9 +1721,10 @@ var CimplifyClient = class {
|
|
|
1567
1721
|
hasClaimedSessionAuthority() {
|
|
1568
1722
|
if (!this.sessionToken) return false;
|
|
1569
1723
|
try {
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
-
|
|
1724
|
+
const payload = parseSessionSyncPayload(
|
|
1725
|
+
this.safeStorage()?.getItem(SESSION_SYNC_STORAGE_KEY) ?? null
|
|
1726
|
+
);
|
|
1727
|
+
if (!payload) return false;
|
|
1573
1728
|
return payload.type === "claimed" && payload.token === this.sessionToken;
|
|
1574
1729
|
} catch {
|
|
1575
1730
|
return false;
|
|
@@ -1584,41 +1739,49 @@ var CimplifyClient = class {
|
|
|
1584
1739
|
});
|
|
1585
1740
|
}
|
|
1586
1741
|
broadcastSessionSync(payload) {
|
|
1742
|
+
const envelope = {
|
|
1743
|
+
...payload,
|
|
1744
|
+
at: this.nextSessionSyncTimestamp()
|
|
1745
|
+
};
|
|
1587
1746
|
try {
|
|
1588
|
-
this.safeStorage()?.setItem(
|
|
1589
|
-
SESSION_SYNC_STORAGE_KEY,
|
|
1590
|
-
JSON.stringify({ ...payload, at: Date.now() })
|
|
1591
|
-
);
|
|
1747
|
+
this.safeStorage()?.setItem(SESSION_SYNC_STORAGE_KEY, JSON.stringify(envelope));
|
|
1592
1748
|
} catch {
|
|
1593
1749
|
}
|
|
1750
|
+
publishLocalSessionSync(envelope);
|
|
1594
1751
|
}
|
|
1595
|
-
|
|
1596
|
-
if (
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1752
|
+
applyCrossTabSession(payload) {
|
|
1753
|
+
if (!this.observeSessionSync(payload)) return;
|
|
1754
|
+
if (payload.token === this.sessionToken) return;
|
|
1755
|
+
if (payload.type === "claimed") {
|
|
1756
|
+
this.sessionToken = payload.token;
|
|
1757
|
+
this.sessionEpoch++;
|
|
1758
|
+
this.events.emit(SESSION_CLAIMED, {
|
|
1759
|
+
sessionToken: payload.token,
|
|
1760
|
+
threadId: null,
|
|
1761
|
+
customerName: payload.name ?? ""
|
|
1762
|
+
});
|
|
1763
|
+
} else {
|
|
1764
|
+
this.accessToken = null;
|
|
1765
|
+
this._activity?.resetSession();
|
|
1766
|
+
this.sessionToken = payload.token;
|
|
1767
|
+
this.sessionEpoch++;
|
|
1768
|
+
this.events.emit(AUTH_TOKEN_CHANGED, { token: null });
|
|
1769
|
+
this.events.emit(SESSION_CLEARED, {});
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
observeSessionSync(payload) {
|
|
1773
|
+
if (payload.at < this.latestSessionSyncAt) return false;
|
|
1774
|
+
const envelope = sessionSyncEnvelopeKey(payload);
|
|
1775
|
+
if (payload.at === this.latestSessionSyncAt && this.latestSessionSyncOrderKey !== null && envelope <= this.latestSessionSyncOrderKey) {
|
|
1776
|
+
return false;
|
|
1777
|
+
}
|
|
1778
|
+
this.latestSessionSyncAt = payload.at;
|
|
1779
|
+
this.latestSessionSyncOrderKey = envelope;
|
|
1780
|
+
return true;
|
|
1781
|
+
}
|
|
1782
|
+
nextSessionSyncTimestamp() {
|
|
1783
|
+
const now = Date.now();
|
|
1784
|
+
return Number.isFinite(this.latestSessionSyncAt) ? Math.max(now, this.latestSessionSyncAt + 1) : now;
|
|
1622
1785
|
}
|
|
1623
1786
|
setOrderToken(orderId, token) {
|
|
1624
1787
|
try {
|
|
@@ -1682,17 +1845,24 @@ var CimplifyClient = class {
|
|
|
1682
1845
|
setPublicKey(publicKey) {
|
|
1683
1846
|
const normalized = publicKey.trim();
|
|
1684
1847
|
if (normalized === this.publicKey) return;
|
|
1848
|
+
const restartPageViewTracking = this.stopPageViewTracking !== null;
|
|
1849
|
+
if (restartPageViewTracking) {
|
|
1850
|
+
this.stopTrackingPageViews();
|
|
1851
|
+
}
|
|
1685
1852
|
this.publicKey = normalized;
|
|
1686
1853
|
this.publicKeyEpoch += 1;
|
|
1687
1854
|
this.businessId = null;
|
|
1688
1855
|
this.businessIdResolvePromise = null;
|
|
1689
1856
|
this.inflightRequests.clear();
|
|
1690
|
-
this._activity?.
|
|
1857
|
+
this._activity?.resetForStorefrontIdentityChange();
|
|
1691
1858
|
delete this.context.location_id;
|
|
1692
1859
|
if (this.accessToken !== null) {
|
|
1693
1860
|
this.setAccessToken(null);
|
|
1694
1861
|
}
|
|
1695
1862
|
this.events.emit(SESSION_CLEARED, {});
|
|
1863
|
+
if (restartPageViewTracking) {
|
|
1864
|
+
this.stopPageViewTracking = this.activity.autoTrackPageViews();
|
|
1865
|
+
}
|
|
1696
1866
|
}
|
|
1697
1867
|
getBusinessId() {
|
|
1698
1868
|
return this.businessId;
|
|
@@ -1708,15 +1878,15 @@ var CimplifyClient = class {
|
|
|
1708
1878
|
const resolution = (async () => {
|
|
1709
1879
|
const result = await this.business.getInfo();
|
|
1710
1880
|
if (!result.ok || !result.value?.id) {
|
|
1711
|
-
throw new
|
|
1712
|
-
|
|
1881
|
+
throw new chunkAVXA4F6G_js.CimplifyError(
|
|
1882
|
+
chunkAVXA4F6G_js.ErrorCode.NOT_FOUND,
|
|
1713
1883
|
"Unable to resolve business ID from the current public key.",
|
|
1714
1884
|
true
|
|
1715
1885
|
);
|
|
1716
1886
|
}
|
|
1717
1887
|
if (this.publicKeyEpoch !== publicKeyEpoch) {
|
|
1718
|
-
throw new
|
|
1719
|
-
|
|
1888
|
+
throw new chunkAVXA4F6G_js.CimplifyError(
|
|
1889
|
+
chunkAVXA4F6G_js.ErrorCode.TENANT_CONTEXT_CHANGED,
|
|
1720
1890
|
"The storefront tenant changed while resolving its business identity.",
|
|
1721
1891
|
true
|
|
1722
1892
|
);
|
|
@@ -1733,8 +1903,8 @@ var CimplifyClient = class {
|
|
|
1733
1903
|
}
|
|
1734
1904
|
}
|
|
1735
1905
|
}
|
|
1736
|
-
async authedFetch(url, options, timeoutMs) {
|
|
1737
|
-
return this.resilientFetch(url, options, timeoutMs);
|
|
1906
|
+
async authedFetch(url, options, timeoutMs, retryPolicy, signal) {
|
|
1907
|
+
return this.resilientFetch(url, options, timeoutMs, retryPolicy, signal);
|
|
1738
1908
|
}
|
|
1739
1909
|
// Storage guards: even the `window.localStorage` property access throws in
|
|
1740
1910
|
// some sandboxed iframes and strict private-browsing modes. These run in the
|
|
@@ -1756,6 +1926,13 @@ var CimplifyClient = class {
|
|
|
1756
1926
|
return null;
|
|
1757
1927
|
}
|
|
1758
1928
|
}
|
|
1929
|
+
loadSessionSyncPayload() {
|
|
1930
|
+
try {
|
|
1931
|
+
return parseSessionSyncPayload(this.safeStorage()?.getItem(SESSION_SYNC_STORAGE_KEY) ?? null);
|
|
1932
|
+
} catch {
|
|
1933
|
+
return null;
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1759
1936
|
/**
|
|
1760
1937
|
* Mint the session token client-side so the very first request already
|
|
1761
1938
|
* carries it. Without this, parallel first-load requests each get a
|
|
@@ -1811,7 +1988,7 @@ var CimplifyClient = class {
|
|
|
1811
1988
|
}
|
|
1812
1989
|
return headers;
|
|
1813
1990
|
}
|
|
1814
|
-
async resilientFetch(url, options, timeoutMs) {
|
|
1991
|
+
async resilientFetch(url, options, timeoutMs, retryPolicy, signal) {
|
|
1815
1992
|
const method = options.method || "GET";
|
|
1816
1993
|
const path = url.replace(this.baseUrl, "").replace(this.linkApiUrl, "");
|
|
1817
1994
|
const startTime = Date.now();
|
|
@@ -1825,15 +2002,31 @@ var CimplifyClient = class {
|
|
|
1825
2002
|
};
|
|
1826
2003
|
this.hooks.onRequestStart?.(context);
|
|
1827
2004
|
let lastError;
|
|
1828
|
-
|
|
2005
|
+
const configuredMaxRetries = Math.max(0, Math.floor(this.maxRetries));
|
|
2006
|
+
const maxRetries = Math.min(
|
|
2007
|
+
configuredMaxRetries,
|
|
2008
|
+
Math.max(0, Math.floor(retryPolicy?.maxRetries ?? configuredMaxRetries))
|
|
2009
|
+
);
|
|
2010
|
+
const jitterRatio = retryPolicy?.jitterRatio ?? 0;
|
|
2011
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
1829
2012
|
try {
|
|
2013
|
+
if (signal?.aborted) {
|
|
2014
|
+
throw new chunkAVXA4F6G_js.CimplifyError(chunkAVXA4F6G_js.ErrorCode.CANCELLED, "Request was cancelled.", true);
|
|
2015
|
+
}
|
|
1830
2016
|
const controller = new AbortController();
|
|
1831
2017
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs ?? this.timeout);
|
|
1832
|
-
const
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
2018
|
+
const onAbort = () => controller.abort();
|
|
2019
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
2020
|
+
let response;
|
|
2021
|
+
try {
|
|
2022
|
+
response = await this.fetchImpl(url, {
|
|
2023
|
+
...options,
|
|
2024
|
+
signal: controller.signal
|
|
2025
|
+
});
|
|
2026
|
+
} finally {
|
|
2027
|
+
clearTimeout(timeoutId);
|
|
2028
|
+
signal?.removeEventListener("abort", onAbort);
|
|
2029
|
+
}
|
|
1837
2030
|
this.captureSessionToken(response);
|
|
1838
2031
|
if (response.ok) {
|
|
1839
2032
|
this.hooks.onRequestSuccess?.({
|
|
@@ -1843,23 +2036,25 @@ var CimplifyClient = class {
|
|
|
1843
2036
|
});
|
|
1844
2037
|
return response;
|
|
1845
2038
|
}
|
|
1846
|
-
if ((response.status === 429 || response.status === 503) && attempt <
|
|
2039
|
+
if ((response.status === 429 || response.status === 503) && attempt < maxRetries) {
|
|
1847
2040
|
retryCount++;
|
|
1848
|
-
const
|
|
1849
|
-
const
|
|
2041
|
+
const retryAfterMs = parseRetryAfterMs(response.headers.get("Retry-After"));
|
|
2042
|
+
const retryBaseMs = retryAfterMs ?? this.retryDelay * Math.pow(2, attempt);
|
|
2043
|
+
const jitteredDelayMs = withPositiveJitter(retryBaseMs, jitterRatio);
|
|
2044
|
+
const delay = retryAfterMs === null ? jitteredDelayMs : Math.min(jitteredDelayMs, MAX_RETRY_AFTER_MS);
|
|
1850
2045
|
this.hooks.onRetry?.({
|
|
1851
2046
|
...context,
|
|
1852
2047
|
attempt: retryCount,
|
|
1853
2048
|
delayMs: delay,
|
|
1854
2049
|
error: new Error(`Retryable: ${response.status}`)
|
|
1855
2050
|
});
|
|
1856
|
-
await sleep(delay);
|
|
2051
|
+
await sleep(delay, signal);
|
|
1857
2052
|
continue;
|
|
1858
2053
|
}
|
|
1859
2054
|
if (response.status >= 400 && response.status < 500) {
|
|
1860
2055
|
this.hooks.onRequestError?.({
|
|
1861
2056
|
...context,
|
|
1862
|
-
error: new
|
|
2057
|
+
error: new chunkAVXA4F6G_js.CimplifyError(
|
|
1863
2058
|
`HTTP_${response.status}`,
|
|
1864
2059
|
`Request failed with status ${response.status}`,
|
|
1865
2060
|
false
|
|
@@ -1871,22 +2066,22 @@ var CimplifyClient = class {
|
|
|
1871
2066
|
});
|
|
1872
2067
|
return response;
|
|
1873
2068
|
}
|
|
1874
|
-
if (response.status >= 500 && attempt <
|
|
2069
|
+
if (response.status >= 500 && attempt < maxRetries) {
|
|
1875
2070
|
retryCount++;
|
|
1876
|
-
const delay = this.retryDelay * Math.pow(2, attempt);
|
|
2071
|
+
const delay = withPositiveJitter(this.retryDelay * Math.pow(2, attempt), jitterRatio);
|
|
1877
2072
|
this.hooks.onRetry?.({
|
|
1878
2073
|
...context,
|
|
1879
2074
|
attempt: retryCount,
|
|
1880
2075
|
delayMs: delay,
|
|
1881
2076
|
error: new Error(`Server error: ${response.status}`)
|
|
1882
2077
|
});
|
|
1883
|
-
await sleep(delay);
|
|
2078
|
+
await sleep(delay, signal);
|
|
1884
2079
|
continue;
|
|
1885
2080
|
}
|
|
1886
2081
|
this.hooks.onRequestError?.({
|
|
1887
2082
|
...context,
|
|
1888
|
-
error: new
|
|
1889
|
-
|
|
2083
|
+
error: new chunkAVXA4F6G_js.CimplifyError(
|
|
2084
|
+
chunkAVXA4F6G_js.ErrorCode.SERVER_ERROR,
|
|
1890
2085
|
`Server error ${response.status} after ${retryCount} retries`,
|
|
1891
2086
|
false
|
|
1892
2087
|
),
|
|
@@ -1898,9 +2093,12 @@ var CimplifyClient = class {
|
|
|
1898
2093
|
return response;
|
|
1899
2094
|
} catch (error) {
|
|
1900
2095
|
lastError = error;
|
|
2096
|
+
if (signal?.aborted) {
|
|
2097
|
+
throw new chunkAVXA4F6G_js.CimplifyError(chunkAVXA4F6G_js.ErrorCode.CANCELLED, "Request was cancelled.", true);
|
|
2098
|
+
}
|
|
1901
2099
|
const networkError = toNetworkError(error, this.isTestMode());
|
|
1902
2100
|
const errorRetryable = isRetryable(error);
|
|
1903
|
-
if (!errorRetryable || attempt >=
|
|
2101
|
+
if (!errorRetryable || attempt >= maxRetries) {
|
|
1904
2102
|
this.hooks.onRequestError?.({
|
|
1905
2103
|
...context,
|
|
1906
2104
|
error: networkError,
|
|
@@ -1911,14 +2109,14 @@ var CimplifyClient = class {
|
|
|
1911
2109
|
throw networkError;
|
|
1912
2110
|
}
|
|
1913
2111
|
retryCount++;
|
|
1914
|
-
const delay = this.retryDelay * Math.pow(2, attempt);
|
|
2112
|
+
const delay = withPositiveJitter(this.retryDelay * Math.pow(2, attempt), jitterRatio);
|
|
1915
2113
|
this.hooks.onRetry?.({
|
|
1916
2114
|
...context,
|
|
1917
2115
|
attempt: retryCount,
|
|
1918
2116
|
delayMs: delay,
|
|
1919
2117
|
error: networkError
|
|
1920
2118
|
});
|
|
1921
|
-
await sleep(delay);
|
|
2119
|
+
await sleep(delay, signal);
|
|
1922
2120
|
}
|
|
1923
2121
|
}
|
|
1924
2122
|
const finalError = toNetworkError(lastError, this.isTestMode());
|
|
@@ -1955,16 +2153,24 @@ var CimplifyClient = class {
|
|
|
1955
2153
|
return request;
|
|
1956
2154
|
}
|
|
1957
2155
|
async get(path, opts) {
|
|
1958
|
-
const
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
2156
|
+
const request = async () => {
|
|
2157
|
+
const response = await this.authedFetch(
|
|
2158
|
+
this.buildUrl(this.baseUrl, path),
|
|
2159
|
+
{
|
|
2160
|
+
method: "GET",
|
|
2161
|
+
credentials: this.credentials,
|
|
2162
|
+
headers: this.getHeaders(),
|
|
2163
|
+
...nextInit(opts?.cacheOptions)
|
|
2164
|
+
},
|
|
2165
|
+
opts?.timeoutMs,
|
|
2166
|
+
opts?.retryPolicy,
|
|
2167
|
+
opts?.signal
|
|
2168
|
+
);
|
|
1966
2169
|
return this.handleRestResponse(response);
|
|
1967
|
-
}
|
|
2170
|
+
};
|
|
2171
|
+
if (opts?.signal) return request();
|
|
2172
|
+
const key = this.getDedupeKey("get", path, opts?.cacheOptions);
|
|
2173
|
+
return this.deduplicatedRequest(key, request);
|
|
1968
2174
|
}
|
|
1969
2175
|
async post(path, body, opts) {
|
|
1970
2176
|
const response = await this.authedFetch(
|
|
@@ -1975,7 +2181,9 @@ var CimplifyClient = class {
|
|
|
1975
2181
|
headers: mergeOptionHeaders(this.getHeaders(), opts),
|
|
1976
2182
|
body: body ? JSON.stringify(body) : void 0
|
|
1977
2183
|
},
|
|
1978
|
-
opts?.timeoutMs
|
|
2184
|
+
opts?.timeoutMs,
|
|
2185
|
+
opts?.retryPolicy,
|
|
2186
|
+
opts?.signal
|
|
1979
2187
|
);
|
|
1980
2188
|
return this.handleRestResponse(response);
|
|
1981
2189
|
}
|
|
@@ -1988,7 +2196,9 @@ var CimplifyClient = class {
|
|
|
1988
2196
|
headers: mergeOptionHeaders(this.getHeaders(), opts),
|
|
1989
2197
|
body: body ? JSON.stringify(body) : void 0
|
|
1990
2198
|
},
|
|
1991
|
-
opts?.timeoutMs
|
|
2199
|
+
opts?.timeoutMs,
|
|
2200
|
+
opts?.retryPolicy,
|
|
2201
|
+
opts?.signal
|
|
1992
2202
|
);
|
|
1993
2203
|
return this.handleRestResponse(response);
|
|
1994
2204
|
}
|
|
@@ -2000,21 +2210,31 @@ var CimplifyClient = class {
|
|
|
2000
2210
|
credentials: this.credentials,
|
|
2001
2211
|
headers: mergeOptionHeaders(this.getHeaders(), opts)
|
|
2002
2212
|
},
|
|
2003
|
-
opts?.timeoutMs
|
|
2213
|
+
opts?.timeoutMs,
|
|
2214
|
+
opts?.retryPolicy,
|
|
2215
|
+
opts?.signal
|
|
2004
2216
|
);
|
|
2005
2217
|
return this.handleRestResponse(response);
|
|
2006
2218
|
}
|
|
2007
2219
|
async linkGet(path, opts) {
|
|
2008
|
-
const
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2220
|
+
const request = async () => {
|
|
2221
|
+
const response = await this.authedFetch(
|
|
2222
|
+
`${this.linkApiUrl}${path}`,
|
|
2223
|
+
{
|
|
2224
|
+
method: "GET",
|
|
2225
|
+
credentials: this.credentials,
|
|
2226
|
+
headers: this.getHeaders(),
|
|
2227
|
+
...nextInit(opts?.cacheOptions)
|
|
2228
|
+
},
|
|
2229
|
+
opts?.timeoutMs,
|
|
2230
|
+
opts?.retryPolicy,
|
|
2231
|
+
opts?.signal
|
|
2232
|
+
);
|
|
2016
2233
|
return this.handleRestResponse(response);
|
|
2017
|
-
}
|
|
2234
|
+
};
|
|
2235
|
+
if (opts?.signal) return request();
|
|
2236
|
+
const key = this.getDedupeKey("linkGet", path, opts?.cacheOptions);
|
|
2237
|
+
return this.deduplicatedRequest(key, request);
|
|
2018
2238
|
}
|
|
2019
2239
|
async linkPost(path, body, opts) {
|
|
2020
2240
|
const response = await this.authedFetch(
|
|
@@ -2025,32 +2245,40 @@ var CimplifyClient = class {
|
|
|
2025
2245
|
headers: mergeOptionHeaders(this.getHeaders(), opts),
|
|
2026
2246
|
body: body ? JSON.stringify(body) : void 0
|
|
2027
2247
|
},
|
|
2028
|
-
opts?.timeoutMs
|
|
2248
|
+
opts?.timeoutMs,
|
|
2249
|
+
opts?.retryPolicy,
|
|
2250
|
+
opts?.signal
|
|
2029
2251
|
);
|
|
2030
2252
|
return this.handleRestResponse(response);
|
|
2031
2253
|
}
|
|
2032
2254
|
async linkDelete(path, opts) {
|
|
2033
|
-
const response = await this.authedFetch(
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2255
|
+
const response = await this.authedFetch(
|
|
2256
|
+
`${this.linkApiUrl}${path}`,
|
|
2257
|
+
{
|
|
2258
|
+
method: "DELETE",
|
|
2259
|
+
credentials: this.credentials,
|
|
2260
|
+
headers: mergeOptionHeaders(this.getHeaders(), opts)
|
|
2261
|
+
},
|
|
2262
|
+
opts?.timeoutMs,
|
|
2263
|
+
opts?.retryPolicy,
|
|
2264
|
+
opts?.signal
|
|
2265
|
+
);
|
|
2038
2266
|
return this.handleRestResponse(response);
|
|
2039
2267
|
}
|
|
2040
2268
|
async handleRestResponse(response) {
|
|
2041
2269
|
const json = await response.json();
|
|
2042
2270
|
if (!response.ok) {
|
|
2043
|
-
const errorCode = typeof json.error === "object" && json.error?.error_code || typeof json.error === "object" && json.error?.code ||
|
|
2271
|
+
const errorCode = typeof json.error === "object" && json.error?.error_code || typeof json.error === "object" && json.error?.code || chunkAVXA4F6G_js.ErrorCode.API_ERROR;
|
|
2044
2272
|
const errorMessage = typeof json.error === "object" && json.error?.error_message || typeof json.error === "object" && json.error?.message || typeof json.error === "string" && json.error || typeof json.message === "string" && json.message || "An error occurred";
|
|
2045
2273
|
const retryable = typeof json.error === "object" && typeof json.error?.retryable === "boolean" ? json.error.retryable : false;
|
|
2046
|
-
if (errorCode ===
|
|
2274
|
+
if (errorCode === chunkAVXA4F6G_js.ErrorCode.IDEMPOTENCY_MISMATCH) {
|
|
2047
2275
|
const originalCreatedAt = typeof json.error === "object" && json.error?.original_created_at || "";
|
|
2048
|
-
throw new
|
|
2276
|
+
throw new chunkAVXA4F6G_js.IdempotencyMismatchError(errorMessage, originalCreatedAt);
|
|
2049
2277
|
}
|
|
2050
|
-
const error =
|
|
2278
|
+
const error = chunkAVXA4F6G_js.enrichError(new chunkAVXA4F6G_js.CimplifyError(errorCode, errorMessage, retryable), {
|
|
2051
2279
|
isTestMode: this.isTestMode()
|
|
2052
2280
|
});
|
|
2053
|
-
if ((response.status === 401 || error.code ===
|
|
2281
|
+
if ((response.status === 401 || error.code === chunkAVXA4F6G_js.ErrorCode.UNAUTHORIZED) && this.accessToken) {
|
|
2054
2282
|
console.warn(
|
|
2055
2283
|
"[Cimplify] Received 401 Unauthorized. Access token may be missing/expired. Refresh authentication and retry the request."
|
|
2056
2284
|
);
|
|
@@ -2058,9 +2286,9 @@ var CimplifyClient = class {
|
|
|
2058
2286
|
throw error;
|
|
2059
2287
|
}
|
|
2060
2288
|
if (json?.success === false || json?.error?.code || json?.error?.message) {
|
|
2061
|
-
const error =
|
|
2062
|
-
new
|
|
2063
|
-
json.error?.code ||
|
|
2289
|
+
const error = chunkAVXA4F6G_js.enrichError(
|
|
2290
|
+
new chunkAVXA4F6G_js.CimplifyError(
|
|
2291
|
+
json.error?.code || chunkAVXA4F6G_js.ErrorCode.API_ERROR,
|
|
2064
2292
|
json.error?.message || "An error occurred",
|
|
2065
2293
|
json.error?.retryable || false
|
|
2066
2294
|
),
|
|
@@ -2075,25 +2303,31 @@ var CimplifyClient = class {
|
|
|
2075
2303
|
}
|
|
2076
2304
|
get catalogue() {
|
|
2077
2305
|
if (!this._catalogue) {
|
|
2078
|
-
this._catalogue = new
|
|
2306
|
+
this._catalogue = new chunkXHVQDEVO_js.CatalogueQueries(this);
|
|
2079
2307
|
}
|
|
2080
2308
|
return this._catalogue;
|
|
2081
2309
|
}
|
|
2082
2310
|
get cart() {
|
|
2083
2311
|
if (!this._cart) {
|
|
2084
|
-
this._cart = new
|
|
2312
|
+
this._cart = new chunkXHVQDEVO_js.CartOperations(this);
|
|
2085
2313
|
}
|
|
2086
2314
|
return this._cart;
|
|
2087
2315
|
}
|
|
2088
2316
|
get checkout() {
|
|
2089
2317
|
if (!this._checkout) {
|
|
2090
|
-
this._checkout = new
|
|
2318
|
+
this._checkout = new chunkXHVQDEVO_js.CheckoutService(this);
|
|
2091
2319
|
}
|
|
2092
2320
|
return this._checkout;
|
|
2093
2321
|
}
|
|
2322
|
+
get purchaseIntents() {
|
|
2323
|
+
if (!this._purchaseIntents) {
|
|
2324
|
+
this._purchaseIntents = new PurchaseIntentService(this);
|
|
2325
|
+
}
|
|
2326
|
+
return this._purchaseIntents;
|
|
2327
|
+
}
|
|
2094
2328
|
get orders() {
|
|
2095
2329
|
if (!this._orders) {
|
|
2096
|
-
this._orders = new
|
|
2330
|
+
this._orders = new chunkXHVQDEVO_js.OrderQueries(this);
|
|
2097
2331
|
}
|
|
2098
2332
|
return this._orders;
|
|
2099
2333
|
}
|
|
@@ -2123,43 +2357,43 @@ var CimplifyClient = class {
|
|
|
2123
2357
|
}
|
|
2124
2358
|
get link() {
|
|
2125
2359
|
if (!this._link) {
|
|
2126
|
-
this._link = new
|
|
2360
|
+
this._link = new chunkXHVQDEVO_js.LinkService(this);
|
|
2127
2361
|
}
|
|
2128
2362
|
return this._link;
|
|
2129
2363
|
}
|
|
2130
2364
|
get auth() {
|
|
2131
2365
|
if (!this._auth) {
|
|
2132
|
-
this._auth = new
|
|
2366
|
+
this._auth = new chunkXHVQDEVO_js.AuthService(this);
|
|
2133
2367
|
}
|
|
2134
2368
|
return this._auth;
|
|
2135
2369
|
}
|
|
2136
2370
|
get business() {
|
|
2137
2371
|
if (!this._business) {
|
|
2138
|
-
this._business = new
|
|
2372
|
+
this._business = new chunkXHVQDEVO_js.BusinessService(this);
|
|
2139
2373
|
}
|
|
2140
2374
|
return this._business;
|
|
2141
2375
|
}
|
|
2142
2376
|
get inventory() {
|
|
2143
2377
|
if (!this._inventory) {
|
|
2144
|
-
this._inventory = new
|
|
2378
|
+
this._inventory = new chunkXHVQDEVO_js.InventoryService(this);
|
|
2145
2379
|
}
|
|
2146
2380
|
return this._inventory;
|
|
2147
2381
|
}
|
|
2148
2382
|
get scheduling() {
|
|
2149
2383
|
if (!this._scheduling) {
|
|
2150
|
-
this._scheduling = new
|
|
2384
|
+
this._scheduling = new chunkXHVQDEVO_js.SchedulingService(this);
|
|
2151
2385
|
}
|
|
2152
2386
|
return this._scheduling;
|
|
2153
2387
|
}
|
|
2154
2388
|
get lite() {
|
|
2155
2389
|
if (!this._lite) {
|
|
2156
|
-
this._lite = new
|
|
2390
|
+
this._lite = new chunkXHVQDEVO_js.LiteService(this);
|
|
2157
2391
|
}
|
|
2158
2392
|
return this._lite;
|
|
2159
2393
|
}
|
|
2160
2394
|
get fx() {
|
|
2161
2395
|
if (!this._fx) {
|
|
2162
|
-
this._fx = new
|
|
2396
|
+
this._fx = new chunkXHVQDEVO_js.FxService(this);
|
|
2163
2397
|
}
|
|
2164
2398
|
return this._fx;
|
|
2165
2399
|
}
|
|
@@ -2194,7 +2428,7 @@ var CimplifyClient = class {
|
|
|
2194
2428
|
if (businessId) {
|
|
2195
2429
|
this.setBusinessId(businessId);
|
|
2196
2430
|
}
|
|
2197
|
-
return
|
|
2431
|
+
return chunkXHVQDEVO_js.createElements(this, businessId ?? this.businessId ?? void 0, options);
|
|
2198
2432
|
}
|
|
2199
2433
|
};
|
|
2200
2434
|
function createCimplifyClient(config = {}) {
|
|
@@ -2205,17 +2439,18 @@ exports.AUTH_TOKEN_CHANGED = AUTH_TOKEN_CHANGED;
|
|
|
2205
2439
|
exports.ActivityService = ActivityService;
|
|
2206
2440
|
exports.CimplifyClient = CimplifyClient;
|
|
2207
2441
|
exports.DeliveryService = DeliveryService;
|
|
2442
|
+
exports.HostedPurchaseIntentService = HostedPurchaseIntentService;
|
|
2208
2443
|
exports.MUTATION_ERROR = MUTATION_ERROR;
|
|
2209
|
-
exports.
|
|
2210
|
-
exports.PaystackAuthorizationAdapter = PaystackAuthorizationAdapter;
|
|
2444
|
+
exports.PURCHASE_INTENT_ROUTE = PURCHASE_INTENT_ROUTE;
|
|
2211
2445
|
exports.PlacesService = PlacesService;
|
|
2446
|
+
exports.PurchaseIntentResolver = PurchaseIntentResolver;
|
|
2447
|
+
exports.PurchaseIntentService = PurchaseIntentService;
|
|
2448
|
+
exports.SESSION_CHANGE_SOURCE = SESSION_CHANGE_SOURCE;
|
|
2212
2449
|
exports.SESSION_CLAIMED = SESSION_CLAIMED;
|
|
2213
2450
|
exports.SESSION_CLEARED = SESSION_CLEARED;
|
|
2214
2451
|
exports.StoreCreditQueries = StoreCreditQueries;
|
|
2215
|
-
exports.StripeAuthorizationAdapter = StripeAuthorizationAdapter;
|
|
2216
2452
|
exports.SubscriptionService = SubscriptionService;
|
|
2217
2453
|
exports.SupportService = SupportService;
|
|
2218
2454
|
exports.UploadService = UploadService;
|
|
2219
2455
|
exports.chatRealtimeUpdateFromWire = chatRealtimeUpdateFromWire;
|
|
2220
2456
|
exports.createCimplifyClient = createCimplifyClient;
|
|
2221
|
-
exports.createDefaultPaymentAuthorizationAdapterRegistry = createDefaultPaymentAuthorizationAdapterRegistry;
|