arky-sdk 0.9.0 → 0.9.11
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/README.md +113 -194
- package/dist/admin-BKXmDIVk.d.ts +1396 -0
- package/dist/admin-CAwQrMOX.d.cts +1396 -0
- package/dist/admin.cjs +1239 -455
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.d.cts +3 -3
- package/dist/admin.d.ts +3 -3
- package/dist/admin.js +1239 -455
- package/dist/admin.js.map +1 -1
- package/dist/api-DJI3S6XA.d.cts +4204 -0
- package/dist/api-DJI3S6XA.d.ts +4204 -0
- package/dist/{index-C5gikdBg.d.cts → index-BaSBPLdF.d.ts} +1 -1
- package/dist/{index-MFMjlIfS.d.ts → index-u-gjHnKs.d.cts} +1 -1
- package/dist/index.cjs +1360 -610
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1360 -610
- package/dist/index.js.map +1 -1
- package/dist/storefront.cjs +590 -382
- package/dist/storefront.cjs.map +1 -1
- package/dist/storefront.d.cts +182 -156
- package/dist/storefront.d.ts +182 -156
- package/dist/storefront.js +588 -381
- package/dist/storefront.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +1 -2666
- package/dist/types.d.ts +1 -2666
- package/dist/types.js.map +1 -1
- package/dist/utils.d.cts +2 -2
- package/dist/utils.d.ts +2 -2
- package/package.json +9 -11
- package/scripts/contract-admin.mjs +137 -0
- package/scripts/contract-storefront.mjs +296 -0
- package/dist/admin-CfHen7c5.d.cts +0 -1036
- package/dist/admin-ru7pX5bd.d.ts +0 -1036
- package/dist/storefront-store.cjs +0 -2794
- package/dist/storefront-store.cjs.map +0 -1
- package/dist/storefront-store.d.cts +0 -5
- package/dist/storefront-store.d.ts +0 -5
- package/dist/storefront-store.js +0 -2792
- package/dist/storefront-store.js.map +0 -1
- package/scripts/smoke-store.mjs +0 -41
package/dist/storefront.cjs
CHANGED
|
@@ -2,132 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var nanostores = require('nanostores');
|
|
4
4
|
|
|
5
|
-
// src/utils/blocks.ts
|
|
6
|
-
function getBlockLabel(block) {
|
|
7
|
-
if (!block) return "";
|
|
8
|
-
return block.key?.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()) ?? "";
|
|
9
|
-
}
|
|
10
|
-
function formatBlockValue(block) {
|
|
11
|
-
if (!block || block.value === null || block.value === void 0) return "";
|
|
12
|
-
const value = block.value;
|
|
13
|
-
switch (block.type) {
|
|
14
|
-
case "boolean":
|
|
15
|
-
return value ? "Yes" : "No";
|
|
16
|
-
case "number":
|
|
17
|
-
if (block.properties?.variant === "DATE" || block.properties?.variant === "DATE_TIME") {
|
|
18
|
-
return new Date(value).toLocaleDateString();
|
|
19
|
-
}
|
|
20
|
-
return String(value);
|
|
21
|
-
case "relationship_entry":
|
|
22
|
-
case "relationship_media":
|
|
23
|
-
if (value && typeof value === "object") {
|
|
24
|
-
return value.mime_type ? value.name || value.id : value.title || value.name || value.id;
|
|
25
|
-
}
|
|
26
|
-
return String(value);
|
|
27
|
-
default:
|
|
28
|
-
return String(value);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function prepareBlocksForSubmission(formData, blockTypes) {
|
|
32
|
-
return Object.keys(formData).filter((key) => formData[key] !== null && formData[key] !== void 0).map((key) => ({
|
|
33
|
-
key,
|
|
34
|
-
value: blockTypes?.[key] === "list" && !Array.isArray(formData[key]) ? [formData[key]] : formData[key]
|
|
35
|
-
}));
|
|
36
|
-
}
|
|
37
|
-
function extractBlockValues(blocks) {
|
|
38
|
-
const values = {};
|
|
39
|
-
blocks.forEach((block) => {
|
|
40
|
-
values[block.key] = block.value ?? null;
|
|
41
|
-
});
|
|
42
|
-
return values;
|
|
43
|
-
}
|
|
44
|
-
var getBlockValue = (entry, blockKey) => {
|
|
45
|
-
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
46
|
-
return block?.value ?? null;
|
|
47
|
-
};
|
|
48
|
-
var getBlockTextValue = (block, locale = "en") => {
|
|
49
|
-
if (!block || block.value === null || block.value === void 0) return "";
|
|
50
|
-
if (block.type === "localized_text" || block.type === "markdown") {
|
|
51
|
-
if (typeof block.value === "object" && block.value !== null) {
|
|
52
|
-
return block.value[locale] ?? block.value["en"] ?? "";
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (typeof block.value === "string") return block.value;
|
|
56
|
-
return String(block.value ?? "");
|
|
57
|
-
};
|
|
58
|
-
var getBlockValues = (entry, blockKey) => {
|
|
59
|
-
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
60
|
-
if (!block) return [];
|
|
61
|
-
if (block.type === "list" && Array.isArray(block.value)) {
|
|
62
|
-
return block.value;
|
|
63
|
-
}
|
|
64
|
-
return [];
|
|
65
|
-
};
|
|
66
|
-
function unwrapBlock(block, locale) {
|
|
67
|
-
if (!block?.type || block.value === void 0) return block;
|
|
68
|
-
if (block.type === "list") {
|
|
69
|
-
return block.value.map((obj) => {
|
|
70
|
-
const parsed = {};
|
|
71
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
72
|
-
parsed[k] = unwrapBlock(v, locale);
|
|
73
|
-
}
|
|
74
|
-
return parsed;
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
if (block.type === "map") {
|
|
78
|
-
const parsed = {};
|
|
79
|
-
for (const [k, v] of Object.entries(block.value || {})) {
|
|
80
|
-
parsed[k] = unwrapBlock(v, locale);
|
|
81
|
-
}
|
|
82
|
-
return parsed;
|
|
83
|
-
}
|
|
84
|
-
if (block.type === "localized_text" || block.type === "markdown") {
|
|
85
|
-
return block.value?.[locale];
|
|
86
|
-
}
|
|
87
|
-
return block.value;
|
|
88
|
-
}
|
|
89
|
-
var getBlockObjectValues = (entry, blockKey, locale = "en") => {
|
|
90
|
-
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
91
|
-
if (!block || block.type !== "list" || !Array.isArray(block.value)) return [];
|
|
92
|
-
return block.value.map((obj) => {
|
|
93
|
-
if (!obj?.value || !Array.isArray(obj.value)) return {};
|
|
94
|
-
return obj.value.reduce((acc, current) => {
|
|
95
|
-
acc[current.key] = unwrapBlock(current, locale);
|
|
96
|
-
return acc;
|
|
97
|
-
}, {});
|
|
98
|
-
});
|
|
99
|
-
};
|
|
100
|
-
var getBlockFromArray = (entry, blockKey, locale = "en") => {
|
|
101
|
-
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
102
|
-
if (!block) return {};
|
|
103
|
-
if (block.type === "list" && Array.isArray(block.value)) {
|
|
104
|
-
return block.value.reduce((acc, current) => {
|
|
105
|
-
acc[current.key] = unwrapBlock(current, locale);
|
|
106
|
-
return acc;
|
|
107
|
-
}, {});
|
|
108
|
-
}
|
|
109
|
-
if (block.type === "map" && block.value && typeof block.value === "object") {
|
|
110
|
-
const result = {};
|
|
111
|
-
for (const [k, v] of Object.entries(block.value)) {
|
|
112
|
-
result[k] = unwrapBlock(v, locale);
|
|
113
|
-
}
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
116
|
-
return { [block.key]: unwrapBlock(block, locale) };
|
|
117
|
-
};
|
|
118
|
-
var getImageUrl = (imageBlock, isBlock = true) => {
|
|
119
|
-
if (!imageBlock) return null;
|
|
120
|
-
if (imageBlock.type === "relationship_media") {
|
|
121
|
-
const mediaValue = imageBlock.value;
|
|
122
|
-
return mediaValue?.resolutions?.original?.url || mediaValue?.url || null;
|
|
123
|
-
}
|
|
124
|
-
if (isBlock) {
|
|
125
|
-
if (typeof imageBlock === "string") return imageBlock;
|
|
126
|
-
if (imageBlock.url) return imageBlock.url;
|
|
127
|
-
}
|
|
128
|
-
return imageBlock.resolutions?.original?.url || null;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
5
|
// src/utils/orderItems.ts
|
|
132
6
|
function normalizeOrderCheckoutItems(items) {
|
|
133
7
|
return items.map((item) => {
|
|
@@ -148,36 +22,36 @@ function normalizePublicCheckoutItems(items) {
|
|
|
148
22
|
}
|
|
149
23
|
|
|
150
24
|
// src/api/storefront.ts
|
|
151
|
-
var
|
|
152
|
-
"
|
|
153
|
-
"
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
"order_created",
|
|
25
|
+
var COMMON_ACTION_KEYS = [
|
|
26
|
+
"page.view",
|
|
27
|
+
"product.view",
|
|
28
|
+
"service.view",
|
|
29
|
+
"provider.view",
|
|
30
|
+
"cart.added",
|
|
31
|
+
"cart.removed",
|
|
32
|
+
"checkout.started",
|
|
33
|
+
"order.created",
|
|
161
34
|
"signin",
|
|
162
35
|
"signup",
|
|
163
|
-
"
|
|
36
|
+
"verified.email",
|
|
164
37
|
"search",
|
|
165
38
|
"share",
|
|
166
|
-
"
|
|
39
|
+
"wishlist.added"
|
|
167
40
|
];
|
|
168
|
-
var
|
|
169
|
-
|
|
41
|
+
var createActionApi = (apiConfig) => ({
|
|
42
|
+
COMMON_ACTION_KEYS,
|
|
170
43
|
async track(params) {
|
|
171
44
|
try {
|
|
45
|
+
const key = "key" in params && params.key ? params.key : params.type;
|
|
172
46
|
await apiConfig.httpClient.post(
|
|
173
|
-
`/v1/storefront/${apiConfig.storeId}/
|
|
174
|
-
{
|
|
47
|
+
`/v1/storefront/${apiConfig.storeId}/actions/track`,
|
|
48
|
+
{ key, payload: params.payload }
|
|
175
49
|
);
|
|
176
50
|
} catch {
|
|
177
51
|
}
|
|
178
52
|
}
|
|
179
53
|
});
|
|
180
|
-
var createStorefrontApi = (apiConfig,
|
|
54
|
+
var createStorefrontApi = (apiConfig, updateContactSession) => {
|
|
181
55
|
const base = (storeId = apiConfig.storeId) => `/v1/storefront/${storeId}`;
|
|
182
56
|
return {
|
|
183
57
|
store: {
|
|
@@ -211,47 +85,32 @@ var createStorefrontApi = (apiConfig, updateCustomerSession) => {
|
|
|
211
85
|
}
|
|
212
86
|
},
|
|
213
87
|
cms: {
|
|
214
|
-
|
|
215
|
-
|
|
88
|
+
collection: {
|
|
89
|
+
get(params, options) {
|
|
216
90
|
const store_id = params.store_id || apiConfig.storeId;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
identifier = params.id;
|
|
220
|
-
} else if (params.slug) {
|
|
221
|
-
identifier = `${store_id}:${apiConfig.locale}:${params.slug}`;
|
|
222
|
-
} else if (params.key) {
|
|
223
|
-
identifier = `${store_id}:${params.key}`;
|
|
224
|
-
} else {
|
|
225
|
-
throw new Error("GetNodeParams requires id, slug, or key");
|
|
91
|
+
if (!params.id) {
|
|
92
|
+
throw new Error("GetCollectionParams requires id");
|
|
226
93
|
}
|
|
227
|
-
|
|
228
|
-
`${base(store_id)}/
|
|
94
|
+
return apiConfig.httpClient.get(
|
|
95
|
+
`${base(store_id)}/collections/${params.id}`,
|
|
96
|
+
options
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
entry: {
|
|
101
|
+
get(params, options) {
|
|
102
|
+
const store_id = params.store_id || apiConfig.storeId;
|
|
103
|
+
if (!params.id) {
|
|
104
|
+
throw new Error("GetEntryParams requires id");
|
|
105
|
+
}
|
|
106
|
+
return apiConfig.httpClient.get(
|
|
107
|
+
`${base(store_id)}/entries/${params.id}`,
|
|
229
108
|
options
|
|
230
109
|
);
|
|
231
|
-
return {
|
|
232
|
-
...response,
|
|
233
|
-
getBlock(key) {
|
|
234
|
-
return getBlockFromArray(response, key, apiConfig.locale);
|
|
235
|
-
},
|
|
236
|
-
getBlockValues(key) {
|
|
237
|
-
return getBlockObjectValues(response, key, apiConfig.locale);
|
|
238
|
-
},
|
|
239
|
-
getImage(key) {
|
|
240
|
-
const block = getBlockFromArray(response, key, apiConfig.locale);
|
|
241
|
-
return getImageUrl(block, true);
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
110
|
},
|
|
245
111
|
find(params, options) {
|
|
246
112
|
const { store_id, ...queryParams } = params;
|
|
247
|
-
return apiConfig.httpClient.get(`${base(store_id)}/
|
|
248
|
-
...options,
|
|
249
|
-
params: queryParams
|
|
250
|
-
});
|
|
251
|
-
},
|
|
252
|
-
getChildren(params, options) {
|
|
253
|
-
const { id, store_id, ...queryParams } = params;
|
|
254
|
-
return apiConfig.httpClient.get(`${base(store_id)}/nodes/${id}/children`, {
|
|
113
|
+
return apiConfig.httpClient.get(`${base(store_id)}/entries`, {
|
|
255
114
|
...options,
|
|
256
115
|
params: queryParams
|
|
257
116
|
});
|
|
@@ -411,7 +270,9 @@ var createStorefrontApi = (apiConfig, updateCustomerSession) => {
|
|
|
411
270
|
{
|
|
412
271
|
id: params.id,
|
|
413
272
|
store_id,
|
|
414
|
-
|
|
273
|
+
payment_method_key: params.payment_method_key,
|
|
274
|
+
confirmation_token_id: params.confirmation_token_id,
|
|
275
|
+
return_url: params.return_url
|
|
415
276
|
},
|
|
416
277
|
options
|
|
417
278
|
);
|
|
@@ -431,6 +292,14 @@ var createStorefrontApi = (apiConfig, updateCustomerSession) => {
|
|
|
431
292
|
...options,
|
|
432
293
|
params: queryParams
|
|
433
294
|
});
|
|
295
|
+
},
|
|
296
|
+
downloadDigitalAccess(params, options) {
|
|
297
|
+
const store_id = params.store_id || apiConfig.storeId;
|
|
298
|
+
return apiConfig.httpClient.post(
|
|
299
|
+
`${base(store_id)}/orders/${params.id}/digital-access/${params.grant_id}/download`,
|
|
300
|
+
{},
|
|
301
|
+
options
|
|
302
|
+
);
|
|
434
303
|
}
|
|
435
304
|
},
|
|
436
305
|
service: {
|
|
@@ -498,11 +367,11 @@ var createStorefrontApi = (apiConfig, updateCustomerSession) => {
|
|
|
498
367
|
}
|
|
499
368
|
},
|
|
500
369
|
crm: {
|
|
501
|
-
|
|
370
|
+
contact: {
|
|
502
371
|
async identify(params, options) {
|
|
503
372
|
const store_id = apiConfig.storeId;
|
|
504
373
|
const result = await apiConfig.httpClient.post(
|
|
505
|
-
`${base(store_id)}/
|
|
374
|
+
`${base(store_id)}/account/identify`,
|
|
506
375
|
{
|
|
507
376
|
store_id,
|
|
508
377
|
market: params?.market || apiConfig.market || null,
|
|
@@ -512,9 +381,9 @@ var createStorefrontApi = (apiConfig, updateCustomerSession) => {
|
|
|
512
381
|
options
|
|
513
382
|
);
|
|
514
383
|
if (result?.token?.token) {
|
|
515
|
-
|
|
384
|
+
updateContactSession(() => ({
|
|
516
385
|
access_token: result.token.token,
|
|
517
|
-
|
|
386
|
+
contact: result.contact,
|
|
518
387
|
store: result.store,
|
|
519
388
|
market: result.market
|
|
520
389
|
}));
|
|
@@ -524,12 +393,12 @@ var createStorefrontApi = (apiConfig, updateCustomerSession) => {
|
|
|
524
393
|
async verify(params, options) {
|
|
525
394
|
const store_id = apiConfig.storeId;
|
|
526
395
|
const result = await apiConfig.httpClient.post(
|
|
527
|
-
`${base(store_id)}/
|
|
396
|
+
`${base(store_id)}/account/verify`,
|
|
528
397
|
{ store_id, code: params.code },
|
|
529
398
|
options
|
|
530
399
|
);
|
|
531
400
|
if (result?.token) {
|
|
532
|
-
|
|
401
|
+
updateContactSession(
|
|
533
402
|
(prev) => prev ? { ...prev, access_token: result.token } : null
|
|
534
403
|
);
|
|
535
404
|
}
|
|
@@ -539,131 +408,74 @@ var createStorefrontApi = (apiConfig, updateCustomerSession) => {
|
|
|
539
408
|
const store_id = apiConfig.storeId;
|
|
540
409
|
try {
|
|
541
410
|
await apiConfig.httpClient.post(
|
|
542
|
-
`${base(store_id)}/
|
|
411
|
+
`${base(store_id)}/account/logout`,
|
|
543
412
|
{},
|
|
544
413
|
options
|
|
545
414
|
);
|
|
546
415
|
} finally {
|
|
547
|
-
|
|
416
|
+
updateContactSession(() => null);
|
|
548
417
|
}
|
|
549
418
|
},
|
|
550
419
|
getMe(options) {
|
|
551
|
-
return apiConfig.httpClient.get(`${base()}/
|
|
420
|
+
return apiConfig.httpClient.get(`${base()}/account/me`, options);
|
|
552
421
|
}
|
|
553
422
|
},
|
|
554
|
-
|
|
423
|
+
contactList: {
|
|
555
424
|
get(params, options) {
|
|
556
|
-
|
|
557
|
-
if (params.id) {
|
|
558
|
-
identifier = params.id;
|
|
559
|
-
} else if (params.key) {
|
|
560
|
-
identifier = `${apiConfig.storeId}:${params.key}`;
|
|
561
|
-
} else {
|
|
562
|
-
throw new Error("GetAudienceParams requires id or key");
|
|
563
|
-
}
|
|
425
|
+
const store_id = params.store_id || apiConfig.storeId;
|
|
564
426
|
return apiConfig.httpClient.get(
|
|
565
|
-
`${base(
|
|
427
|
+
`${base(store_id)}/contact-lists/${params.id}`,
|
|
566
428
|
options
|
|
567
429
|
);
|
|
568
430
|
},
|
|
569
431
|
find(params, options) {
|
|
570
|
-
|
|
432
|
+
const { store_id, ...queryParams } = params || {};
|
|
433
|
+
return apiConfig.httpClient.get(`${base(store_id)}/contact-lists`, {
|
|
571
434
|
...options,
|
|
572
|
-
params
|
|
435
|
+
params: queryParams
|
|
573
436
|
});
|
|
574
437
|
},
|
|
575
438
|
subscribe(params, options) {
|
|
439
|
+
const { store_id, id, ...payload } = params;
|
|
576
440
|
return apiConfig.httpClient.post(
|
|
577
|
-
`${base()}/
|
|
578
|
-
|
|
579
|
-
customer_id: params.customer_id,
|
|
580
|
-
price_id: params.price_id,
|
|
581
|
-
success_url: params.success_url,
|
|
582
|
-
cancel_url: params.cancel_url,
|
|
583
|
-
confirm_url: params.confirm_url
|
|
584
|
-
},
|
|
441
|
+
`${base(store_id)}/contact-lists/${id}/subscribe`,
|
|
442
|
+
payload,
|
|
585
443
|
options
|
|
586
444
|
);
|
|
587
445
|
},
|
|
588
446
|
checkAccess(params, options) {
|
|
589
|
-
return apiConfig.httpClient.get(
|
|
590
|
-
`${base()}/audiences/${params.id}/access`,
|
|
591
|
-
options
|
|
592
|
-
);
|
|
593
|
-
},
|
|
594
|
-
unsubscribe(token, options) {
|
|
595
|
-
return apiConfig.httpClient.get(`${base()}/audiences/unsubscribe`, {
|
|
596
|
-
...options,
|
|
597
|
-
params: { token }
|
|
598
|
-
});
|
|
599
|
-
},
|
|
600
|
-
confirm(token, options) {
|
|
601
|
-
return apiConfig.httpClient.get(`${base()}/audiences/confirm`, {
|
|
602
|
-
...options,
|
|
603
|
-
params: { token }
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
activity: createActivityApi(apiConfig),
|
|
609
|
-
automation: {
|
|
610
|
-
agent: {
|
|
611
|
-
getAgents(params, options) {
|
|
612
|
-
const store_id = params?.store_id || apiConfig.storeId;
|
|
613
|
-
const queryParams = { ...params || {} };
|
|
614
|
-
delete queryParams.store_id;
|
|
615
|
-
return apiConfig.httpClient.get(`${base(store_id)}/agents`, {
|
|
616
|
-
...options,
|
|
617
|
-
params: Object.keys(queryParams).length > 0 ? queryParams : void 0
|
|
618
|
-
});
|
|
619
|
-
},
|
|
620
|
-
getAgent(params, options) {
|
|
621
447
|
const store_id = params.store_id || apiConfig.storeId;
|
|
622
448
|
return apiConfig.httpClient.get(
|
|
623
|
-
`${base(store_id)}/
|
|
449
|
+
`${base(store_id)}/contact-lists/${params.id}/access`,
|
|
624
450
|
options
|
|
625
451
|
);
|
|
626
452
|
},
|
|
627
|
-
|
|
628
|
-
const store_id = params.store_id || apiConfig.storeId;
|
|
629
|
-
const body = { message: params.message };
|
|
630
|
-
if (params.chat_id) body.chat_id = params.chat_id;
|
|
453
|
+
unsubscribe(token, options) {
|
|
631
454
|
return apiConfig.httpClient.post(
|
|
632
|
-
`${base(
|
|
633
|
-
|
|
634
|
-
options
|
|
635
|
-
);
|
|
636
|
-
},
|
|
637
|
-
getChat(params, options) {
|
|
638
|
-
const store_id = params.store_id || apiConfig.storeId;
|
|
639
|
-
return apiConfig.httpClient.get(
|
|
640
|
-
`${base(store_id)}/agents/${params.id}/chats/${params.chat_id}`,
|
|
455
|
+
`${base()}/contact-lists/unsubscribe`,
|
|
456
|
+
{ token },
|
|
641
457
|
options
|
|
642
458
|
);
|
|
643
459
|
},
|
|
644
|
-
|
|
645
|
-
const store_id = params.store_id || apiConfig.storeId;
|
|
646
|
-
const queryParams = {};
|
|
647
|
-
if (params.limit) queryParams.limit = String(params.limit);
|
|
648
|
-
return apiConfig.httpClient.get(
|
|
649
|
-
`${base(store_id)}/agents/${params.id}/chats/${params.chat_id}/messages`,
|
|
650
|
-
{
|
|
651
|
-
...options,
|
|
652
|
-
params: Object.keys(queryParams).length > 0 ? queryParams : void 0
|
|
653
|
-
}
|
|
654
|
-
);
|
|
655
|
-
},
|
|
656
|
-
rateChat(params, options) {
|
|
657
|
-
const store_id = params.store_id || apiConfig.storeId;
|
|
658
|
-
const body = { rating: params.rating };
|
|
659
|
-
if (params.comment) body.comment = params.comment;
|
|
460
|
+
confirm(token, options) {
|
|
660
461
|
return apiConfig.httpClient.post(
|
|
661
|
-
`${base(
|
|
662
|
-
|
|
462
|
+
`${base()}/contact-lists/confirm`,
|
|
463
|
+
{ token },
|
|
663
464
|
options
|
|
664
465
|
);
|
|
665
466
|
}
|
|
666
467
|
}
|
|
468
|
+
},
|
|
469
|
+
action: createActionApi(apiConfig),
|
|
470
|
+
experiments: {
|
|
471
|
+
use(params, options) {
|
|
472
|
+
const store_id = params.store_id || apiConfig.storeId;
|
|
473
|
+
return apiConfig.httpClient.post(
|
|
474
|
+
`${base(store_id)}/experiments/use`,
|
|
475
|
+
{ key: params.key },
|
|
476
|
+
options
|
|
477
|
+
);
|
|
478
|
+
}
|
|
667
479
|
}
|
|
668
480
|
};
|
|
669
481
|
};
|
|
@@ -889,7 +701,7 @@ function createHttpClient(cfg) {
|
|
|
889
701
|
headers["Authorization"] = `Bearer ${tokens.access_token}`;
|
|
890
702
|
}
|
|
891
703
|
const finalPath = options?.params ? path + buildQueryString(options.params) : path;
|
|
892
|
-
const fetchOpts = { method, headers };
|
|
704
|
+
const fetchOpts = { method, headers, signal: options?.signal };
|
|
893
705
|
if (!["GET", "DELETE"].includes(method) && body !== void 0) {
|
|
894
706
|
fetchOpts.body = JSON.stringify(body);
|
|
895
707
|
}
|
|
@@ -900,13 +712,15 @@ function createHttpClient(cfg) {
|
|
|
900
712
|
try {
|
|
901
713
|
res = await fetch(fullUrl, fetchOpts);
|
|
902
714
|
} catch (error) {
|
|
715
|
+
const aborted = options?.signal?.aborted || error instanceof Error && error.name === "AbortError";
|
|
903
716
|
const err = new Error(error instanceof Error ? error.message : "Network request failed");
|
|
904
|
-
err.name = "NetworkError";
|
|
717
|
+
err.name = aborted ? "AbortError" : "NetworkError";
|
|
905
718
|
err.method = method;
|
|
906
719
|
err.url = fullUrl;
|
|
720
|
+
err.aborted = aborted;
|
|
907
721
|
if (options?.onError && method !== "GET") {
|
|
908
722
|
Promise.resolve(
|
|
909
|
-
options.onError({ error: err, method, url: fullUrl, aborted
|
|
723
|
+
options.onError({ error: err, method, url: fullUrl, aborted })
|
|
910
724
|
).catch(() => {
|
|
911
725
|
});
|
|
912
726
|
}
|
|
@@ -999,6 +813,168 @@ function createHttpClient(cfg) {
|
|
|
999
813
|
};
|
|
1000
814
|
}
|
|
1001
815
|
|
|
816
|
+
// src/api/support.ts
|
|
817
|
+
function supportConversationQuery(params) {
|
|
818
|
+
const qs = new URLSearchParams({ store_id: params.store_id });
|
|
819
|
+
if (params.message_limit) qs.set("message_limit", String(params.message_limit));
|
|
820
|
+
if (typeof params.after_created_at === "number") qs.set("after_created_at", String(params.after_created_at));
|
|
821
|
+
if (params.after_id) qs.set("after_id", params.after_id);
|
|
822
|
+
return qs.toString();
|
|
823
|
+
}
|
|
824
|
+
function createStorefrontSupportApi(config) {
|
|
825
|
+
const { httpClient, storeId } = config;
|
|
826
|
+
return {
|
|
827
|
+
async startConversation(params = {}, opts) {
|
|
828
|
+
return httpClient.post(
|
|
829
|
+
`/v1/storefront/${storeId}/support/conversations`,
|
|
830
|
+
{ store_id: storeId, ...params },
|
|
831
|
+
opts
|
|
832
|
+
);
|
|
833
|
+
},
|
|
834
|
+
async sendMessage(params, opts) {
|
|
835
|
+
return httpClient.post(
|
|
836
|
+
`/v1/storefront/${storeId}/support/conversations/${params.conversation_id}/messages`,
|
|
837
|
+
{ store_id: storeId, ...params },
|
|
838
|
+
opts
|
|
839
|
+
);
|
|
840
|
+
},
|
|
841
|
+
async getConversation(params, opts) {
|
|
842
|
+
const qs = supportConversationQuery({ store_id: storeId, ...params });
|
|
843
|
+
return httpClient.get(
|
|
844
|
+
`/v1/storefront/${storeId}/support/conversations/${params.conversation_id}?${qs}`,
|
|
845
|
+
opts
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// src/utils/blocks.ts
|
|
852
|
+
function getBlockLabel(block) {
|
|
853
|
+
if (!block) return "";
|
|
854
|
+
return block.key?.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()) ?? "";
|
|
855
|
+
}
|
|
856
|
+
function formatBlockValue(block) {
|
|
857
|
+
if (!block || block.value === null || block.value === void 0) return "";
|
|
858
|
+
const value = block.value;
|
|
859
|
+
switch (block.type) {
|
|
860
|
+
case "boolean":
|
|
861
|
+
return value ? "Yes" : "No";
|
|
862
|
+
case "number":
|
|
863
|
+
if (block.properties?.variant === "DATE" || block.properties?.variant === "DATE_TIME") {
|
|
864
|
+
return new Date(value).toLocaleDateString();
|
|
865
|
+
}
|
|
866
|
+
return String(value);
|
|
867
|
+
case "media":
|
|
868
|
+
if (value && typeof value === "object") {
|
|
869
|
+
return value.mime_type ? value.name || value.id : value.title || value.name || value.id;
|
|
870
|
+
}
|
|
871
|
+
return String(value);
|
|
872
|
+
default:
|
|
873
|
+
return String(value);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
function prepareBlocksForSubmission(formData, blockTypes) {
|
|
877
|
+
return Object.keys(formData).filter((key) => formData[key] !== null && formData[key] !== void 0).map((key) => ({
|
|
878
|
+
key,
|
|
879
|
+
value: (blockTypes?.[key] || "text") === "array" && !Array.isArray(formData[key]) ? [formData[key]] : formData[key]
|
|
880
|
+
}));
|
|
881
|
+
}
|
|
882
|
+
function extractBlockValues(blocks) {
|
|
883
|
+
const values = {};
|
|
884
|
+
blocks.forEach((block) => {
|
|
885
|
+
values[block.key] = block.value ?? null;
|
|
886
|
+
});
|
|
887
|
+
return values;
|
|
888
|
+
}
|
|
889
|
+
var getBlockValue = (entry, blockKey) => {
|
|
890
|
+
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
891
|
+
return block?.value ?? null;
|
|
892
|
+
};
|
|
893
|
+
var getBlockTextValue = (block, locale = "en") => {
|
|
894
|
+
if (!block || block.value === null || block.value === void 0) return "";
|
|
895
|
+
const blockType = block.type;
|
|
896
|
+
if (blockType === "localized_text" || blockType === "markdown") {
|
|
897
|
+
if (typeof block.value === "object" && block.value !== null) {
|
|
898
|
+
return block.value[locale] ?? block.value["en"] ?? "";
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
if (typeof block.value === "string") return block.value;
|
|
902
|
+
return String(block.value ?? "");
|
|
903
|
+
};
|
|
904
|
+
var getBlockValues = (entry, blockKey) => {
|
|
905
|
+
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
906
|
+
if (!block) return [];
|
|
907
|
+
if (block.type === "array" && Array.isArray(block.value)) {
|
|
908
|
+
return block.value;
|
|
909
|
+
}
|
|
910
|
+
return [];
|
|
911
|
+
};
|
|
912
|
+
function unwrapBlock(block, locale) {
|
|
913
|
+
if (!block?.type || block.value === void 0) return block;
|
|
914
|
+
const blockType = block.type;
|
|
915
|
+
if (blockType === "array") {
|
|
916
|
+
return block.value.map((obj) => {
|
|
917
|
+
const parsed = {};
|
|
918
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
919
|
+
parsed[k] = unwrapBlock(v, locale);
|
|
920
|
+
}
|
|
921
|
+
return parsed;
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
if (blockType === "object") {
|
|
925
|
+
const parsed = {};
|
|
926
|
+
for (const [k, v] of Object.entries(block.value || {})) {
|
|
927
|
+
parsed[k] = unwrapBlock(v, locale);
|
|
928
|
+
}
|
|
929
|
+
return parsed;
|
|
930
|
+
}
|
|
931
|
+
if (blockType === "localized_text" || blockType === "markdown") {
|
|
932
|
+
return block.value?.[locale];
|
|
933
|
+
}
|
|
934
|
+
return block.value;
|
|
935
|
+
}
|
|
936
|
+
var getBlockObjectValues = (entry, blockKey, locale = "en") => {
|
|
937
|
+
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
938
|
+
if (!block || block.type !== "array" || !Array.isArray(block.value)) return [];
|
|
939
|
+
return block.value.map((obj) => {
|
|
940
|
+
if (!obj?.value || !Array.isArray(obj.value)) return {};
|
|
941
|
+
return obj.value.reduce((acc, current) => {
|
|
942
|
+
acc[current.key] = unwrapBlock(current, locale);
|
|
943
|
+
return acc;
|
|
944
|
+
}, {});
|
|
945
|
+
});
|
|
946
|
+
};
|
|
947
|
+
var getBlockFromArray = (entry, blockKey, locale = "en") => {
|
|
948
|
+
const block = entry?.blocks?.find((f) => f.key === blockKey);
|
|
949
|
+
if (!block) return {};
|
|
950
|
+
if (block.type === "array" && Array.isArray(block.value)) {
|
|
951
|
+
return block.value.reduce((acc, current) => {
|
|
952
|
+
acc[current.key] = unwrapBlock(current, locale);
|
|
953
|
+
return acc;
|
|
954
|
+
}, {});
|
|
955
|
+
}
|
|
956
|
+
if (block.type === "object" && block.value && typeof block.value === "object") {
|
|
957
|
+
const result = {};
|
|
958
|
+
for (const [k, v] of Object.entries(block.value)) {
|
|
959
|
+
result[k] = unwrapBlock(v, locale);
|
|
960
|
+
}
|
|
961
|
+
return result;
|
|
962
|
+
}
|
|
963
|
+
return { [block.key]: unwrapBlock(block, locale) };
|
|
964
|
+
};
|
|
965
|
+
var getImageUrl = (imageBlock, isBlock = true) => {
|
|
966
|
+
if (!imageBlock) return null;
|
|
967
|
+
if (imageBlock.type === "media") {
|
|
968
|
+
const mediaValue = imageBlock.value;
|
|
969
|
+
return mediaValue?.resolutions?.original?.url || mediaValue?.url || null;
|
|
970
|
+
}
|
|
971
|
+
if (isBlock) {
|
|
972
|
+
if (typeof imageBlock === "string") return imageBlock;
|
|
973
|
+
if (imageBlock.url) return imageBlock.url;
|
|
974
|
+
}
|
|
975
|
+
return imageBlock.resolutions?.original?.url || null;
|
|
976
|
+
};
|
|
977
|
+
|
|
1002
978
|
// src/utils/price.ts
|
|
1003
979
|
function formatCurrency(amount, currencyCode, locale = "en") {
|
|
1004
980
|
if (!currencyCode) return "";
|
|
@@ -1288,22 +1264,22 @@ function createUtilitySurface(apiConfig) {
|
|
|
1288
1264
|
getFirstAvailableFCId
|
|
1289
1265
|
};
|
|
1290
1266
|
}
|
|
1291
|
-
var
|
|
1292
|
-
function
|
|
1267
|
+
var CONTACT_STORAGE_KEY = "arky_contact_session";
|
|
1268
|
+
function readContactSession() {
|
|
1293
1269
|
if (typeof window === "undefined") return null;
|
|
1294
1270
|
try {
|
|
1295
|
-
const raw = localStorage.getItem(
|
|
1271
|
+
const raw = localStorage.getItem(CONTACT_STORAGE_KEY);
|
|
1296
1272
|
return raw ? JSON.parse(raw) : null;
|
|
1297
1273
|
} catch {
|
|
1298
1274
|
return null;
|
|
1299
1275
|
}
|
|
1300
1276
|
}
|
|
1301
|
-
function
|
|
1277
|
+
function writeContactSession(s) {
|
|
1302
1278
|
if (typeof window === "undefined") return;
|
|
1303
1279
|
if (s) {
|
|
1304
|
-
localStorage.setItem(
|
|
1280
|
+
localStorage.setItem(CONTACT_STORAGE_KEY, JSON.stringify(s));
|
|
1305
1281
|
} else {
|
|
1306
|
-
localStorage.removeItem(
|
|
1282
|
+
localStorage.removeItem(CONTACT_STORAGE_KEY);
|
|
1307
1283
|
}
|
|
1308
1284
|
}
|
|
1309
1285
|
function createStorefront(config) {
|
|
@@ -1312,10 +1288,10 @@ function createStorefront(config) {
|
|
|
1312
1288
|
const listeners = /* @__PURE__ */ new Set();
|
|
1313
1289
|
let bareIdentifyPromise = null;
|
|
1314
1290
|
function toPublic(s) {
|
|
1315
|
-
return s ? {
|
|
1291
|
+
return s ? { contact: s.contact, store: s.store, market: s.market } : null;
|
|
1316
1292
|
}
|
|
1317
1293
|
function emit() {
|
|
1318
|
-
const pub = toPublic(
|
|
1294
|
+
const pub = toPublic(readContactSession());
|
|
1319
1295
|
for (const l of listeners) {
|
|
1320
1296
|
Promise.resolve().then(() => l(pub)).catch(() => {
|
|
1321
1297
|
});
|
|
@@ -1323,9 +1299,9 @@ function createStorefront(config) {
|
|
|
1323
1299
|
}
|
|
1324
1300
|
const updateSession = (updater) => {
|
|
1325
1301
|
if (config.apiToken) return;
|
|
1326
|
-
const prev =
|
|
1302
|
+
const prev = readContactSession();
|
|
1327
1303
|
const next = updater(prev);
|
|
1328
|
-
|
|
1304
|
+
writeContactSession(next);
|
|
1329
1305
|
emit();
|
|
1330
1306
|
};
|
|
1331
1307
|
const authStorage = config.apiToken ? {
|
|
@@ -1336,7 +1312,7 @@ function createStorefront(config) {
|
|
|
1336
1312
|
}
|
|
1337
1313
|
} : {
|
|
1338
1314
|
getTokens() {
|
|
1339
|
-
const s =
|
|
1315
|
+
const s = readContactSession();
|
|
1340
1316
|
return s ? { access_token: s.access_token } : null;
|
|
1341
1317
|
},
|
|
1342
1318
|
onTokensRefreshed() {
|
|
@@ -1363,20 +1339,20 @@ function createStorefront(config) {
|
|
|
1363
1339
|
authStorage
|
|
1364
1340
|
};
|
|
1365
1341
|
const storefrontApi = createStorefrontApi(apiConfig, updateSession);
|
|
1366
|
-
const
|
|
1342
|
+
const contactApi = storefrontApi.crm.contact;
|
|
1367
1343
|
function identify(params) {
|
|
1368
1344
|
if (params?.market !== void 0) apiConfig.market = params.market;
|
|
1369
1345
|
const isBareCall = !params?.email && !params?.verify;
|
|
1370
1346
|
if (isBareCall && bareIdentifyPromise) return bareIdentifyPromise;
|
|
1371
1347
|
const promise = (async () => {
|
|
1372
1348
|
try {
|
|
1373
|
-
const result = await
|
|
1349
|
+
const result = await contactApi.identify({
|
|
1374
1350
|
market: apiConfig.market,
|
|
1375
1351
|
email: params?.email,
|
|
1376
1352
|
verify: params?.verify
|
|
1377
1353
|
});
|
|
1378
1354
|
return {
|
|
1379
|
-
|
|
1355
|
+
contact: result.contact,
|
|
1380
1356
|
store: result.store,
|
|
1381
1357
|
market: result.market
|
|
1382
1358
|
};
|
|
@@ -1385,9 +1361,11 @@ function createStorefront(config) {
|
|
|
1385
1361
|
const status = e?.statusCode || e?.status || e?.response?.status;
|
|
1386
1362
|
if (isBareCall && status === 401) {
|
|
1387
1363
|
updateSession(() => null);
|
|
1388
|
-
const result = await
|
|
1364
|
+
const result = await contactApi.identify({
|
|
1365
|
+
market: apiConfig.market
|
|
1366
|
+
});
|
|
1389
1367
|
return {
|
|
1390
|
-
|
|
1368
|
+
contact: result.contact,
|
|
1391
1369
|
store: result.store,
|
|
1392
1370
|
market: result.market
|
|
1393
1371
|
};
|
|
@@ -1402,7 +1380,7 @@ function createStorefront(config) {
|
|
|
1402
1380
|
return promise;
|
|
1403
1381
|
}
|
|
1404
1382
|
async function verify(params) {
|
|
1405
|
-
const result = await
|
|
1383
|
+
const result = await contactApi.verify(params);
|
|
1406
1384
|
bareIdentifyPromise = null;
|
|
1407
1385
|
return result;
|
|
1408
1386
|
}
|
|
@@ -1410,7 +1388,7 @@ function createStorefront(config) {
|
|
|
1410
1388
|
if (config.apiToken) return;
|
|
1411
1389
|
bareIdentifyPromise = null;
|
|
1412
1390
|
try {
|
|
1413
|
-
await
|
|
1391
|
+
await contactApi.logout();
|
|
1414
1392
|
} catch {
|
|
1415
1393
|
updateSession(() => null);
|
|
1416
1394
|
}
|
|
@@ -1419,19 +1397,19 @@ function createStorefront(config) {
|
|
|
1419
1397
|
identify,
|
|
1420
1398
|
verify,
|
|
1421
1399
|
logout,
|
|
1422
|
-
me: () =>
|
|
1400
|
+
me: () => contactApi.getMe(),
|
|
1423
1401
|
get session() {
|
|
1424
1402
|
if (config.apiToken) return null;
|
|
1425
|
-
return toPublic(
|
|
1403
|
+
return toPublic(readContactSession());
|
|
1426
1404
|
},
|
|
1427
1405
|
get isAuthenticated() {
|
|
1428
1406
|
if (config.apiToken) return true;
|
|
1429
|
-
const s =
|
|
1407
|
+
const s = readContactSession();
|
|
1430
1408
|
return s !== null && !!s.access_token;
|
|
1431
1409
|
},
|
|
1432
1410
|
onAuthStateChanged(listener) {
|
|
1433
1411
|
listeners.add(listener);
|
|
1434
|
-
const current = toPublic(
|
|
1412
|
+
const current = toPublic(readContactSession());
|
|
1435
1413
|
if (current) {
|
|
1436
1414
|
Promise.resolve().then(() => listener(current)).catch(() => {
|
|
1437
1415
|
});
|
|
@@ -1445,8 +1423,9 @@ function createStorefront(config) {
|
|
|
1445
1423
|
cms: storefrontApi.cms,
|
|
1446
1424
|
eshop: storefrontApi.eshop,
|
|
1447
1425
|
crm: storefrontApi.crm,
|
|
1448
|
-
|
|
1449
|
-
|
|
1426
|
+
action: storefrontApi.action,
|
|
1427
|
+
experiments: storefrontApi.experiments,
|
|
1428
|
+
support: createStorefrontSupportApi(apiConfig),
|
|
1450
1429
|
setStoreId: (storeId) => {
|
|
1451
1430
|
apiConfig.storeId = storeId;
|
|
1452
1431
|
bareIdentifyPromise = null;
|
|
@@ -1461,11 +1440,81 @@ function createStorefront(config) {
|
|
|
1461
1440
|
apiConfig.locale = l;
|
|
1462
1441
|
},
|
|
1463
1442
|
getLocale: () => apiConfig.locale,
|
|
1464
|
-
extractBlockValues,
|
|
1465
1443
|
utils: createUtilitySurface(apiConfig)
|
|
1466
1444
|
};
|
|
1467
1445
|
}
|
|
1468
1446
|
|
|
1447
|
+
// src/payments/stripe.ts
|
|
1448
|
+
function normalizeCurrency(currency) {
|
|
1449
|
+
return currency.trim().toLowerCase();
|
|
1450
|
+
}
|
|
1451
|
+
async function createStripeConfirmationTokenController(config) {
|
|
1452
|
+
const { loadStripe } = await import('@stripe/stripe-js');
|
|
1453
|
+
const stripe = await loadStripe(config.publishableKey);
|
|
1454
|
+
if (!stripe) throw new Error("Stripe failed to initialize");
|
|
1455
|
+
let elements = createElements(stripe, config);
|
|
1456
|
+
let paymentElement = elements.create("payment", {
|
|
1457
|
+
layout: "tabs"
|
|
1458
|
+
});
|
|
1459
|
+
return {
|
|
1460
|
+
mount(target) {
|
|
1461
|
+
if (!paymentElement) {
|
|
1462
|
+
paymentElement = elements.create("payment", { layout: "tabs" });
|
|
1463
|
+
}
|
|
1464
|
+
paymentElement.mount(target);
|
|
1465
|
+
},
|
|
1466
|
+
update(input) {
|
|
1467
|
+
elements.update({
|
|
1468
|
+
...input.amount !== void 0 ? { amount: input.amount } : {},
|
|
1469
|
+
...input.currency ? { currency: normalizeCurrency(input.currency) } : {}
|
|
1470
|
+
});
|
|
1471
|
+
},
|
|
1472
|
+
async createConfirmationToken(options = {}) {
|
|
1473
|
+
const submitResult = await elements.submit();
|
|
1474
|
+
if (submitResult.error) {
|
|
1475
|
+
throw new Error(submitResult.error.message || "Payment details are incomplete");
|
|
1476
|
+
}
|
|
1477
|
+
const tokenInput = {
|
|
1478
|
+
elements,
|
|
1479
|
+
params: {
|
|
1480
|
+
...options.return_url ? { return_url: options.return_url } : {},
|
|
1481
|
+
...options.billing_details ? { payment_method_data: { billing_details: options.billing_details } } : {}
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
const result = await stripe.createConfirmationToken(tokenInput);
|
|
1485
|
+
if (result.error) {
|
|
1486
|
+
throw new Error(result.error.message || "Payment confirmation token failed");
|
|
1487
|
+
}
|
|
1488
|
+
if (!result.confirmationToken?.id) {
|
|
1489
|
+
throw new Error("Stripe did not return a confirmation token");
|
|
1490
|
+
}
|
|
1491
|
+
return {
|
|
1492
|
+
confirmation_token_id: result.confirmationToken.id,
|
|
1493
|
+
return_url: options.return_url
|
|
1494
|
+
};
|
|
1495
|
+
},
|
|
1496
|
+
async handleNextAction(clientSecret) {
|
|
1497
|
+
const result = await stripe.handleNextAction({ clientSecret });
|
|
1498
|
+
if (result.error) {
|
|
1499
|
+
throw new Error(result.error.message || "Payment authentication failed");
|
|
1500
|
+
}
|
|
1501
|
+
},
|
|
1502
|
+
destroy() {
|
|
1503
|
+
paymentElement?.destroy();
|
|
1504
|
+
paymentElement = null;
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
function createElements(stripe, config) {
|
|
1509
|
+
return stripe.elements({
|
|
1510
|
+
mode: "payment",
|
|
1511
|
+
amount: config.amount,
|
|
1512
|
+
currency: normalizeCurrency(config.currency),
|
|
1513
|
+
paymentMethodCreation: "manual",
|
|
1514
|
+
...config.appearance ? { appearance: config.appearance } : {}
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1469
1518
|
// src/storefrontStore/utils.ts
|
|
1470
1519
|
function readErrorMessage(error, fallback) {
|
|
1471
1520
|
if (error instanceof Error && error.message) return error.message;
|
|
@@ -1517,7 +1566,7 @@ function priceForMarket(prices, market, fallbackCurrency) {
|
|
|
1517
1566
|
market: price?.market || market,
|
|
1518
1567
|
currency: price?.currency || fallbackCurrency || "",
|
|
1519
1568
|
compare_at: price?.compare_at,
|
|
1520
|
-
|
|
1569
|
+
contact_list_id: price?.contact_list_id
|
|
1521
1570
|
};
|
|
1522
1571
|
}
|
|
1523
1572
|
function availableStock(client, variant) {
|
|
@@ -1681,8 +1730,11 @@ function normalizeTimezoneGroups(groups) {
|
|
|
1681
1730
|
return normalized;
|
|
1682
1731
|
}
|
|
1683
1732
|
|
|
1684
|
-
// src/storefrontStore/
|
|
1685
|
-
function
|
|
1733
|
+
// src/storefrontStore/initialize.ts
|
|
1734
|
+
function firstFiniteNumber(...values) {
|
|
1735
|
+
return values.find((value) => typeof value === "number" && Number.isFinite(value));
|
|
1736
|
+
}
|
|
1737
|
+
function initialize(config) {
|
|
1686
1738
|
const client = createStorefront(config);
|
|
1687
1739
|
const session = nanostores.atom(client.session);
|
|
1688
1740
|
const locale = nanostores.atom(config.locale || client.getLocale());
|
|
@@ -1693,7 +1745,7 @@ function createArkyStore(config) {
|
|
|
1693
1745
|
const payment_config = nanostores.computed(session, (value) => {
|
|
1694
1746
|
const store = value?.store;
|
|
1695
1747
|
const methods = value?.market?.payment_methods || [];
|
|
1696
|
-
const hasCreditCard = methods.some((method) => method.
|
|
1748
|
+
const hasCreditCard = methods.some((method) => method.type === "credit_card");
|
|
1697
1749
|
return { provider: store?.payment || null, enabled: hasCreditCard && !!store?.payment };
|
|
1698
1750
|
});
|
|
1699
1751
|
const cart = nanostores.atom(null);
|
|
@@ -1702,6 +1754,8 @@ function createArkyStore(config) {
|
|
|
1702
1754
|
const quote = nanostores.atom(null);
|
|
1703
1755
|
const promo_code = nanostores.atom(null);
|
|
1704
1756
|
const last_order = nanostores.atom(null);
|
|
1757
|
+
const payment_controller = nanostores.atom(null);
|
|
1758
|
+
const payment_ready = nanostores.computed(payment_controller, (value) => value !== null);
|
|
1705
1759
|
const cart_status = nanostores.map({
|
|
1706
1760
|
loading: false,
|
|
1707
1761
|
syncing: false,
|
|
@@ -1712,20 +1766,48 @@ function createArkyStore(config) {
|
|
|
1712
1766
|
selected_shipping_method_id: null,
|
|
1713
1767
|
user_token: null
|
|
1714
1768
|
});
|
|
1769
|
+
function rawProductItemCount(value) {
|
|
1770
|
+
return (value?.items || []).reduce((total, item) => {
|
|
1771
|
+
if (item.type !== "product") return total;
|
|
1772
|
+
return total + (item.quantity || 0);
|
|
1773
|
+
}, 0);
|
|
1774
|
+
}
|
|
1775
|
+
function rawServiceItemCount(value) {
|
|
1776
|
+
return (value?.items || []).reduce((total, item) => {
|
|
1777
|
+
if (item.type !== "service") return total;
|
|
1778
|
+
return total + Math.max(1, item.slots?.length || 0);
|
|
1779
|
+
}, 0);
|
|
1780
|
+
}
|
|
1715
1781
|
const product_item_count = nanostores.computed(
|
|
1716
|
-
product_items,
|
|
1717
|
-
(items) =>
|
|
1782
|
+
[cart, product_items],
|
|
1783
|
+
(cartValue, items) => Math.max(
|
|
1784
|
+
rawProductItemCount(cartValue),
|
|
1785
|
+
items.reduce((total, item) => total + (item.quantity || 0), 0)
|
|
1786
|
+
)
|
|
1787
|
+
);
|
|
1788
|
+
const service_item_count = nanostores.computed(
|
|
1789
|
+
[cart, service_items],
|
|
1790
|
+
(cartValue, items) => Math.max(rawServiceItemCount(cartValue), items.length)
|
|
1791
|
+
);
|
|
1792
|
+
const item_count = nanostores.computed(
|
|
1793
|
+
[cart, product_item_count, service_item_count],
|
|
1794
|
+
(cartValue, products, services) => Math.max(cartValue?.item_count || 0, products + services)
|
|
1718
1795
|
);
|
|
1719
|
-
const service_item_count = nanostores.computed(service_items, (items) => items.length);
|
|
1720
|
-
const item_count = nanostores.computed([product_item_count, service_item_count], (products, services) => products + services);
|
|
1721
1796
|
const snapshot = nanostores.computed([cart, product_items, service_items, item_count], (cartValue, products, services, count) => ({
|
|
1722
1797
|
cart: cartValue,
|
|
1723
1798
|
product_items: products,
|
|
1724
1799
|
service_items: services,
|
|
1725
1800
|
item_count: count
|
|
1726
1801
|
}));
|
|
1802
|
+
let cartWriteRevision = 0;
|
|
1803
|
+
let sessionRequest = null;
|
|
1804
|
+
let cartRequest = null;
|
|
1805
|
+
function nextCartWriteRevision() {
|
|
1806
|
+
cartWriteRevision += 1;
|
|
1807
|
+
return cartWriteRevision;
|
|
1808
|
+
}
|
|
1727
1809
|
const cms_state = nanostores.map({
|
|
1728
|
-
|
|
1810
|
+
entries: {},
|
|
1729
1811
|
forms: {},
|
|
1730
1812
|
loading: false,
|
|
1731
1813
|
error: null
|
|
@@ -1764,6 +1846,51 @@ function createArkyStore(config) {
|
|
|
1764
1846
|
function currentCurrency() {
|
|
1765
1847
|
return currency.get() || market.get()?.currency || null;
|
|
1766
1848
|
}
|
|
1849
|
+
function currentStripePublishableKey() {
|
|
1850
|
+
const provider = payment_config.get()?.provider;
|
|
1851
|
+
return provider?.publishable_key || provider?.publishableKey || provider?.publicKey || null;
|
|
1852
|
+
}
|
|
1853
|
+
function currentPaymentAmount() {
|
|
1854
|
+
return Math.max(
|
|
1855
|
+
0,
|
|
1856
|
+
firstFiniteNumber(
|
|
1857
|
+
quote.get()?.charge_amount,
|
|
1858
|
+
quote.get()?.payment?.total,
|
|
1859
|
+
cart.get()?.quote_snapshot?.charge_amount,
|
|
1860
|
+
cart.get()?.quote_snapshot?.payment?.total,
|
|
1861
|
+
cart.get()?.quote_snapshot?.total
|
|
1862
|
+
) ?? 0
|
|
1863
|
+
);
|
|
1864
|
+
}
|
|
1865
|
+
function setPaymentController(controller) {
|
|
1866
|
+
const current = payment_controller.get();
|
|
1867
|
+
if (current && current !== controller) {
|
|
1868
|
+
current.destroy();
|
|
1869
|
+
}
|
|
1870
|
+
payment_controller.set(controller);
|
|
1871
|
+
return controller;
|
|
1872
|
+
}
|
|
1873
|
+
function destroyPaymentController() {
|
|
1874
|
+
setPaymentController(null);
|
|
1875
|
+
}
|
|
1876
|
+
async function mountStripePayment(target, options = {}) {
|
|
1877
|
+
const publishableKey = options.publishableKey || currentStripePublishableKey();
|
|
1878
|
+
if (!publishableKey) {
|
|
1879
|
+
throw new Error("Stripe publishable key is required to mount card payment");
|
|
1880
|
+
}
|
|
1881
|
+
const controller = await createStripeConfirmationTokenController({
|
|
1882
|
+
publishableKey,
|
|
1883
|
+
amount: Math.max(0, options.amount ?? currentPaymentAmount()),
|
|
1884
|
+
currency: options.currency || currentCurrency() || "usd",
|
|
1885
|
+
...options.appearance ? { appearance: options.appearance } : {}
|
|
1886
|
+
});
|
|
1887
|
+
controller.mount(target);
|
|
1888
|
+
setPaymentController(controller);
|
|
1889
|
+
return controller;
|
|
1890
|
+
}
|
|
1891
|
+
function updatePaymentController(input) {
|
|
1892
|
+
payment_controller.get()?.update(input);
|
|
1893
|
+
}
|
|
1767
1894
|
function marketForLocale(value) {
|
|
1768
1895
|
return config.marketForLocale?.(value) || null;
|
|
1769
1896
|
}
|
|
@@ -1771,7 +1898,12 @@ function createArkyStore(config) {
|
|
|
1771
1898
|
const current = session.get();
|
|
1772
1899
|
const marketKey = currentMarketKey();
|
|
1773
1900
|
if (current && (!marketKey || current.market?.key === marketKey)) return current;
|
|
1774
|
-
|
|
1901
|
+
if (!sessionRequest) {
|
|
1902
|
+
sessionRequest = identify({ market: marketKey }).finally(() => {
|
|
1903
|
+
sessionRequest = null;
|
|
1904
|
+
});
|
|
1905
|
+
}
|
|
1906
|
+
return sessionRequest;
|
|
1775
1907
|
}
|
|
1776
1908
|
async function identify(params = {}) {
|
|
1777
1909
|
if (params.market) setMarket(params.market);
|
|
@@ -1797,21 +1929,27 @@ function createArkyStore(config) {
|
|
|
1797
1929
|
if (context.market) setMarket(context.market);
|
|
1798
1930
|
}
|
|
1799
1931
|
async function ensureCart() {
|
|
1932
|
+
if (cartRequest) return cartRequest;
|
|
1800
1933
|
cart_status.setKey("loading", true);
|
|
1801
1934
|
cart_status.setKey("error", null);
|
|
1802
|
-
|
|
1935
|
+
const refreshRevision = cartWriteRevision;
|
|
1936
|
+
cartRequest = (async () => {
|
|
1803
1937
|
await ensureSession();
|
|
1804
1938
|
const response = await client.cart.refresh({ market: currentMarketKey() });
|
|
1805
|
-
await
|
|
1939
|
+
await applyCartResponse(response, { ifRevision: refreshRevision });
|
|
1806
1940
|
return response;
|
|
1941
|
+
})();
|
|
1942
|
+
try {
|
|
1943
|
+
return await cartRequest;
|
|
1807
1944
|
} catch (error) {
|
|
1808
1945
|
cart_status.setKey("error", readErrorMessage(error, "Failed to load cart."));
|
|
1809
1946
|
throw error;
|
|
1810
1947
|
} finally {
|
|
1948
|
+
cartRequest = null;
|
|
1811
1949
|
cart_status.setKey("loading", false);
|
|
1812
1950
|
}
|
|
1813
1951
|
}
|
|
1814
|
-
async function
|
|
1952
|
+
async function buildProductCartItem(item, source) {
|
|
1815
1953
|
try {
|
|
1816
1954
|
const product = await client.eshop.product.get({ id: item.product_id });
|
|
1817
1955
|
const variant = product.variants.find((candidate) => candidate.id === item.variant_id);
|
|
@@ -1823,6 +1961,7 @@ function createArkyStore(config) {
|
|
|
1823
1961
|
product_name: productName(product, currentLocale()),
|
|
1824
1962
|
product_slug: entitySlug(product, currentLocale()),
|
|
1825
1963
|
variant_attributes: variant.attributes,
|
|
1964
|
+
requires_shipping: variant.requires_shipping !== false,
|
|
1826
1965
|
price: priceForMarket(variant.prices, currentMarketKey(), currentCurrency()),
|
|
1827
1966
|
quantity: item.quantity,
|
|
1828
1967
|
added_at: source.created_at ? source.created_at * 1e3 : Date.now(),
|
|
@@ -1832,7 +1971,7 @@ function createArkyStore(config) {
|
|
|
1832
1971
|
return null;
|
|
1833
1972
|
}
|
|
1834
1973
|
}
|
|
1835
|
-
async function
|
|
1974
|
+
async function buildServiceCartItems(items) {
|
|
1836
1975
|
const rows = [];
|
|
1837
1976
|
for (const item of items) {
|
|
1838
1977
|
let service = null;
|
|
@@ -1860,7 +1999,10 @@ function createArkyStore(config) {
|
|
|
1860
1999
|
}
|
|
1861
2000
|
return rows;
|
|
1862
2001
|
}
|
|
1863
|
-
async function
|
|
2002
|
+
async function applyCartResponse(response, options = {}) {
|
|
2003
|
+
if (options.ifRevision !== void 0 && options.ifRevision !== cartWriteRevision) {
|
|
2004
|
+
return cart.get() || response;
|
|
2005
|
+
}
|
|
1864
2006
|
cart.set(response);
|
|
1865
2007
|
cart_status.setKey("user_token", response.token || null);
|
|
1866
2008
|
cart_status.setKey("selected_shipping_method_id", response.shipping_method_id || null);
|
|
@@ -1868,9 +2010,9 @@ function createArkyStore(config) {
|
|
|
1868
2010
|
quote.set(response.quote_snapshot || null);
|
|
1869
2011
|
const items = response.items || [];
|
|
1870
2012
|
const products = await Promise.all(
|
|
1871
|
-
items.filter((item) => item.type === "product").map((item) =>
|
|
2013
|
+
items.filter((item) => item.type === "product").map((item) => buildProductCartItem(item, response))
|
|
1872
2014
|
);
|
|
1873
|
-
const services = await
|
|
2015
|
+
const services = await buildServiceCartItems(
|
|
1874
2016
|
items.filter((item) => item.type === "service")
|
|
1875
2017
|
);
|
|
1876
2018
|
product_items.set(products.filter((item) => item !== null));
|
|
@@ -1883,7 +2025,7 @@ function createArkyStore(config) {
|
|
|
1883
2025
|
...toServiceCheckoutItems(input.service_items || service_items.get())
|
|
1884
2026
|
];
|
|
1885
2027
|
}
|
|
1886
|
-
async function syncCart(input = {}) {
|
|
2028
|
+
async function syncCart(input = {}, writeRevision = nextCartWriteRevision()) {
|
|
1887
2029
|
cart_status.setKey("syncing", true);
|
|
1888
2030
|
cart_status.setKey("error", null);
|
|
1889
2031
|
try {
|
|
@@ -1896,14 +2038,14 @@ function createArkyStore(config) {
|
|
|
1896
2038
|
billing_address: input.billing_address || void 0,
|
|
1897
2039
|
forms: normalizeForms(input.forms),
|
|
1898
2040
|
promo_code: input.promo_code === void 0 ? promo_code.get() || void 0 : input.promo_code || void 0,
|
|
1899
|
-
|
|
2041
|
+
payment_method_key: input.payment_method_key || void 0,
|
|
1900
2042
|
shipping_method_id: input.shipping_method_id || cart_status.get().selected_shipping_method_id || void 0
|
|
1901
2043
|
});
|
|
1902
2044
|
if (input.promo_code !== void 0) promo_code.set(input.promo_code);
|
|
1903
2045
|
if (input.shipping_method_id !== void 0) {
|
|
1904
2046
|
cart_status.setKey("selected_shipping_method_id", input.shipping_method_id);
|
|
1905
2047
|
}
|
|
1906
|
-
await
|
|
2048
|
+
await applyCartResponse(response, { ifRevision: writeRevision });
|
|
1907
2049
|
return response;
|
|
1908
2050
|
} catch (error) {
|
|
1909
2051
|
cart_status.setKey("error", readErrorMessage(error, "Failed to sync cart."));
|
|
@@ -1914,6 +2056,7 @@ function createArkyStore(config) {
|
|
|
1914
2056
|
}
|
|
1915
2057
|
async function addProduct(product, variant, quantity = 1) {
|
|
1916
2058
|
cart_status.setKey("error", null);
|
|
2059
|
+
const writeRevision = nextCartWriteRevision();
|
|
1917
2060
|
try {
|
|
1918
2061
|
const current = cart.get() || await ensureCart();
|
|
1919
2062
|
const response = await client.cart.addItem({
|
|
@@ -1925,8 +2068,7 @@ function createArkyStore(config) {
|
|
|
1925
2068
|
quantity
|
|
1926
2069
|
}
|
|
1927
2070
|
});
|
|
1928
|
-
await
|
|
1929
|
-
await client.activity.track({ type: "cart_added", payload: { product_id: product.id, variant_id: variant.id, quantity } });
|
|
2071
|
+
await applyCartResponse(response, { ifRevision: writeRevision });
|
|
1930
2072
|
return response;
|
|
1931
2073
|
} catch (error) {
|
|
1932
2074
|
cart_status.setKey("error", readErrorMessage(error, "Failed to add product to cart."));
|
|
@@ -1934,15 +2076,17 @@ function createArkyStore(config) {
|
|
|
1934
2076
|
}
|
|
1935
2077
|
}
|
|
1936
2078
|
async function setProductQuantity(itemId, quantity) {
|
|
2079
|
+
const writeRevision = nextCartWriteRevision();
|
|
1937
2080
|
const next = product_items.get().map((item) => {
|
|
1938
2081
|
if (item.id !== itemId) return item;
|
|
1939
2082
|
const bounded = item.max_stock ? Math.min(Math.max(1, quantity), item.max_stock) : Math.max(1, quantity);
|
|
1940
2083
|
return { ...item, quantity: bounded };
|
|
1941
2084
|
});
|
|
1942
2085
|
product_items.set(next);
|
|
1943
|
-
return syncCart({ product_items: next });
|
|
2086
|
+
return syncCart({ product_items: next }, writeRevision);
|
|
1944
2087
|
}
|
|
1945
2088
|
async function removeProduct(itemId) {
|
|
2089
|
+
const writeRevision = nextCartWriteRevision();
|
|
1946
2090
|
const item = product_items.get().find((candidate) => candidate.id === itemId);
|
|
1947
2091
|
product_items.set(product_items.get().filter((candidate) => candidate.id !== itemId));
|
|
1948
2092
|
const current = cart.get();
|
|
@@ -1953,31 +2097,37 @@ function createArkyStore(config) {
|
|
|
1953
2097
|
product_id: item.product_id,
|
|
1954
2098
|
variant_id: item.variant_id
|
|
1955
2099
|
});
|
|
1956
|
-
await
|
|
1957
|
-
await client.activity.track({ type: "cart_removed", payload: { product_id: item.product_id, variant_id: item.variant_id } });
|
|
2100
|
+
await applyCartResponse(response, { ifRevision: writeRevision });
|
|
1958
2101
|
return response;
|
|
1959
2102
|
}
|
|
1960
2103
|
async function addServiceItem(item) {
|
|
2104
|
+
const writeRevision = nextCartWriteRevision();
|
|
1961
2105
|
const next = [...service_items.get(), item];
|
|
1962
2106
|
service_items.set(next);
|
|
1963
|
-
return syncCart({ service_items: next });
|
|
2107
|
+
return syncCart({ service_items: next }, writeRevision);
|
|
1964
2108
|
}
|
|
1965
2109
|
async function removeServiceItem(itemId) {
|
|
2110
|
+
const writeRevision = nextCartWriteRevision();
|
|
1966
2111
|
const next = service_items.get().filter((item) => item.id !== itemId);
|
|
1967
2112
|
service_items.set(next);
|
|
1968
|
-
return syncCart({ service_items: next });
|
|
2113
|
+
return syncCart({ service_items: next }, writeRevision);
|
|
1969
2114
|
}
|
|
1970
2115
|
async function clearCart() {
|
|
2116
|
+
const writeRevision = nextCartWriteRevision();
|
|
2117
|
+
const current = cart.get();
|
|
2118
|
+
clearLocalCart();
|
|
2119
|
+
if (!current) return null;
|
|
2120
|
+
const response = await client.cart.clear({ id: current.id });
|
|
2121
|
+
await applyCartResponse(response, { ifRevision: writeRevision });
|
|
2122
|
+
return response;
|
|
2123
|
+
}
|
|
2124
|
+
function clearLocalCart() {
|
|
1971
2125
|
product_items.set([]);
|
|
1972
2126
|
service_items.set([]);
|
|
2127
|
+
cart.set(null);
|
|
1973
2128
|
quote.set(null);
|
|
1974
2129
|
promo_code.set(null);
|
|
1975
2130
|
cart_status.setKey("selected_shipping_method_id", null);
|
|
1976
|
-
const current = cart.get();
|
|
1977
|
-
if (!current) return null;
|
|
1978
|
-
const response = await client.cart.clear({ id: current.id });
|
|
1979
|
-
await hydrateCart(response);
|
|
1980
|
-
return response;
|
|
1981
2131
|
}
|
|
1982
2132
|
async function fetchQuote(input = {}) {
|
|
1983
2133
|
if (checkoutItems(input).length === 0) {
|
|
@@ -2005,16 +2155,51 @@ function createArkyStore(config) {
|
|
|
2005
2155
|
cart_status.setKey("error", null);
|
|
2006
2156
|
try {
|
|
2007
2157
|
const current = await syncCart(input);
|
|
2008
|
-
|
|
2158
|
+
const quoteValue = quote.get();
|
|
2159
|
+
const paymentMethodKey = input.payment_method_key || current.payment_method_key || quoteValue?.payment?.payment_method_key || void 0;
|
|
2160
|
+
let chargeAmount = firstFiniteNumber(
|
|
2161
|
+
quoteValue?.charge_amount,
|
|
2162
|
+
quoteValue?.payment?.total,
|
|
2163
|
+
current.quote_snapshot?.charge_amount,
|
|
2164
|
+
current.quote_snapshot?.payment?.total
|
|
2165
|
+
);
|
|
2166
|
+
if (paymentMethodKey === "credit_card" && chargeAmount === void 0) {
|
|
2167
|
+
const latestQuote = await client.cart.quote({ id: current.id });
|
|
2168
|
+
quote.set(latestQuote);
|
|
2169
|
+
chargeAmount = firstFiniteNumber(
|
|
2170
|
+
latestQuote.charge_amount,
|
|
2171
|
+
latestQuote.payment?.total,
|
|
2172
|
+
latestQuote.total
|
|
2173
|
+
);
|
|
2174
|
+
}
|
|
2175
|
+
const needsConfirmationToken = paymentMethodKey === "credit_card" && (chargeAmount === void 0 || chargeAmount > 0);
|
|
2176
|
+
let confirmationTokenId;
|
|
2177
|
+
let returnUrl = input.return_url;
|
|
2178
|
+
const paymentController = input.payment ?? payment_controller.get();
|
|
2179
|
+
if (needsConfirmationToken) {
|
|
2180
|
+
if (!paymentController) throw new Error("Payment controller is required for card checkout");
|
|
2181
|
+
returnUrl = returnUrl || (typeof window !== "undefined" ? window.location.href : void 0);
|
|
2182
|
+
const token = await paymentController.createConfirmationToken({
|
|
2183
|
+
return_url: returnUrl,
|
|
2184
|
+
billing_details: input.billing_details
|
|
2185
|
+
});
|
|
2186
|
+
confirmationTokenId = token.confirmation_token_id;
|
|
2187
|
+
returnUrl = token.return_url || returnUrl;
|
|
2188
|
+
}
|
|
2009
2189
|
const response = await client.cart.checkout({
|
|
2010
2190
|
id: current.id,
|
|
2011
|
-
|
|
2191
|
+
payment_method_key: paymentMethodKey,
|
|
2192
|
+
confirmation_token_id: confirmationTokenId,
|
|
2193
|
+
return_url: returnUrl
|
|
2012
2194
|
});
|
|
2013
|
-
|
|
2195
|
+
if (response.payment_action.type === "handle_next_action") {
|
|
2196
|
+
if (!paymentController) throw new Error("Payment controller is required for card authentication");
|
|
2197
|
+
await paymentController.handleNextAction(response.payment_action.client_secret);
|
|
2198
|
+
}
|
|
2014
2199
|
const stored = {
|
|
2015
2200
|
order_id: response.order_id,
|
|
2016
2201
|
number: response.number,
|
|
2017
|
-
|
|
2202
|
+
payment_action: response.payment_action,
|
|
2018
2203
|
payment: response.payment,
|
|
2019
2204
|
product_items: input.product_items || product_items.get(),
|
|
2020
2205
|
service_items: input.service_items || service_items.get(),
|
|
@@ -2022,17 +2207,13 @@ function createArkyStore(config) {
|
|
|
2022
2207
|
billing_address: input.billing_address || null,
|
|
2023
2208
|
total: quoteValue?.payment?.total || quoteValue?.total || response.payment?.total,
|
|
2024
2209
|
currency: quoteValue?.payment?.currency || currentCurrency(),
|
|
2025
|
-
|
|
2210
|
+
payment_method_key: paymentMethodKey || null,
|
|
2026
2211
|
created_at: Date.now()
|
|
2027
2212
|
};
|
|
2028
2213
|
last_order.set(stored);
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
quote.set(null);
|
|
2033
|
-
promo_code.set(null);
|
|
2034
|
-
cart_status.setKey("selected_shipping_method_id", null);
|
|
2035
|
-
await client.activity.track({ type: "purchase", payload: { order_id: response.order_id, number: response.number } });
|
|
2214
|
+
if (input.clear_after_checkout !== false) {
|
|
2215
|
+
clearLocalCart();
|
|
2216
|
+
}
|
|
2036
2217
|
return response;
|
|
2037
2218
|
} catch (error) {
|
|
2038
2219
|
cart_status.setKey("error", readErrorMessage(error, "Checkout failed."));
|
|
@@ -2452,7 +2633,7 @@ function createArkyStore(config) {
|
|
|
2452
2633
|
...toServiceCartItem(slot),
|
|
2453
2634
|
forms: []
|
|
2454
2635
|
})),
|
|
2455
|
-
|
|
2636
|
+
payment_method_key: paymentMethodId,
|
|
2456
2637
|
promo_code: state.promoCode || void 0,
|
|
2457
2638
|
forms
|
|
2458
2639
|
});
|
|
@@ -2473,7 +2654,7 @@ function createArkyStore(config) {
|
|
|
2473
2654
|
service_state.setKey("promoCode", promoCode || null);
|
|
2474
2655
|
const response = await fetchQuote({
|
|
2475
2656
|
service_items: state.cart.map(toServiceCartItem),
|
|
2476
|
-
|
|
2657
|
+
payment_method_key: paymentMethodId,
|
|
2477
2658
|
promo_code: promoCode || void 0
|
|
2478
2659
|
});
|
|
2479
2660
|
service_state.setKey("cartId", cart.get()?.id || null);
|
|
@@ -2520,18 +2701,38 @@ function createArkyStore(config) {
|
|
|
2520
2701
|
}
|
|
2521
2702
|
};
|
|
2522
2703
|
service_items.subscribe((items) => setServiceCartFromServiceItems(items));
|
|
2523
|
-
async function
|
|
2704
|
+
async function loadEntry(params, options) {
|
|
2524
2705
|
cms_state.setKey("loading", true);
|
|
2525
2706
|
cms_state.setKey("error", null);
|
|
2526
2707
|
try {
|
|
2527
|
-
const { locale: nextLocale, market: nextMarket, ...
|
|
2708
|
+
const { locale: nextLocale, market: nextMarket, ...entryParams } = params;
|
|
2528
2709
|
setContext({ locale: nextLocale, market: nextMarket });
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2710
|
+
if (entryParams.id) {
|
|
2711
|
+
const entry2 = await client.cms.entry.get(entryParams, options);
|
|
2712
|
+
const cacheKey = entryParams.key || entryParams.id || entry2.id;
|
|
2713
|
+
cms_state.setKey("entries", { ...cms_state.get().entries, [cacheKey]: entry2 });
|
|
2714
|
+
return entry2;
|
|
2715
|
+
}
|
|
2716
|
+
if (!entryParams.collection_id || !entryParams.key) {
|
|
2717
|
+
throw new Error("ArkyCmsEntryParams requires id, or collection_id and key");
|
|
2718
|
+
}
|
|
2719
|
+
const result = await client.cms.entry.find(
|
|
2720
|
+
{
|
|
2721
|
+
...entryParams,
|
|
2722
|
+
collection_id: entryParams.collection_id,
|
|
2723
|
+
key: entryParams.key,
|
|
2724
|
+
limit: 1
|
|
2725
|
+
},
|
|
2726
|
+
options
|
|
2727
|
+
);
|
|
2728
|
+
const entry = result.items?.[0];
|
|
2729
|
+
if (!entry) {
|
|
2730
|
+
throw new Error("CMS entry not found");
|
|
2731
|
+
}
|
|
2732
|
+
cms_state.setKey("entries", { ...cms_state.get().entries, [entryParams.key]: entry });
|
|
2733
|
+
return entry;
|
|
2533
2734
|
} catch (error) {
|
|
2534
|
-
cms_state.setKey("error", readErrorMessage(error, "Failed to load CMS
|
|
2735
|
+
cms_state.setKey("error", readErrorMessage(error, "Failed to load CMS entry."));
|
|
2535
2736
|
throw error;
|
|
2536
2737
|
} finally {
|
|
2537
2738
|
cms_state.setKey("loading", false);
|
|
@@ -2618,19 +2819,14 @@ function createArkyStore(config) {
|
|
|
2618
2819
|
eshop_state.setKey("loading_availability", false);
|
|
2619
2820
|
}
|
|
2620
2821
|
}
|
|
2621
|
-
async function
|
|
2622
|
-
|
|
2623
|
-
const
|
|
2624
|
-
|
|
2625
|
-
session: session.get()
|
|
2626
|
-
};
|
|
2627
|
-
if (shouldIdentify) results.session = await ensureSession();
|
|
2628
|
-
if (options.hydrateCart) results.cart = await ensureCart();
|
|
2629
|
-
if (options.track) await client.activity.track(options.track);
|
|
2630
|
-
return results;
|
|
2822
|
+
async function useExperiment(params) {
|
|
2823
|
+
await ensureSession();
|
|
2824
|
+
const input = typeof params === "string" ? { key: params } : params;
|
|
2825
|
+
return client.experiments.use(input);
|
|
2631
2826
|
}
|
|
2632
|
-
async function
|
|
2633
|
-
|
|
2827
|
+
async function trackAction(params) {
|
|
2828
|
+
await ensureSession();
|
|
2829
|
+
return client.action.track(params);
|
|
2634
2830
|
}
|
|
2635
2831
|
const cart_store = {
|
|
2636
2832
|
cart,
|
|
@@ -2644,17 +2840,26 @@ function createArkyStore(config) {
|
|
|
2644
2840
|
service_item_count,
|
|
2645
2841
|
item_count,
|
|
2646
2842
|
snapshot,
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
sync: syncCart,
|
|
2843
|
+
load: ensureCart,
|
|
2844
|
+
refresh: syncCart,
|
|
2650
2845
|
addProduct,
|
|
2651
2846
|
setProductQuantity,
|
|
2652
2847
|
removeProduct,
|
|
2653
2848
|
addServiceItem,
|
|
2654
2849
|
removeServiceItem,
|
|
2655
2850
|
clear: clearCart,
|
|
2851
|
+
clearLocal: clearLocalCart,
|
|
2656
2852
|
quote: fetchQuote,
|
|
2657
2853
|
checkout,
|
|
2854
|
+
payment: {
|
|
2855
|
+
controller: payment_controller,
|
|
2856
|
+
ready: payment_ready,
|
|
2857
|
+
setController: setPaymentController,
|
|
2858
|
+
getController: () => payment_controller.get(),
|
|
2859
|
+
mountStripe: mountStripePayment,
|
|
2860
|
+
update: updatePaymentController,
|
|
2861
|
+
destroy: destroyPaymentController
|
|
2862
|
+
},
|
|
2658
2863
|
applyPromoCode(code, input = {}) {
|
|
2659
2864
|
promo_code.set(code);
|
|
2660
2865
|
return fetchQuote({ ...input, promo_code: code });
|
|
@@ -2728,30 +2933,29 @@ function createArkyStore(config) {
|
|
|
2728
2933
|
currency,
|
|
2729
2934
|
allowed_payment_methods,
|
|
2730
2935
|
payment_config,
|
|
2731
|
-
|
|
2732
|
-
initialize,
|
|
2936
|
+
cart: cart_store,
|
|
2733
2937
|
identify,
|
|
2734
2938
|
verify: client.verify,
|
|
2735
2939
|
me: client.me,
|
|
2736
2940
|
logout: client.logout,
|
|
2737
2941
|
onAuthStateChanged: client.onAuthStateChanged,
|
|
2738
|
-
get currentSession() {
|
|
2739
|
-
return session.get();
|
|
2740
|
-
},
|
|
2741
2942
|
get isAuthenticated() {
|
|
2742
2943
|
return client.isAuthenticated;
|
|
2743
2944
|
},
|
|
2744
2945
|
setMarket,
|
|
2745
2946
|
setLocale,
|
|
2746
2947
|
setContext,
|
|
2948
|
+
getStoreId: client.getStoreId,
|
|
2747
2949
|
getMarket: currentMarketKey,
|
|
2748
2950
|
getLocale: currentLocale,
|
|
2749
2951
|
cms: {
|
|
2750
2952
|
state: cms_state,
|
|
2751
|
-
|
|
2752
|
-
get:
|
|
2753
|
-
|
|
2754
|
-
|
|
2953
|
+
collection: {
|
|
2954
|
+
get: (params, options) => client.cms.collection.get(params, options)
|
|
2955
|
+
},
|
|
2956
|
+
entry: {
|
|
2957
|
+
get: loadEntry,
|
|
2958
|
+
find: (params, options) => client.cms.entry.find(params, options)
|
|
2755
2959
|
},
|
|
2756
2960
|
form: {
|
|
2757
2961
|
get: loadForm,
|
|
@@ -2772,24 +2976,28 @@ function createArkyStore(config) {
|
|
|
2772
2976
|
cart: cart_store
|
|
2773
2977
|
},
|
|
2774
2978
|
crm: client.crm,
|
|
2775
|
-
|
|
2979
|
+
action: {
|
|
2776
2980
|
track(params) {
|
|
2777
|
-
return
|
|
2981
|
+
return trackAction(params);
|
|
2778
2982
|
},
|
|
2779
2983
|
pageView(payload = {}) {
|
|
2780
|
-
return
|
|
2984
|
+
return trackAction({ key: "page.view", payload });
|
|
2781
2985
|
},
|
|
2782
2986
|
state: nanostores.atom(null)
|
|
2783
2987
|
},
|
|
2988
|
+
experiments: {
|
|
2989
|
+
use: useExperiment
|
|
2990
|
+
},
|
|
2991
|
+
support: client.support,
|
|
2784
2992
|
store: client.store,
|
|
2785
|
-
automation: client.automation,
|
|
2786
2993
|
utils: client.utils
|
|
2787
2994
|
};
|
|
2788
2995
|
}
|
|
2789
2996
|
|
|
2790
|
-
exports.
|
|
2791
|
-
exports.createArkyStore = createArkyStore;
|
|
2997
|
+
exports.COMMON_ACTION_KEYS = COMMON_ACTION_KEYS;
|
|
2792
2998
|
exports.createCartController = createCartController;
|
|
2793
2999
|
exports.createStorefront = createStorefront;
|
|
3000
|
+
exports.createStripeConfirmationTokenController = createStripeConfirmationTokenController;
|
|
3001
|
+
exports.initialize = initialize;
|
|
2794
3002
|
//# sourceMappingURL=storefront.cjs.map
|
|
2795
3003
|
//# sourceMappingURL=storefront.cjs.map
|