arky-sdk 0.9.20 → 0.11.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,106 @@ 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();
213
+ const queryParams = Object.fromEntries(
214
+ Object.entries(
215
+ options?.params || {}
216
+ ).filter(
217
+ ([name]) => !["token", "cart_token"].includes(name.toLowerCase())
218
+ )
219
+ );
220
+ const headers = Object.fromEntries(
221
+ Object.entries(options?.headers || {}).filter(
222
+ ([name]) => name.toLowerCase() !== "x-arky-cart-token"
223
+ )
224
+ );
275
225
  return apiConfig.httpClient.get(
276
- `${base(store_id)}/carts/${params.id}`,
226
+ `${base}/carts/${params.id}`,
277
227
  {
278
228
  ...options,
279
- params: params.token ? { token: params.token } : options?.params
229
+ headers: {
230
+ ...headers,
231
+ ...params.token ? { "X-Arky-Cart-Token": params.token } : {}
232
+ },
233
+ params: Object.keys(queryParams).length > 0 ? queryParams : void 0
280
234
  }
281
235
  );
282
236
  },
283
- update(params, options) {
284
- const { store_id, items, ...payload } = params;
285
- const target = store_id || apiConfig.storeId;
237
+ async update(params, options) {
238
+ await lifecycle.ensureVisitorSession();
239
+ const { items, ...payload } = params;
286
240
  return apiConfig.httpClient.put(
287
- `${base(target)}/carts/${params.id}`,
241
+ `${base}/carts/${params.id}`,
288
242
  {
289
243
  ...payload,
290
- store_id: target,
291
244
  ...items ? { items: sanitizePublicCheckoutItems(items) } : {}
292
245
  },
293
246
  options
294
247
  );
295
248
  },
296
- addItem(params, options) {
297
- const { store_id, item, ...payload } = params;
298
- const target = store_id || apiConfig.storeId;
249
+ async addItem(params, options) {
250
+ await lifecycle.ensureVisitorSession();
251
+ const { item, ...payload } = params;
299
252
  return apiConfig.httpClient.post(
300
- `${base(target)}/carts/${params.id}/items`,
301
- {
302
- ...payload,
303
- store_id: target,
304
- item: sanitizePublicCheckoutItems([item])[0]
305
- },
253
+ `${base}/carts/${params.id}/items`,
254
+ { ...payload, item: sanitizePublicCheckoutItems([item])[0] },
306
255
  options
307
256
  );
308
257
  },
309
- removeItem(params, options) {
310
- const { store_id, ...payload } = params;
311
- const target = store_id || apiConfig.storeId;
258
+ async removeItem(params, options) {
259
+ await lifecycle.ensureVisitorSession();
312
260
  return apiConfig.httpClient.post(
313
- `${base(target)}/carts/${params.id}/items/remove`,
314
- { ...payload, store_id: target },
261
+ `${base}/carts/${params.id}/items/remove`,
262
+ params,
315
263
  options
316
264
  );
317
265
  },
318
- clear(params, options) {
319
- const store_id = params.store_id || apiConfig.storeId;
266
+ async clear(params, options) {
267
+ await lifecycle.ensureVisitorSession();
320
268
  return apiConfig.httpClient.post(
321
- `${base(store_id)}/carts/${params.id}/clear`,
322
- { id: params.id, store_id },
269
+ `${base}/carts/${params.id}/clear`,
270
+ { id: params.id },
323
271
  options
324
272
  );
325
273
  },
326
- quote(params, options) {
327
- const store_id = params.store_id || apiConfig.storeId;
274
+ async quote(params, options) {
275
+ await lifecycle.ensureVisitorSession();
328
276
  return apiConfig.httpClient.post(
329
- `${base(store_id)}/carts/${params.id}/quote`,
330
- { id: params.id, store_id },
277
+ `${base}/carts/${params.id}/quote`,
278
+ { id: params.id },
331
279
  options
332
280
  );
333
281
  },
334
- checkout(params, options) {
335
- const store_id = params.store_id || apiConfig.storeId;
282
+ async checkout(params, options) {
283
+ await lifecycle.ensureVisitorSession();
336
284
  return apiConfig.httpClient.post(
337
- `${base(store_id)}/carts/${params.id}/checkout`,
285
+ `${base}/carts/${params.id}/checkout`,
338
286
  {
339
287
  id: params.id,
340
- store_id,
341
288
  payment_method_key: params.payment_method_key,
342
289
  confirmation_token_id: params.confirmation_token_id,
343
290
  return_url: params.return_url
@@ -347,115 +294,85 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
347
294
  }
348
295
  },
349
296
  order: {
350
- get(params, options) {
351
- const store_id = params.store_id || apiConfig.storeId;
297
+ async get(params, options) {
298
+ await lifecycle.ensureVisitorSession();
352
299
  return apiConfig.httpClient.get(
353
- `${base(store_id)}/orders/${params.id}`,
300
+ `${base}/orders/${params.id}`,
354
301
  options
355
302
  );
356
303
  },
357
- find(params, options) {
358
- const { store_id, ...queryParams } = params;
304
+ async find(params, options) {
305
+ await lifecycle.ensureVisitorSession();
359
306
  return apiConfig.httpClient.get(
360
- `${base(store_id)}/orders`,
361
- {
362
- ...options,
363
- params: queryParams
364
- }
307
+ `${base}/orders`,
308
+ { ...options, params }
365
309
  );
366
310
  },
367
- downloadDigitalAccess(params, options) {
368
- const store_id = params.store_id || apiConfig.storeId;
311
+ async downloadDigitalAccess(params, options) {
312
+ await lifecycle.ensureVisitorSession();
369
313
  return apiConfig.httpClient.post(
370
- `${base(store_id)}/orders/${params.order_id}/digital-access/${params.grant_id}/download`,
314
+ `${base}/orders/${params.order_id}/digital-access/${params.grant_id}/download`,
371
315
  {},
372
316
  options
373
317
  );
374
318
  },
375
- findDigitalAccess(params, options) {
376
- const { order_id, store_id, ...queryParams } = params;
319
+ async findDigitalAccess(params, options) {
320
+ await lifecycle.ensureVisitorSession();
321
+ const { order_id, ...queryParams } = params;
377
322
  return apiConfig.httpClient.get(
378
- `${base(store_id)}/orders/${order_id}/digital-access`,
323
+ `${base}/orders/${order_id}/digital-access`,
379
324
  { ...options, params: queryParams }
380
325
  );
381
326
  },
382
- getDigitalAccess(params, options) {
383
- const store_id = params.store_id || apiConfig.storeId;
327
+ async getDigitalAccess(params, options) {
328
+ await lifecycle.ensureVisitorSession();
384
329
  return apiConfig.httpClient.get(
385
- `${base(store_id)}/orders/${params.order_id}/digital-access/${params.grant_id}`,
330
+ `${base}/orders/${params.order_id}/digital-access/${params.grant_id}`,
386
331
  options
387
332
  );
388
333
  }
389
334
  },
390
335
  service: {
391
336
  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
- }
337
+ const identifier = params.id ?? params.slug;
338
+ if (!identifier) throw new Error("GetServiceParams requires id or slug");
401
339
  return apiConfig.httpClient.get(
402
- `${base(store_id)}/services/${identifier}`,
340
+ `${base}/services/${identifier}`,
403
341
  options
404
342
  );
405
343
  },
406
344
  find(params, options) {
407
- const { store_id, ...queryParams } = params;
408
345
  return apiConfig.httpClient.get(
409
- `${base(store_id)}/services`,
410
- {
411
- ...options,
412
- params: queryParams
413
- }
346
+ `${base}/services`,
347
+ { ...options, params }
414
348
  );
415
349
  },
416
350
  findProviders(params, options) {
417
- const { store_id, ...queryParams } = params;
418
351
  return apiConfig.httpClient.get(
419
- `${base(store_id)}/service-providers`,
420
- {
421
- ...options,
422
- params: queryParams
423
- }
352
+ `${base}/service-providers`,
353
+ { ...options, params }
424
354
  );
425
355
  },
426
356
  getAvailability(params, options) {
427
- const { store_id, ...queryParams } = params;
428
- const target_store_id = store_id || apiConfig.storeId;
429
357
  return apiConfig.httpClient.get(
430
- `${base(target_store_id)}/services/availability`,
431
- { ...options, params: queryParams }
358
+ `${base}/services/availability`,
359
+ { ...options, params }
432
360
  );
433
361
  }
434
362
  },
435
363
  provider: {
436
364
  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
- }
365
+ const identifier = params.id ?? params.slug;
366
+ if (!identifier) throw new Error("GetProviderParams requires id or slug");
446
367
  return apiConfig.httpClient.get(
447
- `${base(store_id)}/providers/${identifier}`,
368
+ `${base}/providers/${identifier}`,
448
369
  options
449
370
  );
450
371
  },
451
372
  find(params, options) {
452
- const { store_id, ...queryParams } = params;
453
373
  return apiConfig.httpClient.get(
454
- `${base(store_id)}/providers`,
455
- {
456
- ...options,
457
- params: queryParams
458
- }
374
+ `${base}/providers`,
375
+ { ...options, params }
459
376
  );
460
377
  }
461
378
  }
@@ -469,36 +386,23 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
469
386
  return submitIdentification("code", params, options);
470
387
  },
471
388
  async verify(params, options) {
472
- const store_id = apiConfig.storeId;
473
389
  const result = await apiConfig.httpClient.post(
474
- `${base(store_id)}/account/verify`,
475
- { store_id, challenge_id: params.challenge_id, code: params.code },
390
+ `${base}/account/verify`,
391
+ params,
476
392
  options
477
393
  );
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);
394
+ if (result.token?.token) {
395
+ updateContactSession(() => ({
396
+ sessionToken: result.token.token,
397
+ contact: result.contact
398
+ }));
494
399
  }
495
400
  return result;
496
401
  },
497
402
  async logout(options) {
498
- const store_id = apiConfig.storeId;
499
403
  try {
500
404
  await apiConfig.httpClient.post(
501
- `${base(store_id)}/account/logout`,
405
+ `${base}/account/logout`,
502
406
  {},
503
407
  options
504
408
  );
@@ -508,110 +412,74 @@ var createStorefrontApi = (apiConfig, updateContactSession) => {
508
412
  },
509
413
  getMe(options) {
510
414
  return apiConfig.httpClient.get(
511
- `${base()}/account/me`,
415
+ `${base}/account/me`,
512
416
  options
513
417
  );
514
418
  }
515
419
  },
516
420
  contactList: {
517
421
  get(params, options) {
518
- const store_id = params.store_id || apiConfig.storeId;
519
422
  return apiConfig.httpClient.get(
520
- `${base(store_id)}/contact-lists/${params.id}`,
423
+ `${base}/contact-lists/${params.id}`,
521
424
  options
522
425
  );
523
426
  },
524
- find(params, options) {
525
- const { store_id, ...queryParams } = params || {};
427
+ find(params = {}, options) {
526
428
  return apiConfig.httpClient.get(
527
- `${base(store_id)}/contact-lists`,
528
- {
529
- ...options,
530
- params: queryParams
531
- }
429
+ `${base}/contact-lists`,
430
+ { ...options, params }
532
431
  );
533
432
  },
534
433
  plans: {
535
434
  find(params, options) {
536
- const { store_id, contact_list_id, ...queryParams } = params;
435
+ const { contact_list_id, ...queryParams } = params;
537
436
  return apiConfig.httpClient.get(
538
- `${base(store_id)}/contact-lists/${contact_list_id}/plans`,
437
+ `${base}/contact-lists/${contact_list_id}/plans`,
539
438
  { ...options, params: queryParams }
540
439
  );
541
440
  }
542
441
  },
543
442
  memberships: {
544
- find(params, options) {
545
- const { store_id, ...queryParams } = params || {};
546
- return apiConfig.httpClient.get(`${base(store_id)}/contact-lists/memberships`, {
443
+ async find(params = {}, options) {
444
+ await lifecycle.ensureVisitorSession();
445
+ return apiConfig.httpClient.get(`${base}/contact-lists/memberships`, {
547
446
  ...options,
548
- params: queryParams
447
+ params
549
448
  });
550
449
  }
551
450
  },
552
- subscribe(params, options) {
553
- const { store_id, id, ...payload } = params;
451
+ async subscribe(params, options) {
452
+ await lifecycle.ensureVisitorSession();
453
+ const { id, ...payload } = params;
554
454
  return apiConfig.httpClient.post(
555
- `${base(store_id)}/contact-lists/${id}/subscribe`,
455
+ `${base}/contact-lists/${id}/subscribe`,
556
456
  payload,
557
457
  options
558
458
  );
559
459
  },
560
- checkAccess(params, options) {
561
- const store_id = params.store_id || apiConfig.storeId;
460
+ async checkAccess(params, options) {
461
+ await lifecycle.ensureVisitorSession();
562
462
  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,
572
- options
573
- );
574
- },
575
- manage(token, options) {
576
- return apiConfig.httpClient.post(
577
- `${base()}/contact-lists/manage`,
578
- { token },
463
+ `${base}/contact-lists/${params.id}/access`,
579
464
  options
580
465
  );
581
466
  },
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
- }
467
+ async checkContentAccess(params, options) {
468
+ await lifecycle.ensureVisitorSession();
587
469
  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 },
470
+ `${base}/contact-lists/access`,
471
+ params,
604
472
  options
605
473
  );
606
474
  }
607
475
  }
608
476
  },
609
- action: createActionApi(apiConfig),
477
+ action: createActionApi(apiConfig, lifecycle),
610
478
  experiments: {
611
- use(params, options) {
612
- const store_id = params.store_id || apiConfig.storeId;
479
+ async use(params, options) {
480
+ await lifecycle.ensureVisitorSession();
613
481
  return apiConfig.httpClient.post(
614
- `${base(store_id)}/experiments/use`,
482
+ `${base}/experiments/use`,
615
483
  { key: params.key },
616
484
  options
617
485
  );
@@ -771,6 +639,15 @@ function requestError(name, message, details = {}) {
771
639
  function isRecord(value) {
772
640
  return typeof value === "object" && value !== null;
773
641
  }
642
+ function omitStorefrontRouting(value) {
643
+ if (!isRecord(value) || Array.isArray(value)) return value;
644
+ const prototype = Object.getPrototypeOf(value);
645
+ if (prototype !== Object.prototype && prototype !== null) return value;
646
+ const result = { ...value };
647
+ delete result.store_id;
648
+ delete result.market;
649
+ return result;
650
+ }
774
651
  function isTokenSet(value) {
775
652
  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
653
  }
@@ -846,10 +723,25 @@ function createHttpClient(cfg) {
846
723
  if (!retried && options?.transformRequest) {
847
724
  body = options.transformRequest(body);
848
725
  }
726
+ if (cfg.storefrontMode) {
727
+ body = omitStorefrontRouting(body);
728
+ }
729
+ const forcedHeaders = typeof cfg.forcedHeaders === "function" ? cfg.forcedHeaders() : cfg.forcedHeaders || {};
730
+ const callerHeaders = { ...options?.headers || {} };
731
+ const protectedHeaderNames = new Set(
732
+ Object.keys(forcedHeaders).map((name) => name.toLowerCase())
733
+ );
734
+ if (cfg.storefrontMode) protectedHeaderNames.add("authorization");
735
+ for (const name of Object.keys(callerHeaders)) {
736
+ if (protectedHeaderNames.has(name.toLowerCase())) {
737
+ delete callerHeaders[name];
738
+ }
739
+ }
849
740
  const headers = {
850
741
  Accept: "application/json",
851
742
  "Content-Type": "application/json",
852
- ...options?.headers || {}
743
+ ...callerHeaders,
744
+ ...forcedHeaders
853
745
  };
854
746
  let tokens = authStorage.getTokens();
855
747
  const nowSec = Date.now() / 1e3;
@@ -860,7 +752,8 @@ function createHttpClient(cfg) {
860
752
  if (tokens?.access_token) {
861
753
  headers["Authorization"] = `Bearer ${tokens.access_token}`;
862
754
  }
863
- const finalPath = options?.params ? path + buildQueryString(options.params) : path;
755
+ const requestParams = cfg.storefrontMode ? omitStorefrontRouting(options?.params) : options?.params;
756
+ const finalPath = requestParams ? path + buildQueryString(requestParams) : path;
864
757
  const fetchOptions = {
865
758
  method,
866
759
  headers,
@@ -891,8 +784,19 @@ function createHttpClient(cfg) {
891
784
  throw err;
892
785
  }
893
786
  if (res.status === 401 && !retried) {
894
- await ensureFreshToken();
895
- return request(method, path, body, options, true);
787
+ if (cfg.onUnauthorized) {
788
+ const recovered = await cfg.onUnauthorized({
789
+ hadAuthorization: Boolean(tokens?.access_token),
790
+ authorizationToken: tokens?.access_token || null,
791
+ path
792
+ });
793
+ if (recovered) {
794
+ return request(method, path, body, options, true);
795
+ }
796
+ } else {
797
+ await ensureFreshToken();
798
+ return request(method, path, body, options, true);
799
+ }
896
800
  }
897
801
  try {
898
802
  const contentLength = res.headers.get("content-length");
@@ -973,13 +877,6 @@ function createHttpClient(cfg) {
973
877
  }
974
878
 
975
879
  // 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
880
  function storefrontSupportOptions(supportToken, options) {
984
881
  if (!/^[0-9a-f]{64}$/.test(supportToken)) {
985
882
  throw new Error("support_token must be a 64-character lowercase hexadecimal token");
@@ -996,32 +893,38 @@ function storefrontSupportOptions(supportToken, options) {
996
893
  }
997
894
  };
998
895
  }
999
- function createStorefrontSupportApi(config) {
896
+ function createStorefrontSupportApi(config, ensureVisitorSession) {
1000
897
  const { httpClient } = config;
1001
898
  return {
1002
899
  async startConversation(params = {}, opts) {
1003
- const storeId = config.storeId;
900
+ await ensureVisitorSession();
1004
901
  return httpClient.post(
1005
- `/v1/storefront/${storeId}/support/conversations`,
1006
- { ...params, store_id: storeId },
902
+ "/v1/storefront/support/conversations",
903
+ params,
1007
904
  opts
1008
905
  );
1009
906
  },
1010
907
  async sendMessage(params, opts) {
908
+ await ensureVisitorSession();
1011
909
  const { support_token, ...request } = params;
1012
- const storeId = config.storeId;
1013
910
  return httpClient.post(
1014
- `/v1/storefront/${storeId}/support/conversations/${request.conversation_id}/messages`,
1015
- { ...request, store_id: storeId },
911
+ `/v1/storefront/support/conversations/${request.conversation_id}/messages`,
912
+ request,
1016
913
  storefrontSupportOptions(support_token, opts)
1017
914
  );
1018
915
  },
1019
916
  async getConversation(params, opts) {
917
+ await ensureVisitorSession();
1020
918
  const { support_token, ...request } = params;
1021
- const storeId = config.storeId;
1022
- const qs = supportConversationQuery({ ...request, store_id: storeId });
919
+ const query = new URLSearchParams();
920
+ if (request.message_limit) query.set("message_limit", String(request.message_limit));
921
+ if (typeof request.after_created_at === "number") {
922
+ query.set("after_created_at", String(request.after_created_at));
923
+ }
924
+ if (request.after_id) query.set("after_id", request.after_id);
925
+ const suffix = query.size ? `?${query}` : "";
1023
926
  return httpClient.get(
1024
- `/v1/storefront/${storeId}/support/conversations/${request.conversation_id}?${qs}`,
927
+ `/v1/storefront/support/conversations/${request.conversation_id}${suffix}`,
1025
928
  storefrontSupportOptions(support_token, opts)
1026
929
  );
1027
930
  }
@@ -1479,280 +1382,6 @@ function getFirstAvailableFCId(variant, quantity = 1) {
1479
1382
  return inv?.location_id;
1480
1383
  }
1481
1384
 
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
1385
  // src/payments/stripe.ts
1757
1386
  async function defaultStripeLoader(publishableKey, options) {
1758
1387
  const { loadStripe } = await import('@stripe/stripe-js');
@@ -1826,7 +1455,8 @@ function createElements(stripe, config) {
1826
1455
  amount: config.amount,
1827
1456
  currency: normalizeCurrency(config.currency),
1828
1457
  paymentMethodCreation: "manual",
1829
- ...config.appearance ? { appearance: config.appearance } : {}
1458
+ ...config.appearance ? { appearance: config.appearance } : {},
1459
+ ...config.setupFutureUsage ? { setupFutureUsage: config.setupFutureUsage } : {}
1830
1460
  });
1831
1461
  }
1832
1462
 
@@ -2129,22 +1759,24 @@ function normalizeTimezoneGroups(groups) {
2129
1759
  function firstFiniteNumber(...values) {
2130
1760
  return values.find((value) => typeof value === "number" && Number.isFinite(value));
2131
1761
  }
2132
- function initializeStore(config) {
2133
- const client = createStorefront(config);
2134
- const formClients = /* @__PURE__ */ new Map([[client.getStoreId(), client]]);
1762
+ function initializeStoreCore(publishableKey, config, scopedClient) {
1763
+ const client = scopedClient || createStorefront(publishableKey, config);
2135
1764
  const session = atom(client.session);
1765
+ const setup = atom(null);
2136
1766
  const locale = atom(config.locale || client.getLocale());
2137
1767
  const market_key = atom(config.market || client.getMarket());
2138
- const market = computed(session, (value) => value?.market || null);
1768
+ const market = computed([setup, market_key], (setupValue, marketKey) => {
1769
+ const resolvedKey = marketKey || setupValue?.markets.default;
1770
+ return setupValue?.markets.available.find((candidate) => candidate.key === resolvedKey) || null;
1771
+ });
2139
1772
  const currency = computed(market, (value) => value?.currency || null);
2140
1773
  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 || [];
1774
+ const payment_config = computed([setup, market], (setupValue, marketValue) => {
1775
+ const methods = marketValue?.payment_methods || [];
2144
1776
  const hasCreditCard = methods.some((method) => method.type === "credit_card");
2145
1777
  return {
2146
- provider: store?.payment || null,
2147
- enabled: hasCreditCard && !!store?.payment
1778
+ provider: setupValue?.payment || null,
1779
+ enabled: hasCreditCard && Boolean(setupValue?.readiness.payment)
2148
1780
  };
2149
1781
  });
2150
1782
  const cart = atom(null);
@@ -2240,24 +1872,17 @@ function initializeStore(config) {
2240
1872
  const service_form_blocks = computed(service_form_groups, (groups) => groups.flatMap((group) => group.blocks));
2241
1873
  client.onAuthStateChanged((value) => session.set(value));
2242
1874
  currency.subscribe((value) => service_state.setKey("currency", value));
2243
- session.subscribe((value) => {
2244
- const methods = value?.market?.payment_methods || [];
1875
+ market.subscribe((value) => {
1876
+ const methods = value?.payment_methods || [];
2245
1877
  if (methods.length && service_state.get().availablePaymentMethods.length === 0) {
2246
1878
  service_state.setKey("availablePaymentMethods", methods);
2247
1879
  }
2248
1880
  });
2249
1881
  function currentMarketKey() {
2250
- return market_key.get() || client.getMarket() || market.get()?.key || "";
1882
+ return market_key.get() || client.getMarket() || setup.get()?.markets.default || "";
2251
1883
  }
2252
1884
  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;
1885
+ return locale.get() || client.getLocale() || setup.get()?.languages.default || "en";
2261
1886
  }
2262
1887
  function currentStripePublishableKey() {
2263
1888
  const provider = payment_config.get()?.provider;
@@ -2287,10 +1912,24 @@ function initializeStore(config) {
2287
1912
  function destroyPaymentController() {
2288
1913
  setPaymentController(null);
2289
1914
  }
2290
- 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");
1915
+ async function loadSetup() {
1916
+ const current = setup.get();
1917
+ if (current) return current;
1918
+ const result = await client.getSetup();
1919
+ setup.set(result);
1920
+ if (!market_key.get() && result.markets.default) {
1921
+ market_key.set(result.markets.default);
1922
+ }
1923
+ if (!locale.get() && result.languages.default) {
1924
+ locale.set(result.languages.default);
1925
+ }
1926
+ return result;
1927
+ }
1928
+ async function mountPayment(target, options = {}) {
1929
+ await loadSetup();
1930
+ const publishableKey2 = currentStripePublishableKey();
1931
+ if (!publishableKey2) {
1932
+ throw new Error("Stripe card payment is not configured for this Store");
2294
1933
  }
2295
1934
  const hasExplicitAmount = options.amount !== void 0;
2296
1935
  const hasExplicitCurrency = Boolean(options.currency?.trim());
@@ -2306,11 +1945,12 @@ function initializeStore(config) {
2306
1945
  throw new Error("An explicit three-letter payment currency is required to mount card payment");
2307
1946
  }
2308
1947
  const controller = await createStripeConfirmationTokenController({
2309
- publishableKey,
2310
- connectedAccountId: options.connectedAccountId || currentStripeConnectedAccountId() || void 0,
1948
+ publishableKey: publishableKey2,
1949
+ connectedAccountId: currentStripeConnectedAccountId() || void 0,
2311
1950
  amount,
2312
1951
  currency: paymentCurrency,
2313
- ...options.appearance ? { appearance: options.appearance } : {}
1952
+ ...options.appearance ? { appearance: options.appearance } : {},
1953
+ ...options.setupFutureUsage ? { setupFutureUsage: options.setupFutureUsage } : {}
2314
1954
  });
2315
1955
  controller.mount(target);
2316
1956
  setPaymentController(controller);
@@ -2319,15 +1959,11 @@ function initializeStore(config) {
2319
1959
  function updatePaymentController(input) {
2320
1960
  payment_controller.get()?.update(input);
2321
1961
  }
2322
- function marketForLocale(value) {
2323
- return config.marketForLocale?.(value) || null;
2324
- }
2325
1962
  async function ensureSession() {
2326
1963
  const current = session.get();
2327
- const marketKey = currentMarketKey();
2328
- if (current && (!marketKey || current.market?.key === marketKey)) return current;
1964
+ if (client.isAuthenticated) return current;
2329
1965
  if (!sessionRequest) {
2330
- sessionRequest = identify({ market: marketKey }).finally(() => {
1966
+ sessionRequest = identify().finally(() => {
2331
1967
  sessionRequest = null;
2332
1968
  });
2333
1969
  }
@@ -2340,9 +1976,7 @@ function initializeStore(config) {
2340
1976
  market: params.market || currentMarketKey()
2341
1977
  });
2342
1978
  session.set({
2343
- contact: result.contact,
2344
- store: result.store,
2345
- market: result.market
1979
+ contact: result.contact
2346
1980
  });
2347
1981
  return result;
2348
1982
  }
@@ -2354,21 +1988,24 @@ function initializeStore(config) {
2354
1988
  return identify({ email: normalizedEmail });
2355
1989
  }
2356
1990
  function setMarket(key) {
2357
- market_key.set(key);
2358
- client.setMarket(key);
1991
+ const next = key.trim();
1992
+ const current = currentMarketKey();
1993
+ if (next && current && next !== current && (cart.get()?.item_count || item_count.get()) > 0) {
1994
+ throw Object.assign(
1995
+ new Error("Market cannot change while the cart contains items"),
1996
+ { code: "CART_MARKET_LOCKED" }
1997
+ );
1998
+ }
1999
+ market_key.set(next);
2000
+ client.setMarket(next);
2359
2001
  }
2360
- function setLocale(value, options = {}) {
2002
+ function setLocale(value) {
2361
2003
  locale.set(value);
2362
2004
  client.setLocale(value);
2363
- const nextMarket = options.market || marketForLocale(value);
2364
- if (nextMarket) setMarket(nextMarket);
2365
2005
  }
2366
2006
  function setContext(context) {
2367
- if (context.locale) {
2368
- setLocale(context.locale, { market: context.market });
2369
- return;
2370
- }
2371
- if (context.market) setMarket(context.market);
2007
+ if (context.market !== void 0) setMarket(context.market);
2008
+ if (context.locale !== void 0) setLocale(context.locale);
2372
2009
  }
2373
2010
  async function ensureCart() {
2374
2011
  if (cartRequest) return cartRequest;
@@ -2377,9 +2014,7 @@ function initializeStore(config) {
2377
2014
  const refreshRevision = cartWriteRevision;
2378
2015
  cartRequest = (async () => {
2379
2016
  await ensureSession();
2380
- const response = await client.eshop.cart.current({
2381
- market: currentMarketKey()
2382
- });
2017
+ const response = await client.eshop.cart.current();
2383
2018
  await applyCartResponse(response, { ifRevision: refreshRevision });
2384
2019
  return response;
2385
2020
  })();
@@ -2396,8 +2031,16 @@ function initializeStore(config) {
2396
2031
  async function buildProductCartItem(item, source, productHint) {
2397
2032
  try {
2398
2033
  const product = productHint?.id === item.product_id ? productHint : await client.eshop.product.get({ id: item.product_id });
2399
- const variant = product.variants.find((candidate) => candidate.id === item.variant_id);
2400
- if (!variant) return null;
2034
+ const variant = product.variants.find(
2035
+ (candidate) => candidate.id === item.variant_id
2036
+ );
2037
+ if (!variant) {
2038
+ cart_status.setKey(
2039
+ "error",
2040
+ `Cart product ${item.product_id} references unavailable variant ${item.variant_id}.`
2041
+ );
2042
+ return null;
2043
+ }
2401
2044
  return {
2402
2045
  id: item.id || createId("product"),
2403
2046
  product_id: product.id,
@@ -2411,7 +2054,14 @@ function initializeStore(config) {
2411
2054
  added_at: source.created_at ? source.created_at * 1e3 : Date.now(),
2412
2055
  max_stock: availableStock(client, variant)
2413
2056
  };
2414
- } catch {
2057
+ } catch (error) {
2058
+ cart_status.setKey(
2059
+ "error",
2060
+ readErrorMessage(
2061
+ error,
2062
+ `Failed to load cart product ${item.product_id}.`
2063
+ )
2064
+ );
2415
2065
  return null;
2416
2066
  }
2417
2067
  }
@@ -2450,6 +2100,7 @@ function initializeStore(config) {
2450
2100
  promo_code.set(response.promo_code || null);
2451
2101
  quote.set(response.quote_snapshot || null);
2452
2102
  const items = response.items || [];
2103
+ if (items.length > 0) await loadSetup();
2453
2104
  const products = await Promise.all(
2454
2105
  items.filter((item) => item.type === "product").map((item) => buildProductCartItem(item, response, options.productHint))
2455
2106
  );
@@ -2471,7 +2122,6 @@ function initializeStore(config) {
2471
2122
  const current = cart.get() || await ensureCart();
2472
2123
  const response = await client.eshop.cart.update({
2473
2124
  id: current.id,
2474
- market: currentMarketKey(),
2475
2125
  items: checkoutItems(input),
2476
2126
  shipping_address: input.shipping_address,
2477
2127
  billing_address: input.billing_address,
@@ -2887,7 +2537,7 @@ function initializeStore(config) {
2887
2537
  async initialize() {
2888
2538
  service_state.setKey("tzGroups", normalizeTimezoneGroups(client.utils.tzGroups));
2889
2539
  await ensureCart();
2890
- const methods = session.get()?.market?.payment_methods || [];
2540
+ const methods = market.get()?.payment_methods || [];
2891
2541
  if (methods.length) service_state.setKey("availablePaymentMethods", methods);
2892
2542
  },
2893
2543
  setTimezone(tz) {
@@ -2936,7 +2586,9 @@ function initializeStore(config) {
2936
2586
  ...service_state.get(),
2937
2587
  service: fullService,
2938
2588
  serviceProviders,
2939
- providers: providerResults.filter((provider) => provider !== null),
2589
+ providers: providerResults.filter(
2590
+ (provider) => provider !== null
2591
+ ),
2940
2592
  selectedProviderId: null,
2941
2593
  availability: null,
2942
2594
  selectedDate: null,
@@ -3150,7 +2802,7 @@ function initializeStore(config) {
3150
2802
  });
3151
2803
  service_state.setKey("cartId", cart.get()?.id || null);
3152
2804
  service_state.setKey("quote", response);
3153
- const methods = response?.payment_methods || session.get()?.market?.payment_methods || [];
2805
+ const methods = response?.payment_methods || market.get()?.payment_methods || [];
3154
2806
  if (methods.length) service_state.setKey("availablePaymentMethods", methods);
3155
2807
  return response;
3156
2808
  } catch (error) {
@@ -3242,20 +2894,17 @@ function initializeStore(config) {
3242
2894
  }
3243
2895
  }
3244
2896
  function formCacheKey(params) {
3245
- const storeId = params.store_id || client.getStoreId();
3246
2897
  const identifier = params.id ? `id:${params.id}` : params.key ? `key:${params.key}` : "missing";
3247
- return `${storeId}:${identifier}`;
2898
+ return identifier;
3248
2899
  }
3249
2900
  async function loadForm(params, options) {
3250
2901
  cms_state.setKey("loading", true);
3251
2902
  cms_state.setKey("error", null);
3252
2903
  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);
2904
+ const form = await client.cms.form.get(params, options);
3256
2905
  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;
2906
+ forms[formCacheKey({ id: form.id })] = form;
2907
+ forms[formCacheKey({ key: form.key })] = form;
3259
2908
  cms_state.setKey("forms", forms);
3260
2909
  return form;
3261
2910
  } catch (error) {
@@ -3265,26 +2914,14 @@ function initializeStore(config) {
3265
2914
  cms_state.setKey("loading", false);
3266
2915
  }
3267
2916
  }
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
2917
  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);
2918
+ await ensureSession();
2919
+ return client.cms.form.submit(params, options);
3282
2920
  }
3283
2921
  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);
2922
+ const form = await loadForm({ key: params.key }, options);
3286
2923
  const entry = createFormEntryFromValues(form, params.values);
3287
- return submitForm({ store_id: storeId, form_id: form.id, fields: entry.fields }, options);
2924
+ return submitForm({ form_id: form.id, fields: entry.fields }, options);
3288
2925
  }
3289
2926
  async function loadProducts(params = {}, options) {
3290
2927
  eshop_state.setKey("loading_products", true);
@@ -3382,7 +3019,7 @@ function initializeStore(config) {
3382
3019
  ready: payment_ready,
3383
3020
  setController: setPaymentController,
3384
3021
  getController: () => payment_controller.get(),
3385
- mountStripe: mountStripePayment,
3022
+ mount: mountPayment,
3386
3023
  update: updatePaymentController,
3387
3024
  destroy: destroyPaymentController
3388
3025
  },
@@ -3446,6 +3083,7 @@ function initializeStore(config) {
3446
3083
  return {
3447
3084
  client,
3448
3085
  session,
3086
+ setup,
3449
3087
  market,
3450
3088
  market_key,
3451
3089
  locale,
@@ -3464,7 +3102,6 @@ function initializeStore(config) {
3464
3102
  setMarket,
3465
3103
  setLocale,
3466
3104
  setContext,
3467
- getStoreId: client.getStoreId,
3468
3105
  getMarket: currentMarketKey,
3469
3106
  getLocale: currentLocale,
3470
3107
  cms: {
@@ -3508,31 +3145,400 @@ function initializeStore(config) {
3508
3145
  use: useExperiment
3509
3146
  },
3510
3147
  support: client.support,
3511
- store: client.store,
3148
+ store: {
3149
+ ...client.store,
3150
+ setup,
3151
+ load: loadSetup
3152
+ },
3512
3153
  utils: client.utils
3513
3154
  };
3514
3155
  }
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
- })
3156
+ function initializeStore(publishableKey, config, scopedClient) {
3157
+ const store = initializeStoreCore(publishableKey, config, scopedClient);
3158
+ return Object.assign(store, {
3159
+ withContext(context) {
3160
+ return initializeStore(
3161
+ publishableKey,
3162
+ {
3163
+ ...config,
3164
+ locale: context.locale ?? store.getLocale(),
3165
+ market: context.market ?? store.getMarket()
3166
+ },
3167
+ store.client.withContext(context)
3168
+ );
3169
+ }
3170
+ });
3171
+ }
3172
+ function initialize(publishableKey, options = {}) {
3173
+ return initializeStore(publishableKey, options);
3174
+ }
3175
+
3176
+ // src/index.ts
3177
+ function createUtilitySurface(apiConfig) {
3178
+ return {
3179
+ getImageUrl: (imageBlock, isBlock2 = true) => getImageUrl(imageBlock, isBlock2),
3180
+ getBlockValue,
3181
+ getBlockTextValue,
3182
+ getBlockContentValue,
3183
+ getBlockValues,
3184
+ getBlockLabel,
3185
+ getBlockObjectValues,
3186
+ getBlockFromArray,
3187
+ formatBlockValue,
3188
+ prepareBlocksForSubmission,
3189
+ extractBlockValues,
3190
+ formatPrice: (prices) => formatPrice(prices, apiConfig.market),
3191
+ getPriceAmount: (prices) => getPriceAmount(prices, apiConfig.market),
3192
+ formatPayment,
3193
+ formatMinor,
3194
+ getCurrencySymbol,
3195
+ getCurrencyName,
3196
+ validatePhoneNumber,
3197
+ tzGroups,
3198
+ findTimeZone,
3199
+ slugify,
3200
+ humanize,
3201
+ categorify,
3202
+ formatDate,
3203
+ getSvgContentForAstro,
3204
+ fetchSvgContent,
3205
+ injectSvgIntoElement,
3206
+ isValidKey,
3207
+ validateKey,
3208
+ toKey,
3209
+ nameToKey,
3210
+ getAvailableStock,
3211
+ getReservedStock,
3212
+ hasStock,
3213
+ getInventoryAt,
3214
+ getFirstAvailableFCId
3215
+ };
3216
+ }
3217
+ var DEFAULT_STOREFRONT_API_URL = "https://api.arky.io";
3218
+ var storefrontScopeSequence = 0;
3219
+ function defaultStorefrontSessionStorage() {
3220
+ if (typeof window === "undefined") return null;
3221
+ try {
3222
+ return window.localStorage;
3223
+ } catch {
3224
+ return null;
3225
+ }
3226
+ }
3227
+ function normalizeStorefrontApiUrl(value) {
3228
+ const input = value?.trim() || DEFAULT_STOREFRONT_API_URL;
3229
+ let parsed;
3230
+ try {
3231
+ parsed = new URL(input);
3232
+ } catch {
3233
+ throw new Error("Storefront apiUrl must be a valid HTTP(S) URL");
3234
+ }
3235
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
3236
+ throw new Error("Storefront apiUrl must use HTTP or HTTPS");
3237
+ }
3238
+ return input.replace(/\/+$/, "");
3239
+ }
3240
+ function validatePublishableKey(publishableKey) {
3241
+ if (typeof publishableKey !== "string") {
3242
+ throw new Error(
3243
+ "A valid Arky publishable key is required (arky_pk_ followed by 43 URL-safe characters)"
3244
+ );
3245
+ }
3246
+ const key = publishableKey.trim();
3247
+ if (!/^arky_pk_[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/.test(key)) {
3248
+ throw new Error(
3249
+ "A valid Arky publishable key is required (arky_pk_ followed by 43 URL-safe characters)"
3250
+ );
3251
+ }
3252
+ return key;
3253
+ }
3254
+ function publishableKeyFingerprint(publishableKey) {
3255
+ let hashA = 2166136261;
3256
+ let hashB = 2654435769;
3257
+ for (let index = 0; index < publishableKey.length; index += 1) {
3258
+ const code = publishableKey.charCodeAt(index);
3259
+ hashA = Math.imul(hashA ^ code, 16777619);
3260
+ hashB = Math.imul(hashB ^ code, 2246822507);
3261
+ }
3262
+ return `${(hashA >>> 0).toString(36)}${(hashB >>> 0).toString(36)}`;
3263
+ }
3264
+ function storefrontSessionStorageKey(apiUrl, publishableKey) {
3265
+ return `arky_visitor_session:${encodeURIComponent(apiUrl.toLowerCase())}:${publishableKeyFingerprint(publishableKey)}`;
3266
+ }
3267
+ function isVisitorSessionToken(value) {
3268
+ return Boolean(value && /^arky_vst_[0-9a-f]{64}$/.test(value));
3269
+ }
3270
+ function createStorefrontClientCore(publishableKeyInput, options = {}, isolatedSession = false) {
3271
+ const publishableKey = validatePublishableKey(publishableKeyInput);
3272
+ const apiUrl = normalizeStorefrontApiUrl(options.apiUrl);
3273
+ let locale = options.locale?.trim() || "";
3274
+ let market = options.market?.trim() || "";
3275
+ const listeners = /* @__PURE__ */ new Set();
3276
+ let identifyPromise = null;
3277
+ let identityTail = Promise.resolve();
3278
+ let setupPromise = null;
3279
+ let setupValue = null;
3280
+ const explicitSessionStorage = options.sessionStorage;
3281
+ const sessionStorage = isolatedSession ? explicitSessionStorage || null : explicitSessionStorage || defaultStorefrontSessionStorage();
3282
+ const canCreateVisitorSession = typeof window !== "undefined" || Boolean(explicitSessionStorage);
3283
+ const storageKey = `${storefrontSessionStorageKey(apiUrl, publishableKey)}${isolatedSession ? `:scope:${++storefrontScopeSequence}` : ""}`;
3284
+ let memorySession = null;
3285
+ let memorySessionToken = null;
3286
+ function readSessionToken() {
3287
+ if (!sessionStorage) return memorySessionToken;
3288
+ try {
3289
+ const stored = sessionStorage.getItem(storageKey);
3290
+ return isVisitorSessionToken(stored) ? stored : memorySessionToken;
3291
+ } catch {
3292
+ return memorySessionToken;
3293
+ }
3294
+ }
3295
+ function writeContactSession(session) {
3296
+ memorySession = session;
3297
+ memorySessionToken = session?.sessionToken || null;
3298
+ if (!sessionStorage) return;
3299
+ try {
3300
+ if (session) {
3301
+ sessionStorage.setItem(storageKey, session.sessionToken);
3302
+ } else {
3303
+ sessionStorage.removeItem(storageKey);
3304
+ }
3305
+ } catch {
3306
+ }
3307
+ }
3308
+ function toPublic(s) {
3309
+ return s ? { contact: s.contact } : null;
3310
+ }
3311
+ function emit() {
3312
+ const pub = toPublic(memorySession);
3313
+ for (const l of listeners) {
3314
+ Promise.resolve().then(() => l(pub)).catch(() => {
3315
+ });
3316
+ }
3317
+ }
3318
+ const updateSession = (updater) => {
3319
+ const next = updater(memorySession);
3320
+ writeContactSession(next);
3321
+ emit();
3322
+ };
3323
+ const authStorage = {
3324
+ getTokens() {
3325
+ const sessionToken = readSessionToken();
3326
+ return sessionToken ? { access_token: sessionToken } : null;
3327
+ },
3328
+ onTokensRefreshed() {
3329
+ },
3330
+ onForcedLogout() {
3331
+ identifyPromise = null;
3332
+ updateSession(() => null);
3333
+ }
3334
+ };
3335
+ let recoverUnauthorized = async () => false;
3336
+ let visitorRecoveryPromise = null;
3337
+ const httpClient = createHttpClient({
3338
+ baseUrl: apiUrl,
3339
+ authStorage,
3340
+ storefrontMode: true,
3341
+ forcedHeaders: () => ({
3342
+ "X-Arky-Publishable-Key": publishableKey,
3343
+ ...locale ? { "X-Arky-Locale": locale } : {},
3344
+ ...market ? { "X-Arky-Market": market } : {}
3345
+ }),
3346
+ onUnauthorized: ({ authorizationToken, path }) => recoverUnauthorized(authorizationToken, path)
3347
+ });
3348
+ const apiConfig = {
3349
+ httpClient,
3350
+ apiUrl,
3351
+ publishableKey,
3352
+ market,
3353
+ locale,
3354
+ authStorage
3355
+ };
3356
+ function requireVisitorSessionCapability() {
3357
+ if (!canCreateVisitorSession) {
3358
+ throw new Error(
3359
+ "Stateful storefront operations during SSR require an explicit request-local sessionStorage adapter"
3360
+ );
3361
+ }
3362
+ }
3363
+ async function getSetup(requestOptions) {
3364
+ if (setupValue) return setupValue;
3365
+ if (setupPromise) return setupPromise;
3366
+ setupPromise = httpClient.get(
3367
+ "/v1/storefront",
3368
+ requestOptions
3369
+ ).then((setup) => {
3370
+ setupValue = setup;
3371
+ return setup;
3372
+ }).finally(() => {
3373
+ setupPromise = null;
3532
3374
  });
3533
- return store;
3375
+ return setupPromise;
3376
+ }
3377
+ async function ensureVisitorSession() {
3378
+ if (readSessionToken()) return;
3379
+ requireVisitorSessionCapability();
3380
+ await identify();
3381
+ }
3382
+ const storefrontApi = createStorefrontApi(apiConfig, updateSession, {
3383
+ ensureVisitorSession,
3384
+ getSetup
3385
+ });
3386
+ const contactApi = storefrontApi.crm.contact;
3387
+ function identify(params) {
3388
+ requireVisitorSessionCapability();
3389
+ if (params?.market !== void 0) setMarket(params.market);
3390
+ const isBareCall = !params?.email && !params?.verify;
3391
+ if (isBareCall && identifyPromise) return identifyPromise;
3392
+ const run = async () => {
3393
+ const result = await (params?.verify ? contactApi.requestCode({ email: params.email }) : contactApi.identify({ email: params?.email }));
3394
+ return {
3395
+ contact: result.contact,
3396
+ verification_challenge: result.verification_challenge
3397
+ };
3398
+ };
3399
+ const promise = identityTail.then(run);
3400
+ identityTail = promise.then(
3401
+ () => void 0,
3402
+ () => void 0
3403
+ );
3404
+ if (isBareCall) {
3405
+ identifyPromise = promise;
3406
+ void promise.then(
3407
+ () => {
3408
+ if (identifyPromise === promise) identifyPromise = null;
3409
+ },
3410
+ () => {
3411
+ if (identifyPromise === promise) identifyPromise = null;
3412
+ }
3413
+ );
3414
+ }
3415
+ return promise;
3416
+ }
3417
+ async function verify(params) {
3418
+ requireVisitorSessionCapability();
3419
+ const result = await contactApi.verify(params);
3420
+ identifyPromise = null;
3421
+ return { contact: result.contact };
3422
+ }
3423
+ async function me() {
3424
+ await ensureVisitorSession();
3425
+ return contactApi.getMe();
3426
+ }
3427
+ async function logout() {
3428
+ identifyPromise = null;
3429
+ if (!readSessionToken()) {
3430
+ updateSession(() => null);
3431
+ return;
3432
+ }
3433
+ try {
3434
+ await contactApi.logout();
3435
+ } catch {
3436
+ updateSession(() => null);
3437
+ }
3438
+ }
3439
+ function setMarket(value) {
3440
+ market = value.trim();
3441
+ apiConfig.market = market;
3442
+ identifyPromise = null;
3443
+ }
3444
+ function setLocale(value) {
3445
+ locale = value.trim();
3446
+ apiConfig.locale = locale;
3447
+ }
3448
+ function setContext(context) {
3449
+ if (context.locale !== void 0) setLocale(context.locale);
3450
+ if (context.market !== void 0) setMarket(context.market);
3451
+ }
3452
+ recoverUnauthorized = async (authorizationToken, path) => {
3453
+ if (!authorizationToken) return false;
3454
+ const currentToken = readSessionToken();
3455
+ if (currentToken !== authorizationToken) {
3456
+ if (currentToken) return true;
3457
+ if (!visitorRecoveryPromise) return false;
3458
+ await visitorRecoveryPromise;
3459
+ return Boolean(readSessionToken());
3460
+ }
3461
+ updateSession(() => null);
3462
+ if (/\/account\/(identify|code)$/.test(path)) return true;
3463
+ const recovery = ensureVisitorSession();
3464
+ const trackedRecovery = recovery.finally(() => {
3465
+ if (visitorRecoveryPromise === trackedRecovery) {
3466
+ visitorRecoveryPromise = null;
3467
+ }
3468
+ });
3469
+ visitorRecoveryPromise = trackedRecovery;
3470
+ await trackedRecovery;
3471
+ return true;
3534
3472
  };
3535
- return createScope(config);
3473
+ return {
3474
+ identify,
3475
+ verify,
3476
+ logout,
3477
+ me,
3478
+ get session() {
3479
+ return toPublic(memorySession);
3480
+ },
3481
+ get isAuthenticated() {
3482
+ return Boolean(readSessionToken());
3483
+ },
3484
+ onAuthStateChanged(listener) {
3485
+ listeners.add(listener);
3486
+ const current = toPublic(memorySession);
3487
+ if (current) {
3488
+ Promise.resolve().then(() => listener(current)).catch(() => {
3489
+ });
3490
+ }
3491
+ return () => {
3492
+ listeners.delete(listener);
3493
+ };
3494
+ },
3495
+ store: storefrontApi.store,
3496
+ cms: storefrontApi.cms,
3497
+ eshop: storefrontApi.eshop,
3498
+ crm: {
3499
+ ...storefrontApi.crm,
3500
+ contact: {
3501
+ identify: (params) => identify(params),
3502
+ requestCode: (params) => identify({ ...params, verify: true }),
3503
+ verify,
3504
+ logout,
3505
+ getMe: me
3506
+ }
3507
+ },
3508
+ action: storefrontApi.action,
3509
+ experiments: storefrontApi.experiments,
3510
+ support: createStorefrontSupportApi(apiConfig, ensureVisitorSession),
3511
+ getSetup,
3512
+ setContext,
3513
+ setMarket,
3514
+ getMarket: () => market,
3515
+ setLocale,
3516
+ getLocale: () => locale,
3517
+ utils: createUtilitySurface(apiConfig)
3518
+ };
3519
+ }
3520
+ function createStorefrontClient(publishableKey, options = {}, isolatedSession = false) {
3521
+ const client = createStorefrontClientCore(
3522
+ publishableKey,
3523
+ options,
3524
+ isolatedSession
3525
+ );
3526
+ return Object.assign(client, {
3527
+ withContext(context) {
3528
+ return createStorefrontClient(
3529
+ publishableKey,
3530
+ {
3531
+ ...options,
3532
+ locale: context.locale ?? client.getLocale(),
3533
+ market: context.market ?? client.getMarket()
3534
+ },
3535
+ true
3536
+ );
3537
+ }
3538
+ });
3539
+ }
3540
+ function createStorefront(publishableKey, options = {}) {
3541
+ return createStorefrontClient(publishableKey, options);
3536
3542
  }
3537
3543
 
3538
3544
  export { COMMON_ACTION_KEYS, buildFormFields, createCartController, createFormEntry, createFormEntryFromValues, createStorefront, createStripeConfirmationTokenController, getBlockContentValue, initialize };