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