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