arky-sdk 0.9.20 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,70 +40,50 @@ var COMMON_ACTION_KEYS = [
40
40
  "share",
41
41
  "wishlist.added"
42
42
  ];
43
- var createActionApi = (apiConfig) => ({
43
+ var createActionApi = (apiConfig, lifecycle) => ({
44
44
  COMMON_ACTION_KEYS,
45
45
  async track(params) {
46
+ await lifecycle.ensureVisitorSession();
46
47
  try {
47
- await apiConfig.httpClient.post(
48
- `/v1/storefront/${apiConfig.storeId}/actions/track`,
49
- { key: params.key, payload: params.payload }
50
- );
48
+ await apiConfig.httpClient.post("/v1/storefront/actions/track", {
49
+ key: params.key,
50
+ payload: params.payload
51
+ });
51
52
  } catch {
52
53
  }
53
54
  }
54
55
  });
55
- var createStorefrontApi = (apiConfig, updateContactSession) => {
56
- const base = (storeId = apiConfig.storeId) => `/v1/storefront/${storeId}`;
57
- const pendingVerifications = /* @__PURE__ */ new Map();
56
+ var createStorefrontApi = (apiConfig, updateContactSession, lifecycle) => {
57
+ const base = "/v1/storefront";
58
58
  function persistIdentification(result) {
59
- const issued = result.token;
60
- if (issued?.token) {
59
+ const sessionToken = result.token?.token;
60
+ if (sessionToken) {
61
61
  updateContactSession(() => ({
62
- access_token: issued.token,
63
- contact: result.contact,
64
- store: result.store,
65
- market: result.market
62
+ sessionToken,
63
+ contact: result.contact
66
64
  }));
67
65
  } else {
68
- if (result.verification_challenge) {
69
- pendingVerifications.set(result.verification_challenge.challenge_id, {
70
- store: result.store,
71
- market: result.market
72
- });
73
- }
74
66
  updateContactSession(
75
- (current) => current ? {
76
- ...current,
77
- contact: result.contact,
78
- store: result.store,
79
- market: result.market
80
- } : null
67
+ (current) => current ? { ...current, contact: result.contact } : null
81
68
  );
82
69
  }
83
70
  return result;
84
71
  }
85
72
  async function submitIdentification(path, params, options) {
86
- const store_id = apiConfig.storeId;
87
73
  const result = await apiConfig.httpClient.post(
88
- `${base(store_id)}/account/${path}`,
89
- {
90
- store_id,
91
- market: params?.market || apiConfig.market || null,
92
- email: params?.email
93
- },
74
+ `${base}/account/${path}`,
75
+ { email: params?.email },
94
76
  options
95
77
  );
96
78
  return persistIdentification(result);
97
79
  }
98
80
  return {
99
81
  store: {
100
- getStore(options) {
101
- return apiConfig.httpClient.get(base(), options);
102
- },
82
+ getSetup: lifecycle.getSetup,
103
83
  location: {
104
84
  getCountries(options) {
105
85
  return apiConfig.httpClient.get(
106
- `/v1/platform/countries`,
86
+ "/v1/platform/countries",
107
87
  options
108
88
  );
109
89
  },
@@ -115,13 +95,13 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
115
95
  },
116
96
  list(options) {
117
97
  return apiConfig.httpClient.get(
118
- `${base()}/locations`,
98
+ `${base}/locations`,
119
99
  options
120
100
  );
121
101
  },
122
102
  get(id, options) {
123
103
  return apiConfig.httpClient.get(
124
- `${base()}/locations/${id}`,
104
+ `${base}/locations/${id}`,
125
105
  options
126
106
  );
127
107
  }
@@ -129,13 +109,13 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
129
109
  market: {
130
110
  list(options) {
131
111
  return apiConfig.httpClient.get(
132
- `${base()}/markets`,
112
+ `${base}/markets`,
133
113
  options
134
114
  );
135
115
  },
136
116
  get(id, options) {
137
117
  return apiConfig.httpClient.get(
138
- `${base()}/markets/${id}`,
118
+ `${base}/markets/${id}`,
139
119
  options
140
120
  );
141
121
  }
@@ -144,85 +124,59 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
144
124
  cms: {
145
125
  collection: {
146
126
  get(params, options) {
147
- const store_id = params.store_id || apiConfig.storeId;
148
- const identifier = params.id !== void 0 ? params.id : `${store_id}:${params.key}`;
127
+ const identifier = params.id ?? params.key;
149
128
  return apiConfig.httpClient.get(
150
- `${base(store_id)}/collections/${identifier}`,
129
+ `${base}/collections/${identifier}`,
151
130
  options
152
131
  );
153
132
  }
154
133
  },
155
134
  entry: {
156
135
  get(params, options) {
157
- const store_id = params.store_id || apiConfig.storeId;
158
- if (!params.id) {
159
- throw new Error("GetEntryParams requires id");
160
- }
161
136
  return apiConfig.httpClient.get(
162
- `${base(store_id)}/entries/${params.id}`,
137
+ `${base}/entries/${params.id}`,
163
138
  options
164
139
  );
165
140
  },
166
141
  find(params, options) {
167
- const { store_id, ...queryParams } = params;
168
142
  return apiConfig.httpClient.get(
169
- `${base(store_id)}/entries`,
170
- {
171
- ...options,
172
- params: queryParams
173
- }
143
+ `${base}/entries`,
144
+ { ...options, params }
174
145
  );
175
146
  }
176
147
  },
177
148
  form: {
178
149
  get(params, options) {
179
- const store_id = params.store_id || apiConfig.storeId;
180
- let identifier;
181
- if (params.id) {
182
- identifier = params.id;
183
- } else if (params.key) {
184
- identifier = `${store_id}:${params.key}`;
185
- } else {
186
- throw new Error("GetFormParams requires id or key");
187
- }
150
+ const identifier = params.id ?? params.key;
151
+ if (!identifier) throw new Error("GetFormParams requires id or key");
188
152
  return apiConfig.httpClient.get(
189
- `${base(store_id)}/forms/${identifier}`,
153
+ `${base}/forms/${identifier}`,
190
154
  options
191
155
  );
192
156
  },
193
- submit(params, options) {
194
- const { store_id, form_id, ...payload } = params;
195
- const target_store_id = store_id || apiConfig.storeId;
196
- if (!form_id) {
197
- throw new Error("SubmitFormParams requires form_id");
198
- }
157
+ async submit(params, options) {
158
+ await lifecycle.ensureVisitorSession();
159
+ const { form_id, ...payload } = params;
160
+ if (!form_id) throw new Error("SubmitFormParams requires form_id");
199
161
  return apiConfig.httpClient.post(
200
- `${base(target_store_id)}/forms/${form_id}/submissions`,
201
- { ...payload, form_id, store_id: target_store_id },
162
+ `${base}/forms/${form_id}/submissions`,
163
+ { ...payload, form_id },
202
164
  options
203
165
  );
204
166
  }
205
167
  },
206
168
  taxonomy: {
207
169
  get(params, options) {
208
- const store_id = params.store_id || apiConfig.storeId;
209
- let identifier;
210
- if (params.id) {
211
- identifier = params.id;
212
- } else if (params.key) {
213
- identifier = `${store_id}:${params.key}`;
214
- } else {
215
- throw new Error("GetTaxonomyParams requires id or key");
216
- }
170
+ const identifier = params.id ?? params.key;
171
+ if (!identifier) throw new Error("GetTaxonomyParams requires id or key");
217
172
  return apiConfig.httpClient.get(
218
- `${base(store_id)}/taxonomies/${identifier}`,
173
+ `${base}/taxonomies/${identifier}`,
219
174
  options
220
175
  );
221
176
  },
222
177
  getChildren(params, options) {
223
- const store_id = params.store_id || apiConfig.storeId;
224
178
  return apiConfig.httpClient.get(
225
- `${base(store_id)}/taxonomies/${params.id}/children`,
179
+ `${base}/taxonomies/${params.id}/children`,
226
180
  options
227
181
  );
228
182
  }
@@ -231,113 +185,90 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
231
185
  eshop: {
232
186
  product: {
233
187
  get(params, options) {
234
- const store_id = params.store_id || apiConfig.storeId;
235
- let identifier;
236
- if (params.id) {
237
- identifier = params.id;
238
- } else if (params.slug) {
239
- identifier = `${store_id}:${apiConfig.locale}:${params.slug}`;
240
- } else {
241
- throw new Error("GetProductParams requires id or slug");
242
- }
188
+ const identifier = params.id ?? params.slug;
189
+ if (!identifier) throw new Error("GetProductParams requires id or slug");
243
190
  return apiConfig.httpClient.get(
244
- `${base(store_id)}/products/${identifier}`,
191
+ `${base}/products/${identifier}`,
245
192
  options
246
193
  );
247
194
  },
248
195
  find(params, options) {
249
- const { store_id, ...queryParams } = params;
250
196
  return apiConfig.httpClient.get(
251
- `${base(store_id)}/products`,
252
- {
253
- ...options,
254
- params: queryParams
255
- }
197
+ `${base}/products`,
198
+ { ...options, params }
256
199
  );
257
200
  }
258
201
  },
259
202
  cart: {
260
- current(params = {}, options) {
261
- const store_id = params.store_id || apiConfig.storeId;
262
- const { store_id: _store_id, ...payload } = params;
203
+ async current(options) {
204
+ await lifecycle.ensureVisitorSession();
263
205
  return apiConfig.httpClient.post(
264
- `${base(store_id)}/carts/current`,
265
- {
266
- ...payload,
267
- store_id,
268
- market: payload.market || apiConfig.market
269
- },
206
+ `${base}/carts/current`,
207
+ {},
270
208
  options
271
209
  );
272
210
  },
273
- get(params, options) {
274
- const store_id = params.store_id || apiConfig.storeId;
211
+ async get(params, options) {
212
+ await lifecycle.ensureVisitorSession();
275
213
  return apiConfig.httpClient.get(
276
- `${base(store_id)}/carts/${params.id}`,
214
+ `${base}/carts/${params.id}`,
277
215
  {
278
216
  ...options,
279
217
  params: params.token ? { token: params.token } : options?.params
280
218
  }
281
219
  );
282
220
  },
283
- update(params, options) {
284
- const { store_id, items, ...payload } = params;
285
- const target = store_id || apiConfig.storeId;
221
+ async update(params, options) {
222
+ await lifecycle.ensureVisitorSession();
223
+ const { items, ...payload } = params;
286
224
  return apiConfig.httpClient.put(
287
- `${base(target)}/carts/${params.id}`,
225
+ `${base}/carts/${params.id}`,
288
226
  {
289
227
  ...payload,
290
- store_id: target,
291
228
  ...items ? { items: sanitizePublicCheckoutItems(items) } : {}
292
229
  },
293
230
  options
294
231
  );
295
232
  },
296
- addItem(params, options) {
297
- const { store_id, item, ...payload } = params;
298
- const target = store_id || apiConfig.storeId;
233
+ async addItem(params, options) {
234
+ await lifecycle.ensureVisitorSession();
235
+ const { item, ...payload } = params;
299
236
  return apiConfig.httpClient.post(
300
- `${base(target)}/carts/${params.id}/items`,
301
- {
302
- ...payload,
303
- store_id: target,
304
- item: sanitizePublicCheckoutItems([item])[0]
305
- },
237
+ `${base}/carts/${params.id}/items`,
238
+ { ...payload, item: sanitizePublicCheckoutItems([item])[0] },
306
239
  options
307
240
  );
308
241
  },
309
- removeItem(params, options) {
310
- const { store_id, ...payload } = params;
311
- const target = store_id || apiConfig.storeId;
242
+ async removeItem(params, options) {
243
+ await lifecycle.ensureVisitorSession();
312
244
  return apiConfig.httpClient.post(
313
- `${base(target)}/carts/${params.id}/items/remove`,
314
- { ...payload, store_id: target },
245
+ `${base}/carts/${params.id}/items/remove`,
246
+ params,
315
247
  options
316
248
  );
317
249
  },
318
- clear(params, options) {
319
- const store_id = params.store_id || apiConfig.storeId;
250
+ async clear(params, options) {
251
+ await lifecycle.ensureVisitorSession();
320
252
  return apiConfig.httpClient.post(
321
- `${base(store_id)}/carts/${params.id}/clear`,
322
- { id: params.id, store_id },
253
+ `${base}/carts/${params.id}/clear`,
254
+ { id: params.id },
323
255
  options
324
256
  );
325
257
  },
326
- quote(params, options) {
327
- const store_id = params.store_id || apiConfig.storeId;
258
+ async quote(params, options) {
259
+ await lifecycle.ensureVisitorSession();
328
260
  return apiConfig.httpClient.post(
329
- `${base(store_id)}/carts/${params.id}/quote`,
330
- { id: params.id, store_id },
261
+ `${base}/carts/${params.id}/quote`,
262
+ { id: params.id },
331
263
  options
332
264
  );
333
265
  },
334
- checkout(params, options) {
335
- const store_id = params.store_id || apiConfig.storeId;
266
+ async checkout(params, options) {
267
+ await lifecycle.ensureVisitorSession();
336
268
  return apiConfig.httpClient.post(
337
- `${base(store_id)}/carts/${params.id}/checkout`,
269
+ `${base}/carts/${params.id}/checkout`,
338
270
  {
339
271
  id: params.id,
340
- store_id,
341
272
  payment_method_key: params.payment_method_key,
342
273
  confirmation_token_id: params.confirmation_token_id,
343
274
  return_url: params.return_url
@@ -347,115 +278,85 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
347
278
  }
348
279
  },
349
280
  order: {
350
- get(params, options) {
351
- const store_id = params.store_id || apiConfig.storeId;
281
+ async get(params, options) {
282
+ await lifecycle.ensureVisitorSession();
352
283
  return apiConfig.httpClient.get(
353
- `${base(store_id)}/orders/${params.id}`,
284
+ `${base}/orders/${params.id}`,
354
285
  options
355
286
  );
356
287
  },
357
- find(params, options) {
358
- const { store_id, ...queryParams } = params;
288
+ async find(params, options) {
289
+ await lifecycle.ensureVisitorSession();
359
290
  return apiConfig.httpClient.get(
360
- `${base(store_id)}/orders`,
361
- {
362
- ...options,
363
- params: queryParams
364
- }
291
+ `${base}/orders`,
292
+ { ...options, params }
365
293
  );
366
294
  },
367
- downloadDigitalAccess(params, options) {
368
- const store_id = params.store_id || apiConfig.storeId;
295
+ async downloadDigitalAccess(params, options) {
296
+ await lifecycle.ensureVisitorSession();
369
297
  return apiConfig.httpClient.post(
370
- `${base(store_id)}/orders/${params.order_id}/digital-access/${params.grant_id}/download`,
298
+ `${base}/orders/${params.order_id}/digital-access/${params.grant_id}/download`,
371
299
  {},
372
300
  options
373
301
  );
374
302
  },
375
- findDigitalAccess(params, options) {
376
- const { order_id, store_id, ...queryParams } = params;
303
+ async findDigitalAccess(params, options) {
304
+ await lifecycle.ensureVisitorSession();
305
+ const { order_id, ...queryParams } = params;
377
306
  return apiConfig.httpClient.get(
378
- `${base(store_id)}/orders/${order_id}/digital-access`,
307
+ `${base}/orders/${order_id}/digital-access`,
379
308
  { ...options, params: queryParams }
380
309
  );
381
310
  },
382
- getDigitalAccess(params, options) {
383
- const store_id = params.store_id || apiConfig.storeId;
311
+ async getDigitalAccess(params, options) {
312
+ await lifecycle.ensureVisitorSession();
384
313
  return apiConfig.httpClient.get(
385
- `${base(store_id)}/orders/${params.order_id}/digital-access/${params.grant_id}`,
314
+ `${base}/orders/${params.order_id}/digital-access/${params.grant_id}`,
386
315
  options
387
316
  );
388
317
  }
389
318
  },
390
319
  service: {
391
320
  get(params, options) {
392
- const store_id = params.store_id || apiConfig.storeId;
393
- let identifier;
394
- if (params.id) {
395
- identifier = params.id;
396
- } else if (params.slug) {
397
- identifier = `${store_id}:${apiConfig.locale}:${params.slug}`;
398
- } else {
399
- throw new Error("GetServiceParams requires id or slug");
400
- }
321
+ const identifier = params.id ?? params.slug;
322
+ if (!identifier) throw new Error("GetServiceParams requires id or slug");
401
323
  return apiConfig.httpClient.get(
402
- `${base(store_id)}/services/${identifier}`,
324
+ `${base}/services/${identifier}`,
403
325
  options
404
326
  );
405
327
  },
406
328
  find(params, options) {
407
- const { store_id, ...queryParams } = params;
408
329
  return apiConfig.httpClient.get(
409
- `${base(store_id)}/services`,
410
- {
411
- ...options,
412
- params: queryParams
413
- }
330
+ `${base}/services`,
331
+ { ...options, params }
414
332
  );
415
333
  },
416
334
  findProviders(params, options) {
417
- const { store_id, ...queryParams } = params;
418
335
  return apiConfig.httpClient.get(
419
- `${base(store_id)}/service-providers`,
420
- {
421
- ...options,
422
- params: queryParams
423
- }
336
+ `${base}/service-providers`,
337
+ { ...options, params }
424
338
  );
425
339
  },
426
340
  getAvailability(params, options) {
427
- const { store_id, ...queryParams } = params;
428
- const target_store_id = store_id || apiConfig.storeId;
429
341
  return apiConfig.httpClient.get(
430
- `${base(target_store_id)}/services/availability`,
431
- { ...options, params: queryParams }
342
+ `${base}/services/availability`,
343
+ { ...options, params }
432
344
  );
433
345
  }
434
346
  },
435
347
  provider: {
436
348
  get(params, options) {
437
- const store_id = params.store_id || apiConfig.storeId;
438
- let identifier;
439
- if (params.id) {
440
- identifier = params.id;
441
- } else if (params.slug) {
442
- identifier = `${store_id}:${apiConfig.locale}:${params.slug}`;
443
- } else {
444
- throw new Error("GetProviderParams requires id or slug");
445
- }
349
+ const identifier = params.id ?? params.slug;
350
+ if (!identifier) throw new Error("GetProviderParams requires id or slug");
446
351
  return apiConfig.httpClient.get(
447
- `${base(store_id)}/providers/${identifier}`,
352
+ `${base}/providers/${identifier}`,
448
353
  options
449
354
  );
450
355
  },
451
356
  find(params, options) {
452
- const { store_id, ...queryParams } = params;
453
357
  return apiConfig.httpClient.get(
454
- `${base(store_id)}/providers`,
455
- {
456
- ...options,
457
- params: queryParams
458
- }
358
+ `${base}/providers`,
359
+ { ...options, params }
459
360
  );
460
361
  }
461
362
  }
@@ -469,36 +370,23 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
469
370
  return submitIdentification("code", params, options);
470
371
  },
471
372
  async verify(params, options) {
472
- const store_id = apiConfig.storeId;
473
373
  const result = await apiConfig.httpClient.post(
474
- `${base(store_id)}/account/verify`,
475
- { store_id, challenge_id: params.challenge_id, code: params.code },
374
+ `${base}/account/verify`,
375
+ params,
476
376
  options
477
377
  );
478
- if (result?.token?.token) {
479
- const pending = pendingVerifications.get(params.challenge_id);
480
- const identifiedStore = pending?.store || await apiConfig.httpClient.get(base(store_id), options);
481
- updateContactSession(
482
- (prev) => prev ? {
483
- ...prev,
484
- access_token: result.token.token,
485
- contact: result.contact
486
- } : {
487
- access_token: result.token.token,
488
- contact: result.contact,
489
- store: identifiedStore,
490
- market: pending?.market || null
491
- }
492
- );
493
- pendingVerifications.delete(params.challenge_id);
378
+ if (result.token?.token) {
379
+ updateContactSession(() => ({
380
+ sessionToken: result.token.token,
381
+ contact: result.contact
382
+ }));
494
383
  }
495
384
  return result;
496
385
  },
497
386
  async logout(options) {
498
- const store_id = apiConfig.storeId;
499
387
  try {
500
388
  await apiConfig.httpClient.post(
501
- `${base(store_id)}/account/logout`,
389
+ `${base}/account/logout`,
502
390
  {},
503
391
  options
504
392
  );
@@ -508,110 +396,74 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
508
396
  },
509
397
  getMe(options) {
510
398
  return apiConfig.httpClient.get(
511
- `${base()}/account/me`,
399
+ `${base}/account/me`,
512
400
  options
513
401
  );
514
402
  }
515
403
  },
516
404
  contactList: {
517
405
  get(params, options) {
518
- const store_id = params.store_id || apiConfig.storeId;
519
406
  return apiConfig.httpClient.get(
520
- `${base(store_id)}/contact-lists/${params.id}`,
407
+ `${base}/contact-lists/${params.id}`,
521
408
  options
522
409
  );
523
410
  },
524
- find(params, options) {
525
- const { store_id, ...queryParams } = params || {};
411
+ find(params = {}, options) {
526
412
  return apiConfig.httpClient.get(
527
- `${base(store_id)}/contact-lists`,
528
- {
529
- ...options,
530
- params: queryParams
531
- }
413
+ `${base}/contact-lists`,
414
+ { ...options, params }
532
415
  );
533
416
  },
534
417
  plans: {
535
418
  find(params, options) {
536
- const { store_id, contact_list_id, ...queryParams } = params;
419
+ const { contact_list_id, ...queryParams } = params;
537
420
  return apiConfig.httpClient.get(
538
- `${base(store_id)}/contact-lists/${contact_list_id}/plans`,
421
+ `${base}/contact-lists/${contact_list_id}/plans`,
539
422
  { ...options, params: queryParams }
540
423
  );
541
424
  }
542
425
  },
543
426
  memberships: {
544
- find(params, options) {
545
- const { store_id, ...queryParams } = params || {};
546
- return apiConfig.httpClient.get(`${base(store_id)}/contact-lists/memberships`, {
427
+ async find(params = {}, options) {
428
+ await lifecycle.ensureVisitorSession();
429
+ return apiConfig.httpClient.get(`${base}/contact-lists/memberships`, {
547
430
  ...options,
548
- params: queryParams
431
+ params
549
432
  });
550
433
  }
551
434
  },
552
- subscribe(params, options) {
553
- const { store_id, id, ...payload } = params;
435
+ async subscribe(params, options) {
436
+ await lifecycle.ensureVisitorSession();
437
+ const { id, ...payload } = params;
554
438
  return apiConfig.httpClient.post(
555
- `${base(store_id)}/contact-lists/${id}/subscribe`,
439
+ `${base}/contact-lists/${id}/subscribe`,
556
440
  payload,
557
441
  options
558
442
  );
559
443
  },
560
- checkAccess(params, options) {
561
- const store_id = params.store_id || apiConfig.storeId;
444
+ async checkAccess(params, options) {
445
+ await lifecycle.ensureVisitorSession();
562
446
  return apiConfig.httpClient.get(
563
- `${base(store_id)}/contact-lists/${params.id}/access`,
564
- options
565
- );
566
- },
567
- checkContentAccess(params, options) {
568
- const { store_id, ...payload } = params;
569
- return apiConfig.httpClient.post(
570
- `${base(store_id)}/contact-lists/access`,
571
- payload,
447
+ `${base}/contact-lists/${params.id}/access`,
572
448
  options
573
449
  );
574
450
  },
575
- manage(token, options) {
451
+ async checkContentAccess(params, options) {
452
+ await lifecycle.ensureVisitorSession();
576
453
  return apiConfig.httpClient.post(
577
- `${base()}/contact-lists/manage`,
578
- { token },
579
- options
580
- );
581
- },
582
- unsubscribe(token, options) {
583
- const headers = { ...options?.headers };
584
- for (const name of Object.keys(headers)) {
585
- if (name.toLowerCase() === "content-type") delete headers[name];
586
- }
587
- return apiConfig.httpClient.post(
588
- `${base()}/contact-lists/unsubscribe`,
589
- new URLSearchParams({ "List-Unsubscribe": "One-Click" }),
590
- {
591
- ...options,
592
- params: { ...options?.params || {}, token },
593
- headers: {
594
- ...headers,
595
- "Content-Type": "application/x-www-form-urlencoded"
596
- }
597
- }
598
- );
599
- },
600
- confirm(token, options) {
601
- return apiConfig.httpClient.post(
602
- `${base()}/contact-lists/confirm`,
603
- { token },
454
+ `${base}/contact-lists/access`,
455
+ params,
604
456
  options
605
457
  );
606
458
  }
607
459
  }
608
460
  },
609
- action: createActionApi(apiConfig),
461
+ action: createActionApi(apiConfig, lifecycle),
610
462
  experiments: {
611
- use(params, options) {
612
- const store_id = params.store_id || apiConfig.storeId;
463
+ async use(params, options) {
464
+ await lifecycle.ensureVisitorSession();
613
465
  return apiConfig.httpClient.post(
614
- `${base(store_id)}/experiments/use`,
466
+ `${base}/experiments/use`,
615
467
  { key: params.key },
616
468
  options
617
469
  );
@@ -771,6 +623,15 @@ function requestError(name, message, details = {}) {
771
623
  function isRecord(value) {
772
624
  return typeof value === "object" && value !== null;
773
625
  }
626
+ function omitStorefrontRouting(value) {
627
+ if (!isRecord(value) || Array.isArray(value)) return value;
628
+ const prototype = Object.getPrototypeOf(value);
629
+ if (prototype !== Object.prototype && prototype !== null) return value;
630
+ const result = { ...value };
631
+ delete result.store_id;
632
+ delete result.market;
633
+ return result;
634
+ }
774
635
  function isTokenSet(value) {
775
636
  return isRecord(value) && typeof value.access_token === "string" && (value.refresh_token === void 0 || typeof value.refresh_token === "string") && (value.access_expires_at === void 0 || typeof value.access_expires_at === "number");
776
637
  }
@@ -846,10 +707,25 @@ function createHttpClient(cfg) {
846
707
  if (!retried && options?.transformRequest) {
847
708
  body = options.transformRequest(body);
848
709
  }
710
+ if (cfg.storefrontMode) {
711
+ body = omitStorefrontRouting(body);
712
+ }
713
+ const forcedHeaders = typeof cfg.forcedHeaders === "function" ? cfg.forcedHeaders() : cfg.forcedHeaders || {};
714
+ const callerHeaders = { ...options?.headers || {} };
715
+ const protectedHeaderNames = new Set(
716
+ Object.keys(forcedHeaders).map((name) => name.toLowerCase())
717
+ );
718
+ if (cfg.storefrontMode) protectedHeaderNames.add("authorization");
719
+ for (const name of Object.keys(callerHeaders)) {
720
+ if (protectedHeaderNames.has(name.toLowerCase())) {
721
+ delete callerHeaders[name];
722
+ }
723
+ }
849
724
  const headers = {
850
725
  Accept: "application/json",
851
726
  "Content-Type": "application/json",
852
- ...options?.headers || {}
727
+ ...callerHeaders,
728
+ ...forcedHeaders
853
729
  };
854
730
  let tokens = authStorage.getTokens();
855
731
  const nowSec = Date.now() / 1e3;
@@ -860,7 +736,8 @@ function createHttpClient(cfg) {
860
736
  if (tokens?.access_token) {
861
737
  headers["Authorization"] = `Bearer ${tokens.access_token}`;
862
738
  }
863
- const finalPath = options?.params ? path + buildQueryString(options.params) : path;
739
+ const requestParams = cfg.storefrontMode ? omitStorefrontRouting(options?.params) : options?.params;
740
+ const finalPath = requestParams ? path + buildQueryString(requestParams) : path;
864
741
  const fetchOptions = {
865
742
  method,
866
743
  headers,
@@ -891,8 +768,19 @@ function createHttpClient(cfg) {
891
768
  throw err;
892
769
  }
893
770
  if (res.status === 401 && !retried) {
894
- await ensureFreshToken();
895
- return request(method, path, body, options, true);
771
+ if (cfg.onUnauthorized) {
772
+ const recovered = await cfg.onUnauthorized({
773
+ hadAuthorization: Boolean(tokens?.access_token),
774
+ authorizationToken: tokens?.access_token || null,
775
+ path
776
+ });
777
+ if (recovered) {
778
+ return request(method, path, body, options, true);
779
+ }
780
+ } else {
781
+ await ensureFreshToken();
782
+ return request(method, path, body, options, true);
783
+ }
896
784
  }
897
785
  try {
898
786
  const contentLength = res.headers.get("content-length");
@@ -973,13 +861,6 @@ function createHttpClient(cfg) {
973
861
  }
974
862
 
975
863
  // src/api/support.ts
976
- function supportConversationQuery(params) {
977
- const qs = new URLSearchParams({ store_id: params.store_id });
978
- if (params.message_limit) qs.set("message_limit", String(params.message_limit));
979
- if (typeof params.after_created_at === "number") qs.set("after_created_at", String(params.after_created_at));
980
- if (params.after_id) qs.set("after_id", params.after_id);
981
- return qs.toString();
982
- }
983
864
  function storefrontSupportOptions(supportToken, options) {
984
865
  if (!/^[0-9a-f]{64}$/.test(supportToken)) {
985
866
  throw new Error("support_token must be a 64-character lowercase hexadecimal token");
@@ -996,32 +877,38 @@ function storefrontSupportOptions(supportToken, options) {
996
877
  }
997
878
  };
998
879
  }
999
- function createStorefrontSupportApi(config) {
880
+ function createStorefrontSupportApi(config, ensureVisitorSession) {
1000
881
  const { httpClient } = config;
1001
882
  return {
1002
883
  async startConversation(params = {}, opts) {
1003
- const storeId = config.storeId;
884
+ await ensureVisitorSession();
1004
885
  return httpClient.post(
1005
- `/v1/storefront/${storeId}/support/conversations`,
1006
- { ...params, store_id: storeId },
886
+ "/v1/storefront/support/conversations",
887
+ params,
1007
888
  opts
1008
889
  );
1009
890
  },
1010
891
  async sendMessage(params, opts) {
892
+ await ensureVisitorSession();
1011
893
  const { support_token, ...request } = params;
1012
- const storeId = config.storeId;
1013
894
  return httpClient.post(
1014
- `/v1/storefront/${storeId}/support/conversations/${request.conversation_id}/messages`,
1015
- { ...request, store_id: storeId },
895
+ `/v1/storefront/support/conversations/${request.conversation_id}/messages`,
896
+ request,
1016
897
  storefrontSupportOptions(support_token, opts)
1017
898
  );
1018
899
  },
1019
900
  async getConversation(params, opts) {
901
+ await ensureVisitorSession();
1020
902
  const { support_token, ...request } = params;
1021
- const storeId = config.storeId;
1022
- const qs = supportConversationQuery({ ...request, store_id: storeId });
903
+ const query = new URLSearchParams();
904
+ if (request.message_limit) query.set("message_limit", String(request.message_limit));
905
+ if (typeof request.after_created_at === "number") {
906
+ query.set("after_created_at", String(request.after_created_at));
907
+ }
908
+ if (request.after_id) query.set("after_id", request.after_id);
909
+ const suffix = query.size ? `?${query}` : "";
1023
910
  return httpClient.get(
1024
- `/v1/storefront/${storeId}/support/conversations/${request.conversation_id}?${qs}`,
911
+ `/v1/storefront/support/conversations/${request.conversation_id}${suffix}`,
1025
912
  storefrontSupportOptions(support_token, opts)
1026
913
  );
1027
914
  }
@@ -1479,280 +1366,6 @@ function getFirstAvailableFCId(variant, quantity = 1) {
1479
1366
  return inv?.location_id;
1480
1367
  }
1481
1368
 
1482
- // src/index.ts
1483
- function createUtilitySurface(apiConfig) {
1484
- return {
1485
- getImageUrl: (imageBlock, isBlock2 = true) => getImageUrl(imageBlock, isBlock2),
1486
- getBlockValue,
1487
- getBlockTextValue,
1488
- getBlockContentValue,
1489
- getBlockValues,
1490
- getBlockLabel,
1491
- getBlockObjectValues,
1492
- getBlockFromArray,
1493
- formatBlockValue,
1494
- prepareBlocksForSubmission,
1495
- extractBlockValues,
1496
- formatPrice: (prices) => formatPrice(prices, apiConfig.market),
1497
- getPriceAmount: (prices) => getPriceAmount(prices, apiConfig.market),
1498
- formatPayment,
1499
- formatMinor,
1500
- getCurrencySymbol,
1501
- getCurrencyName,
1502
- validatePhoneNumber,
1503
- tzGroups,
1504
- findTimeZone,
1505
- slugify,
1506
- humanize,
1507
- categorify,
1508
- formatDate,
1509
- getSvgContentForAstro,
1510
- fetchSvgContent,
1511
- injectSvgIntoElement,
1512
- isValidKey,
1513
- validateKey,
1514
- toKey,
1515
- nameToKey,
1516
- getAvailableStock,
1517
- getReservedStock,
1518
- hasStock,
1519
- getInventoryAt,
1520
- getFirstAvailableFCId
1521
- };
1522
- }
1523
- function defaultStorefrontSessionStorage() {
1524
- if (typeof window === "undefined") return null;
1525
- try {
1526
- return window.localStorage;
1527
- } catch {
1528
- return null;
1529
- }
1530
- }
1531
- function storefrontSessionStorageKey(baseUrl, storeId) {
1532
- const normalizedBaseUrl = baseUrl.trim().replace(/\/+$/, "").toLowerCase();
1533
- return `arky_contact_session:${encodeURIComponent(normalizedBaseUrl)}:${encodeURIComponent(storeId)}`;
1534
- }
1535
- function createStorefrontClient(config) {
1536
- const locale = config.locale || "en";
1537
- const initialMarket = config.market || "";
1538
- const listeners = /* @__PURE__ */ new Set();
1539
- let bareIdentifyPromise = null;
1540
- let identityTail = Promise.resolve();
1541
- const sessionStorage = config.sessionStorage || defaultStorefrontSessionStorage();
1542
- let memorySession = null;
1543
- function readContactSession() {
1544
- if (!sessionStorage) return memorySession;
1545
- try {
1546
- const raw = sessionStorage.getItem(
1547
- storefrontSessionStorageKey(config.baseUrl, config.storeId)
1548
- );
1549
- return raw ? JSON.parse(raw) : null;
1550
- } catch {
1551
- return memorySession;
1552
- }
1553
- }
1554
- function writeContactSession(session) {
1555
- memorySession = session;
1556
- if (!sessionStorage) return;
1557
- const key = storefrontSessionStorageKey(config.baseUrl, config.storeId);
1558
- try {
1559
- if (session) {
1560
- sessionStorage.setItem(key, JSON.stringify(session));
1561
- } else {
1562
- sessionStorage.removeItem(key);
1563
- }
1564
- } catch {
1565
- }
1566
- }
1567
- function toPublic(s) {
1568
- return s ? { contact: s.contact, store: s.store, market: s.market } : null;
1569
- }
1570
- function emit() {
1571
- const pub = toPublic(readContactSession());
1572
- for (const l of listeners) {
1573
- Promise.resolve().then(() => l(pub)).catch(() => {
1574
- });
1575
- }
1576
- }
1577
- const updateSession = (updater) => {
1578
- if (config.apiToken) return;
1579
- const prev = readContactSession();
1580
- const next = updater(prev);
1581
- writeContactSession(next);
1582
- emit();
1583
- };
1584
- const authStorage = config.apiToken ? {
1585
- getTokens: () => ({ access_token: config.apiToken }),
1586
- onTokensRefreshed: () => {
1587
- },
1588
- onForcedLogout: () => {
1589
- }
1590
- } : {
1591
- getTokens() {
1592
- const s = readContactSession();
1593
- return s ? { access_token: s.access_token } : null;
1594
- },
1595
- onTokensRefreshed() {
1596
- },
1597
- onForcedLogout() {
1598
- bareIdentifyPromise = null;
1599
- updateSession(() => null);
1600
- }
1601
- };
1602
- const httpClient = createHttpClient({
1603
- baseUrl: config.baseUrl,
1604
- storeId: config.storeId,
1605
- refreshPath: config.refreshPath,
1606
- navigate: config.navigate,
1607
- loginFallbackPath: config.loginFallbackPath,
1608
- authStorage
1609
- });
1610
- const apiConfig = {
1611
- httpClient,
1612
- storeId: config.storeId,
1613
- baseUrl: config.baseUrl,
1614
- market: initialMarket,
1615
- locale,
1616
- authStorage
1617
- };
1618
- const storefrontApi = createStorefrontApi(apiConfig, updateSession);
1619
- const contactApi = storefrontApi.crm.contact;
1620
- function identify(params) {
1621
- if (params?.market !== void 0) apiConfig.market = params.market;
1622
- const market = apiConfig.market;
1623
- const isBareCall = !params?.email && !params?.verify;
1624
- if (isBareCall && bareIdentifyPromise) return bareIdentifyPromise;
1625
- const run = async () => {
1626
- try {
1627
- const result = await (params?.verify ? contactApi.requestCode({
1628
- market,
1629
- email: params.email
1630
- }) : contactApi.identify({
1631
- market,
1632
- email: params?.email
1633
- }));
1634
- return {
1635
- contact: result.contact,
1636
- store: result.store,
1637
- market: result.market,
1638
- verification_challenge: result.verification_challenge
1639
- };
1640
- } catch (err) {
1641
- const e = err;
1642
- const status = e?.statusCode || e?.status || e?.response?.status;
1643
- if (isBareCall && status === 401) {
1644
- updateSession(() => null);
1645
- const result = await contactApi.identify({
1646
- market
1647
- });
1648
- return {
1649
- contact: result.contact,
1650
- store: result.store,
1651
- market: result.market,
1652
- verification_challenge: result.verification_challenge
1653
- };
1654
- }
1655
- throw err;
1656
- }
1657
- };
1658
- const promise = identityTail.then(run);
1659
- identityTail = promise.then(
1660
- () => void 0,
1661
- () => void 0
1662
- );
1663
- if (isBareCall) {
1664
- bareIdentifyPromise = promise;
1665
- void promise.then(
1666
- () => {
1667
- if (bareIdentifyPromise === promise) bareIdentifyPromise = null;
1668
- },
1669
- () => {
1670
- if (bareIdentifyPromise === promise) bareIdentifyPromise = null;
1671
- }
1672
- );
1673
- }
1674
- return promise;
1675
- }
1676
- async function verify(params) {
1677
- const result = await contactApi.verify(params);
1678
- bareIdentifyPromise = null;
1679
- return result;
1680
- }
1681
- async function logout() {
1682
- if (config.apiToken) return;
1683
- bareIdentifyPromise = null;
1684
- try {
1685
- await contactApi.logout();
1686
- } catch {
1687
- updateSession(() => null);
1688
- }
1689
- }
1690
- return {
1691
- identify,
1692
- verify,
1693
- logout,
1694
- me: () => contactApi.getMe(),
1695
- get session() {
1696
- if (config.apiToken) return null;
1697
- return toPublic(readContactSession());
1698
- },
1699
- get isAuthenticated() {
1700
- if (config.apiToken) return true;
1701
- const s = readContactSession();
1702
- return s !== null && !!s.access_token;
1703
- },
1704
- onAuthStateChanged(listener) {
1705
- listeners.add(listener);
1706
- const current = toPublic(readContactSession());
1707
- if (current) {
1708
- Promise.resolve().then(() => listener(current)).catch(() => {
1709
- });
1710
- }
1711
- return () => {
1712
- listeners.delete(listener);
1713
- };
1714
- },
1715
- store: storefrontApi.store,
1716
- cms: storefrontApi.cms,
1717
- eshop: storefrontApi.eshop,
1718
- crm: storefrontApi.crm,
1719
- action: storefrontApi.action,
1720
- experiments: storefrontApi.experiments,
1721
- support: createStorefrontSupportApi(apiConfig),
1722
- getStoreId: () => apiConfig.storeId,
1723
- setMarket: (key) => {
1724
- apiConfig.market = key;
1725
- bareIdentifyPromise = null;
1726
- },
1727
- getMarket: () => apiConfig.market,
1728
- setLocale: (l) => {
1729
- apiConfig.locale = l;
1730
- },
1731
- getLocale: () => apiConfig.locale,
1732
- utils: createUtilitySurface(apiConfig)
1733
- };
1734
- }
1735
- function createStorefront(config) {
1736
- const sessionStorage = config.sessionStorage || defaultStorefrontSessionStorage() || void 0;
1737
- const scopedConfig = {
1738
- ...config,
1739
- sessionStorage
1740
- };
1741
- const client = createStorefrontClient(scopedConfig);
1742
- Object.defineProperty(client, "forStore", {
1743
- enumerable: true,
1744
- configurable: false,
1745
- writable: false,
1746
- value: (storeId) => createStorefront({
1747
- ...scopedConfig,
1748
- storeId,
1749
- market: client.getMarket(),
1750
- locale: client.getLocale()
1751
- })
1752
- });
1753
- return client;
1754
- }
1755
-
1756
1369
  // src/payments/stripe.ts
1757
1370
  async function defaultStripeLoader(publishableKey, options) {
1758
1371
  const { loadStripe } = await import('@stripe/stripe-js');
@@ -2129,22 +1742,24 @@ function normalizeTimezoneGroups(groups) {
2129
1742
  function firstFiniteNumber(...values) {
2130
1743
  return values.find((value) => typeof value === "number" && Number.isFinite(value));
2131
1744
  }
2132
- function initializeStore(config) {
2133
- const client = createStorefront(config);
2134
- const formClients = /* @__PURE__ */ new Map([[client.getStoreId(), client]]);
1745
+ function initializeStoreCore(publishableKey, config, scopedClient) {
1746
+ const client = scopedClient || createStorefront(publishableKey, config);
2135
1747
  const session = atom(client.session);
1748
+ const setup = atom(null);
2136
1749
  const locale = atom(config.locale || client.getLocale());
2137
1750
  const market_key = atom(config.market || client.getMarket());
2138
- const market = computed(session, (value) => value?.market || null);
1751
+ const market = computed([setup, market_key], (setupValue, marketKey) => {
1752
+ const resolvedKey = marketKey || setupValue?.markets.default;
1753
+ return setupValue?.markets.available.find((candidate) => candidate.key === resolvedKey) || null;
1754
+ });
2139
1755
  const currency = computed(market, (value) => value?.currency || null);
2140
1756
  const allowed_payment_methods = computed(market, (value) => value?.payment_methods || []);
2141
- const payment_config = computed(session, (value) => {
2142
- const store = value?.store;
2143
- const methods = value?.market?.payment_methods || [];
1757
+ const payment_config = computed([setup, market], (setupValue, marketValue) => {
1758
+ const methods = marketValue?.payment_methods || [];
2144
1759
  const hasCreditCard = methods.some((method) => method.type === "credit_card");
2145
1760
  return {
2146
- provider: store?.payment || null,
2147
- enabled: hasCreditCard && !!store?.payment
1761
+ provider: setupValue?.payment || null,
1762
+ enabled: hasCreditCard && Boolean(setupValue?.readiness.payment)
2148
1763
  };
2149
1764
  });
2150
1765
  const cart = atom(null);
@@ -2240,24 +1855,17 @@ function initializeStore(config) {
2240
1855
  const service_form_blocks = computed(service_form_groups, (groups) => groups.flatMap((group) => group.blocks));
2241
1856
  client.onAuthStateChanged((value) => session.set(value));
2242
1857
  currency.subscribe((value) => service_state.setKey("currency", value));
2243
- session.subscribe((value) => {
2244
- const methods = value?.market?.payment_methods || [];
1858
+ market.subscribe((value) => {
1859
+ const methods = value?.payment_methods || [];
2245
1860
  if (methods.length && service_state.get().availablePaymentMethods.length === 0) {
2246
1861
  service_state.setKey("availablePaymentMethods", methods);
2247
1862
  }
2248
1863
  });
2249
1864
  function currentMarketKey() {
2250
- return market_key.get() || client.getMarket() || market.get()?.key || "";
1865
+ return market_key.get() || client.getMarket() || setup.get()?.markets.default || "";
2251
1866
  }
2252
1867
  function currentLocale() {
2253
- return locale.get() || client.getLocale() || "en";
2254
- }
2255
- function clientForStore(storeId) {
2256
- const existing = formClients.get(storeId);
2257
- if (existing) return existing;
2258
- const scoped = client.forStore(storeId);
2259
- formClients.set(storeId, scoped);
2260
- return scoped;
1868
+ return locale.get() || client.getLocale() || setup.get()?.languages.default || "en";
2261
1869
  }
2262
1870
  function currentStripePublishableKey() {
2263
1871
  const provider = payment_config.get()?.provider;
@@ -2287,10 +1895,24 @@ function initializeStore(config) {
2287
1895
  function destroyPaymentController() {
2288
1896
  setPaymentController(null);
2289
1897
  }
1898
+ async function loadSetup() {
1899
+ const current = setup.get();
1900
+ if (current) return current;
1901
+ const result = await client.getSetup();
1902
+ setup.set(result);
1903
+ if (!market_key.get() && result.markets.default) {
1904
+ market_key.set(result.markets.default);
1905
+ }
1906
+ if (!locale.get() && result.languages.default) {
1907
+ locale.set(result.languages.default);
1908
+ }
1909
+ return result;
1910
+ }
2290
1911
  async function mountStripePayment(target, options = {}) {
2291
- const publishableKey = options.publishableKey || currentStripePublishableKey();
2292
- if (!publishableKey) {
2293
- throw new Error("Stripe publishable key is required to mount card payment");
1912
+ await loadSetup();
1913
+ const publishableKey2 = currentStripePublishableKey();
1914
+ if (!publishableKey2) {
1915
+ throw new Error("Stripe card payment is not configured for this Store");
2294
1916
  }
2295
1917
  const hasExplicitAmount = options.amount !== void 0;
2296
1918
  const hasExplicitCurrency = Boolean(options.currency?.trim());
@@ -2306,8 +1928,8 @@ function initializeStore(config) {
2306
1928
  throw new Error("An explicit three-letter payment currency is required to mount card payment");
2307
1929
  }
2308
1930
  const controller = await createStripeConfirmationTokenController({
2309
- publishableKey,
2310
- connectedAccountId: options.connectedAccountId || currentStripeConnectedAccountId() || void 0,
1931
+ publishableKey: publishableKey2,
1932
+ connectedAccountId: currentStripeConnectedAccountId() || void 0,
2311
1933
  amount,
2312
1934
  currency: paymentCurrency,
2313
1935
  ...options.appearance ? { appearance: options.appearance } : {}
@@ -2319,15 +1941,11 @@ function initializeStore(config) {
2319
1941
  function updatePaymentController(input) {
2320
1942
  payment_controller.get()?.update(input);
2321
1943
  }
2322
- function marketForLocale(value) {
2323
- return config.marketForLocale?.(value) || null;
2324
- }
2325
1944
  async function ensureSession() {
2326
1945
  const current = session.get();
2327
- const marketKey = currentMarketKey();
2328
- if (current && (!marketKey || current.market?.key === marketKey)) return current;
1946
+ if (client.isAuthenticated) return current;
2329
1947
  if (!sessionRequest) {
2330
- sessionRequest = identify({ market: marketKey }).finally(() => {
1948
+ sessionRequest = identify().finally(() => {
2331
1949
  sessionRequest = null;
2332
1950
  });
2333
1951
  }
@@ -2340,9 +1958,7 @@ function initializeStore(config) {
2340
1958
  market: params.market || currentMarketKey()
2341
1959
  });
2342
1960
  session.set({
2343
- contact: result.contact,
2344
- store: result.store,
2345
- market: result.market
1961
+ contact: result.contact
2346
1962
  });
2347
1963
  return result;
2348
1964
  }
@@ -2354,21 +1970,24 @@ function initializeStore(config) {
2354
1970
  return identify({ email: normalizedEmail });
2355
1971
  }
2356
1972
  function setMarket(key) {
2357
- market_key.set(key);
2358
- client.setMarket(key);
1973
+ const next = key.trim();
1974
+ const current = currentMarketKey();
1975
+ if (next && current && next !== current && (cart.get()?.item_count || item_count.get()) > 0) {
1976
+ throw Object.assign(
1977
+ new Error("Market cannot change while the cart contains items"),
1978
+ { code: "CART_MARKET_LOCKED" }
1979
+ );
1980
+ }
1981
+ market_key.set(next);
1982
+ client.setMarket(next);
2359
1983
  }
2360
- function setLocale(value, options = {}) {
1984
+ function setLocale(value) {
2361
1985
  locale.set(value);
2362
1986
  client.setLocale(value);
2363
- const nextMarket = options.market || marketForLocale(value);
2364
- if (nextMarket) setMarket(nextMarket);
2365
1987
  }
2366
1988
  function setContext(context) {
2367
- if (context.locale) {
2368
- setLocale(context.locale, { market: context.market });
2369
- return;
2370
- }
2371
- if (context.market) setMarket(context.market);
1989
+ if (context.market !== void 0) setMarket(context.market);
1990
+ if (context.locale !== void 0) setLocale(context.locale);
2372
1991
  }
2373
1992
  async function ensureCart() {
2374
1993
  if (cartRequest) return cartRequest;
@@ -2377,9 +1996,7 @@ function initializeStore(config) {
2377
1996
  const refreshRevision = cartWriteRevision;
2378
1997
  cartRequest = (async () => {
2379
1998
  await ensureSession();
2380
- const response = await client.eshop.cart.current({
2381
- market: currentMarketKey()
2382
- });
1999
+ const response = await client.eshop.cart.current();
2383
2000
  await applyCartResponse(response, { ifRevision: refreshRevision });
2384
2001
  return response;
2385
2002
  })();
@@ -2471,7 +2088,6 @@ function initializeStore(config) {
2471
2088
  const current = cart.get() || await ensureCart();
2472
2089
  const response = await client.eshop.cart.update({
2473
2090
  id: current.id,
2474
- market: currentMarketKey(),
2475
2091
  items: checkoutItems(input),
2476
2092
  shipping_address: input.shipping_address,
2477
2093
  billing_address: input.billing_address,
@@ -2887,7 +2503,7 @@ function initializeStore(config) {
2887
2503
  async initialize() {
2888
2504
  service_state.setKey("tzGroups", normalizeTimezoneGroups(client.utils.tzGroups));
2889
2505
  await ensureCart();
2890
- const methods = session.get()?.market?.payment_methods || [];
2506
+ const methods = market.get()?.payment_methods || [];
2891
2507
  if (methods.length) service_state.setKey("availablePaymentMethods", methods);
2892
2508
  },
2893
2509
  setTimezone(tz) {
@@ -2936,7 +2552,9 @@ function initializeStore(config) {
2936
2552
  ...service_state.get(),
2937
2553
  service: fullService,
2938
2554
  serviceProviders,
2939
- providers: providerResults.filter((provider) => provider !== null),
2555
+ providers: providerResults.filter(
2556
+ (provider) => provider !== null
2557
+ ),
2940
2558
  selectedProviderId: null,
2941
2559
  availability: null,
2942
2560
  selectedDate: null,
@@ -3150,7 +2768,7 @@ function initializeStore(config) {
3150
2768
  });
3151
2769
  service_state.setKey("cartId", cart.get()?.id || null);
3152
2770
  service_state.setKey("quote", response);
3153
- const methods = response?.payment_methods || session.get()?.market?.payment_methods || [];
2771
+ const methods = response?.payment_methods || market.get()?.payment_methods || [];
3154
2772
  if (methods.length) service_state.setKey("availablePaymentMethods", methods);
3155
2773
  return response;
3156
2774
  } catch (error) {
@@ -3242,20 +2860,17 @@ function initializeStore(config) {
3242
2860
  }
3243
2861
  }
3244
2862
  function formCacheKey(params) {
3245
- const storeId = params.store_id || client.getStoreId();
3246
2863
  const identifier = params.id ? `id:${params.id}` : params.key ? `key:${params.key}` : "missing";
3247
- return `${storeId}:${identifier}`;
2864
+ return identifier;
3248
2865
  }
3249
2866
  async function loadForm(params, options) {
3250
2867
  cms_state.setKey("loading", true);
3251
2868
  cms_state.setKey("error", null);
3252
2869
  try {
3253
- const storeId = params.store_id || client.getStoreId();
3254
- const formClient = clientForStore(storeId);
3255
- const form = await formClient.cms.form.get({ ...params, store_id: storeId }, options);
2870
+ const form = await client.cms.form.get(params, options);
3256
2871
  const forms = { ...cms_state.get().forms };
3257
- forms[formCacheKey({ id: form.id, store_id: storeId })] = form;
3258
- forms[formCacheKey({ key: form.key, store_id: storeId })] = form;
2872
+ forms[formCacheKey({ id: form.id })] = form;
2873
+ forms[formCacheKey({ key: form.key })] = form;
3259
2874
  cms_state.setKey("forms", forms);
3260
2875
  return form;
3261
2876
  } catch (error) {
@@ -3265,26 +2880,14 @@ function initializeStore(config) {
3265
2880
  cms_state.setKey("loading", false);
3266
2881
  }
3267
2882
  }
3268
- async function ensureFormClient(storeId) {
3269
- const formClient = clientForStore(storeId);
3270
- const marketKey = currentMarketKey();
3271
- if (formClient === client) {
3272
- await ensureSession();
3273
- } else if (!formClient.session || marketKey && formClient.session.market?.key !== marketKey) {
3274
- await formClient.identify({ market: marketKey });
3275
- }
3276
- return formClient;
3277
- }
3278
2883
  async function submitForm(params, options) {
3279
- const storeId = params.store_id || client.getStoreId();
3280
- const formClient = await ensureFormClient(storeId);
3281
- return formClient.cms.form.submit({ ...params, store_id: storeId }, options);
2884
+ await ensureSession();
2885
+ return client.cms.form.submit(params, options);
3282
2886
  }
3283
2887
  async function submitFormByKey(params, options) {
3284
- const storeId = params.store_id || client.getStoreId();
3285
- const form = await loadForm({ key: params.key, store_id: storeId }, options);
2888
+ const form = await loadForm({ key: params.key }, options);
3286
2889
  const entry = createFormEntryFromValues(form, params.values);
3287
- return submitForm({ store_id: storeId, form_id: form.id, fields: entry.fields }, options);
2890
+ return submitForm({ form_id: form.id, fields: entry.fields }, options);
3288
2891
  }
3289
2892
  async function loadProducts(params = {}, options) {
3290
2893
  eshop_state.setKey("loading_products", true);
@@ -3446,6 +3049,7 @@ function initializeStore(config) {
3446
3049
  return {
3447
3050
  client,
3448
3051
  session,
3052
+ setup,
3449
3053
  market,
3450
3054
  market_key,
3451
3055
  locale,
@@ -3464,7 +3068,6 @@ function initializeStore(config) {
3464
3068
  setMarket,
3465
3069
  setLocale,
3466
3070
  setContext,
3467
- getStoreId: client.getStoreId,
3468
3071
  getMarket: currentMarketKey,
3469
3072
  getLocale: currentLocale,
3470
3073
  cms: {
@@ -3508,31 +3111,400 @@ function initializeStore(config) {
3508
3111
  use: useExperiment
3509
3112
  },
3510
3113
  support: client.support,
3511
- store: client.store,
3114
+ store: {
3115
+ ...client.store,
3116
+ setup,
3117
+ load: loadSetup
3118
+ },
3512
3119
  utils: client.utils
3513
3120
  };
3514
3121
  }
3515
- function initialize(config) {
3516
- const stores = /* @__PURE__ */ new Map();
3517
- const createScope = (scopeConfig) => {
3518
- const existing = stores.get(scopeConfig.storeId);
3519
- if (existing) return existing;
3520
- const store = initializeStore(scopeConfig);
3521
- stores.set(scopeConfig.storeId, store);
3522
- Object.defineProperty(store, "forStore", {
3523
- enumerable: true,
3524
- configurable: false,
3525
- writable: false,
3526
- value: (storeId) => createScope({
3527
- ...config,
3528
- storeId,
3529
- market: store.getMarket(),
3530
- locale: store.getLocale()
3531
- })
3122
+ function initializeStore(publishableKey, config, scopedClient) {
3123
+ const store = initializeStoreCore(publishableKey, config, scopedClient);
3124
+ return Object.assign(store, {
3125
+ withContext(context) {
3126
+ return initializeStore(
3127
+ publishableKey,
3128
+ {
3129
+ ...config,
3130
+ locale: context.locale ?? store.getLocale(),
3131
+ market: context.market ?? store.getMarket()
3132
+ },
3133
+ store.client.withContext(context)
3134
+ );
3135
+ }
3136
+ });
3137
+ }
3138
+ function initialize(publishableKey, options = {}) {
3139
+ return initializeStore(publishableKey, options);
3140
+ }
3141
+
3142
+ // src/index.ts
3143
+ function createUtilitySurface(apiConfig) {
3144
+ return {
3145
+ getImageUrl: (imageBlock, isBlock2 = true) => getImageUrl(imageBlock, isBlock2),
3146
+ getBlockValue,
3147
+ getBlockTextValue,
3148
+ getBlockContentValue,
3149
+ getBlockValues,
3150
+ getBlockLabel,
3151
+ getBlockObjectValues,
3152
+ getBlockFromArray,
3153
+ formatBlockValue,
3154
+ prepareBlocksForSubmission,
3155
+ extractBlockValues,
3156
+ formatPrice: (prices) => formatPrice(prices, apiConfig.market),
3157
+ getPriceAmount: (prices) => getPriceAmount(prices, apiConfig.market),
3158
+ formatPayment,
3159
+ formatMinor,
3160
+ getCurrencySymbol,
3161
+ getCurrencyName,
3162
+ validatePhoneNumber,
3163
+ tzGroups,
3164
+ findTimeZone,
3165
+ slugify,
3166
+ humanize,
3167
+ categorify,
3168
+ formatDate,
3169
+ getSvgContentForAstro,
3170
+ fetchSvgContent,
3171
+ injectSvgIntoElement,
3172
+ isValidKey,
3173
+ validateKey,
3174
+ toKey,
3175
+ nameToKey,
3176
+ getAvailableStock,
3177
+ getReservedStock,
3178
+ hasStock,
3179
+ getInventoryAt,
3180
+ getFirstAvailableFCId
3181
+ };
3182
+ }
3183
+ var DEFAULT_STOREFRONT_API_URL = "https://api.arky.io";
3184
+ var storefrontScopeSequence = 0;
3185
+ function defaultStorefrontSessionStorage() {
3186
+ if (typeof window === "undefined") return null;
3187
+ try {
3188
+ return window.localStorage;
3189
+ } catch {
3190
+ return null;
3191
+ }
3192
+ }
3193
+ function normalizeStorefrontApiUrl(value) {
3194
+ const input = value?.trim() || DEFAULT_STOREFRONT_API_URL;
3195
+ let parsed;
3196
+ try {
3197
+ parsed = new URL(input);
3198
+ } catch {
3199
+ throw new Error("Storefront apiUrl must be a valid HTTP(S) URL");
3200
+ }
3201
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
3202
+ throw new Error("Storefront apiUrl must use HTTP or HTTPS");
3203
+ }
3204
+ return input.replace(/\/+$/, "");
3205
+ }
3206
+ function validatePublishableKey(publishableKey) {
3207
+ if (typeof publishableKey !== "string") {
3208
+ throw new Error(
3209
+ "A valid Arky publishable key is required (arky_pk_ followed by 43 URL-safe characters)"
3210
+ );
3211
+ }
3212
+ const key = publishableKey.trim();
3213
+ if (!/^arky_pk_[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/.test(key)) {
3214
+ throw new Error(
3215
+ "A valid Arky publishable key is required (arky_pk_ followed by 43 URL-safe characters)"
3216
+ );
3217
+ }
3218
+ return key;
3219
+ }
3220
+ function publishableKeyFingerprint(publishableKey) {
3221
+ let hashA = 2166136261;
3222
+ let hashB = 2654435769;
3223
+ for (let index = 0; index < publishableKey.length; index += 1) {
3224
+ const code = publishableKey.charCodeAt(index);
3225
+ hashA = Math.imul(hashA ^ code, 16777619);
3226
+ hashB = Math.imul(hashB ^ code, 2246822507);
3227
+ }
3228
+ return `${(hashA >>> 0).toString(36)}${(hashB >>> 0).toString(36)}`;
3229
+ }
3230
+ function storefrontSessionStorageKey(apiUrl, publishableKey) {
3231
+ return `arky_visitor_session:${encodeURIComponent(apiUrl.toLowerCase())}:${publishableKeyFingerprint(publishableKey)}`;
3232
+ }
3233
+ function isVisitorSessionToken(value) {
3234
+ return Boolean(value && /^arky_vst_[0-9a-f]{64}$/.test(value));
3235
+ }
3236
+ function createStorefrontClientCore(publishableKeyInput, options = {}, isolatedSession = false) {
3237
+ const publishableKey = validatePublishableKey(publishableKeyInput);
3238
+ const apiUrl = normalizeStorefrontApiUrl(options.apiUrl);
3239
+ let locale = options.locale?.trim() || "";
3240
+ let market = options.market?.trim() || "";
3241
+ const listeners = /* @__PURE__ */ new Set();
3242
+ let identifyPromise = null;
3243
+ let identityTail = Promise.resolve();
3244
+ let setupPromise = null;
3245
+ let setupValue = null;
3246
+ const explicitSessionStorage = options.sessionStorage;
3247
+ const sessionStorage = isolatedSession ? explicitSessionStorage || null : explicitSessionStorage || defaultStorefrontSessionStorage();
3248
+ const canCreateVisitorSession = typeof window !== "undefined" || Boolean(explicitSessionStorage);
3249
+ const storageKey = `${storefrontSessionStorageKey(apiUrl, publishableKey)}${isolatedSession ? `:scope:${++storefrontScopeSequence}` : ""}`;
3250
+ let memorySession = null;
3251
+ let memorySessionToken = null;
3252
+ function readSessionToken() {
3253
+ if (!sessionStorage) return memorySessionToken;
3254
+ try {
3255
+ const stored = sessionStorage.getItem(storageKey);
3256
+ return isVisitorSessionToken(stored) ? stored : memorySessionToken;
3257
+ } catch {
3258
+ return memorySessionToken;
3259
+ }
3260
+ }
3261
+ function writeContactSession(session) {
3262
+ memorySession = session;
3263
+ memorySessionToken = session?.sessionToken || null;
3264
+ if (!sessionStorage) return;
3265
+ try {
3266
+ if (session) {
3267
+ sessionStorage.setItem(storageKey, session.sessionToken);
3268
+ } else {
3269
+ sessionStorage.removeItem(storageKey);
3270
+ }
3271
+ } catch {
3272
+ }
3273
+ }
3274
+ function toPublic(s) {
3275
+ return s ? { contact: s.contact } : null;
3276
+ }
3277
+ function emit() {
3278
+ const pub = toPublic(memorySession);
3279
+ for (const l of listeners) {
3280
+ Promise.resolve().then(() => l(pub)).catch(() => {
3281
+ });
3282
+ }
3283
+ }
3284
+ const updateSession = (updater) => {
3285
+ const next = updater(memorySession);
3286
+ writeContactSession(next);
3287
+ emit();
3288
+ };
3289
+ const authStorage = {
3290
+ getTokens() {
3291
+ const sessionToken = readSessionToken();
3292
+ return sessionToken ? { access_token: sessionToken } : null;
3293
+ },
3294
+ onTokensRefreshed() {
3295
+ },
3296
+ onForcedLogout() {
3297
+ identifyPromise = null;
3298
+ updateSession(() => null);
3299
+ }
3300
+ };
3301
+ let recoverUnauthorized = async () => false;
3302
+ let visitorRecoveryPromise = null;
3303
+ const httpClient = createHttpClient({
3304
+ baseUrl: apiUrl,
3305
+ authStorage,
3306
+ storefrontMode: true,
3307
+ forcedHeaders: () => ({
3308
+ "X-Arky-Publishable-Key": publishableKey,
3309
+ ...locale ? { "X-Arky-Locale": locale } : {},
3310
+ ...market ? { "X-Arky-Market": market } : {}
3311
+ }),
3312
+ onUnauthorized: ({ authorizationToken, path }) => recoverUnauthorized(authorizationToken, path)
3313
+ });
3314
+ const apiConfig = {
3315
+ httpClient,
3316
+ apiUrl,
3317
+ publishableKey,
3318
+ market,
3319
+ locale,
3320
+ authStorage
3321
+ };
3322
+ function requireVisitorSessionCapability() {
3323
+ if (!canCreateVisitorSession) {
3324
+ throw new Error(
3325
+ "Stateful storefront operations during SSR require an explicit request-local sessionStorage adapter"
3326
+ );
3327
+ }
3328
+ }
3329
+ async function getSetup(requestOptions) {
3330
+ if (setupValue) return setupValue;
3331
+ if (setupPromise) return setupPromise;
3332
+ setupPromise = httpClient.get(
3333
+ "/v1/storefront",
3334
+ requestOptions
3335
+ ).then((setup) => {
3336
+ setupValue = setup;
3337
+ return setup;
3338
+ }).finally(() => {
3339
+ setupPromise = null;
3340
+ });
3341
+ return setupPromise;
3342
+ }
3343
+ async function ensureVisitorSession() {
3344
+ if (readSessionToken()) return;
3345
+ requireVisitorSessionCapability();
3346
+ await identify();
3347
+ }
3348
+ const storefrontApi = createStorefrontApi(apiConfig, updateSession, {
3349
+ ensureVisitorSession,
3350
+ getSetup
3351
+ });
3352
+ const contactApi = storefrontApi.crm.contact;
3353
+ function identify(params) {
3354
+ requireVisitorSessionCapability();
3355
+ if (params?.market !== void 0) setMarket(params.market);
3356
+ const isBareCall = !params?.email && !params?.verify;
3357
+ if (isBareCall && identifyPromise) return identifyPromise;
3358
+ const run = async () => {
3359
+ const result = await (params?.verify ? contactApi.requestCode({ email: params.email }) : contactApi.identify({ email: params?.email }));
3360
+ return {
3361
+ contact: result.contact,
3362
+ verification_challenge: result.verification_challenge
3363
+ };
3364
+ };
3365
+ const promise = identityTail.then(run);
3366
+ identityTail = promise.then(
3367
+ () => void 0,
3368
+ () => void 0
3369
+ );
3370
+ if (isBareCall) {
3371
+ identifyPromise = promise;
3372
+ void promise.then(
3373
+ () => {
3374
+ if (identifyPromise === promise) identifyPromise = null;
3375
+ },
3376
+ () => {
3377
+ if (identifyPromise === promise) identifyPromise = null;
3378
+ }
3379
+ );
3380
+ }
3381
+ return promise;
3382
+ }
3383
+ async function verify(params) {
3384
+ requireVisitorSessionCapability();
3385
+ const result = await contactApi.verify(params);
3386
+ identifyPromise = null;
3387
+ return { contact: result.contact };
3388
+ }
3389
+ async function me() {
3390
+ await ensureVisitorSession();
3391
+ return contactApi.getMe();
3392
+ }
3393
+ async function logout() {
3394
+ identifyPromise = null;
3395
+ if (!readSessionToken()) {
3396
+ updateSession(() => null);
3397
+ return;
3398
+ }
3399
+ try {
3400
+ await contactApi.logout();
3401
+ } catch {
3402
+ updateSession(() => null);
3403
+ }
3404
+ }
3405
+ function setMarket(value) {
3406
+ market = value.trim();
3407
+ apiConfig.market = market;
3408
+ identifyPromise = null;
3409
+ }
3410
+ function setLocale(value) {
3411
+ locale = value.trim();
3412
+ apiConfig.locale = locale;
3413
+ }
3414
+ function setContext(context) {
3415
+ if (context.locale !== void 0) setLocale(context.locale);
3416
+ if (context.market !== void 0) setMarket(context.market);
3417
+ }
3418
+ recoverUnauthorized = async (authorizationToken, path) => {
3419
+ if (!authorizationToken) return false;
3420
+ const currentToken = readSessionToken();
3421
+ if (currentToken !== authorizationToken) {
3422
+ if (currentToken) return true;
3423
+ if (!visitorRecoveryPromise) return false;
3424
+ await visitorRecoveryPromise;
3425
+ return Boolean(readSessionToken());
3426
+ }
3427
+ updateSession(() => null);
3428
+ if (/\/account\/(identify|code)$/.test(path)) return true;
3429
+ const recovery = ensureVisitorSession();
3430
+ const trackedRecovery = recovery.finally(() => {
3431
+ if (visitorRecoveryPromise === trackedRecovery) {
3432
+ visitorRecoveryPromise = null;
3433
+ }
3532
3434
  });
3533
- return store;
3435
+ visitorRecoveryPromise = trackedRecovery;
3436
+ await trackedRecovery;
3437
+ return true;
3438
+ };
3439
+ return {
3440
+ identify,
3441
+ verify,
3442
+ logout,
3443
+ me,
3444
+ get session() {
3445
+ return toPublic(memorySession);
3446
+ },
3447
+ get isAuthenticated() {
3448
+ return Boolean(readSessionToken());
3449
+ },
3450
+ onAuthStateChanged(listener) {
3451
+ listeners.add(listener);
3452
+ const current = toPublic(memorySession);
3453
+ if (current) {
3454
+ Promise.resolve().then(() => listener(current)).catch(() => {
3455
+ });
3456
+ }
3457
+ return () => {
3458
+ listeners.delete(listener);
3459
+ };
3460
+ },
3461
+ store: storefrontApi.store,
3462
+ cms: storefrontApi.cms,
3463
+ eshop: storefrontApi.eshop,
3464
+ crm: {
3465
+ ...storefrontApi.crm,
3466
+ contact: {
3467
+ identify: (params) => identify(params),
3468
+ requestCode: (params) => identify({ ...params, verify: true }),
3469
+ verify,
3470
+ logout,
3471
+ getMe: me
3472
+ }
3473
+ },
3474
+ action: storefrontApi.action,
3475
+ experiments: storefrontApi.experiments,
3476
+ support: createStorefrontSupportApi(apiConfig, ensureVisitorSession),
3477
+ getSetup,
3478
+ setContext,
3479
+ setMarket,
3480
+ getMarket: () => market,
3481
+ setLocale,
3482
+ getLocale: () => locale,
3483
+ utils: createUtilitySurface(apiConfig)
3534
3484
  };
3535
- return createScope(config);
3485
+ }
3486
+ function createStorefrontClient(publishableKey, options = {}, isolatedSession = false) {
3487
+ const client = createStorefrontClientCore(
3488
+ publishableKey,
3489
+ options,
3490
+ isolatedSession
3491
+ );
3492
+ return Object.assign(client, {
3493
+ withContext(context) {
3494
+ return createStorefrontClient(
3495
+ publishableKey,
3496
+ {
3497
+ ...options,
3498
+ locale: context.locale ?? client.getLocale(),
3499
+ market: context.market ?? client.getMarket()
3500
+ },
3501
+ true
3502
+ );
3503
+ }
3504
+ });
3505
+ }
3506
+ function createStorefront(publishableKey, options = {}) {
3507
+ return createStorefrontClient(publishableKey, options);
3536
3508
  }
3537
3509
 
3538
3510
  export { COMMON_ACTION_KEYS, buildFormFields, createCartController, createFormEntry, createFormEntryFromValues, createStorefront, createStripeConfirmationTokenController, getBlockContentValue, initialize };