@behio/storefront-sdk 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/{chunk-SCFR6JH7.mjs → chunk-MCWHR3BY.mjs} +67 -12
- package/dist/{chunk-TDIAWIQR.js → chunk-SF7JTW3Y.js} +68 -13
- package/dist/{client-C4dnHtID.d.mts → client-Gf4MBpav.d.mts} +13 -0
- package/dist/{client-C4dnHtID.d.ts → client-Gf4MBpav.d.ts} +13 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/index.mjs +1 -1
- package/dist/next.d.mts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +2 -2
- package/dist/next.mjs +1 -1
- package/dist/react.d.mts +13 -0
- package/dist/react.d.ts +13 -0
- package/dist/react.js +101 -22
- package/dist/react.mjs +101 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,14 @@ accepting the server response. This includes adding, clearing, applying or
|
|
|
18
18
|
removing a discount, and merging baskets. A delayed read cannot restore an old
|
|
19
19
|
basket after one of those actions succeeds.
|
|
20
20
|
|
|
21
|
+
From 2.0.2, responses and retries from an older customer, cart session, currency,
|
|
22
|
+
country or locale are rejected with SDK status 409. Retry explicitly in the
|
|
23
|
+
current context. An ordinary token refresh remains in the same customer session.
|
|
24
|
+
`useAuth()` cancels old queries and removes customer data and prices on an
|
|
25
|
+
identity change, including seeded SSR data. A late logout or failed refresh
|
|
26
|
+
cannot clear a newer login. This browser protection does not replace per-request
|
|
27
|
+
SSR clients or server authorization.
|
|
28
|
+
|
|
21
29
|
```bash
|
|
22
30
|
npm install @behio/storefront-sdk
|
|
23
31
|
```
|
|
@@ -165,6 +165,8 @@ var BehioStorefront = class {
|
|
|
165
165
|
// Token refresh lock
|
|
166
166
|
this.isRefreshing = false;
|
|
167
167
|
this.refreshPromise = null;
|
|
168
|
+
this.requestContextVersion = 0;
|
|
169
|
+
this.authContextVersion = 0;
|
|
168
170
|
// Event emitter
|
|
169
171
|
this.listeners = /* @__PURE__ */ new Map();
|
|
170
172
|
// Interceptors
|
|
@@ -208,6 +210,28 @@ var BehioStorefront = class {
|
|
|
208
210
|
this.subscriptions = new SubscriptionsModule(this);
|
|
209
211
|
this.certificates = new CourseCertificatesModule(this);
|
|
210
212
|
}
|
|
213
|
+
/** @internal Opaque generation, never a token or customer identifier. */
|
|
214
|
+
getRequestContextVersion() {
|
|
215
|
+
return this.requestContextVersion;
|
|
216
|
+
}
|
|
217
|
+
/** @internal Refreshes must not restore a session that has been replaced. */
|
|
218
|
+
getAuthContextVersion() {
|
|
219
|
+
return this.authContextVersion;
|
|
220
|
+
}
|
|
221
|
+
/** @internal A refresh rotates credentials within the same customer session. */
|
|
222
|
+
acceptRefreshedTokens(tokens, expectedVersion) {
|
|
223
|
+
if (this.authContextVersion !== expectedVersion) return false;
|
|
224
|
+
if (!this.accessToken) this.setTokens(tokens);
|
|
225
|
+
else {
|
|
226
|
+
this.accessToken = tokens.accessToken;
|
|
227
|
+
this.refreshToken = tokens.refreshToken;
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
/** @internal An obsolete response must not update cache, session or retries. */
|
|
232
|
+
assertRequestContext(version, authOnly = false) {
|
|
233
|
+
if (version !== (authOnly ? this.authContextVersion : this.requestContextVersion)) throw new BehioApiError(409, null, "The storefront session or pricing context changed. Please retry in the current context.");
|
|
234
|
+
}
|
|
211
235
|
// --- Public methods ---
|
|
212
236
|
/**
|
|
213
237
|
* Called by the analytics tracker when the visitor grants (id) or revokes
|
|
@@ -301,11 +325,19 @@ var BehioStorefront = class {
|
|
|
301
325
|
}
|
|
302
326
|
/** Set auth tokens (e.g. from localStorage) */
|
|
303
327
|
setTokens(tokens) {
|
|
328
|
+
if (this.accessToken !== tokens.accessToken || this.refreshToken !== tokens.refreshToken) {
|
|
329
|
+
this.authContextVersion++;
|
|
330
|
+
this.requestContextVersion++;
|
|
331
|
+
}
|
|
304
332
|
this.accessToken = tokens.accessToken;
|
|
305
333
|
this.refreshToken = tokens.refreshToken;
|
|
306
334
|
}
|
|
307
335
|
/** Clear auth tokens */
|
|
308
336
|
clearTokens() {
|
|
337
|
+
if (this.accessToken || this.refreshToken) {
|
|
338
|
+
this.authContextVersion++;
|
|
339
|
+
this.requestContextVersion++;
|
|
340
|
+
}
|
|
309
341
|
this.accessToken = void 0;
|
|
310
342
|
this.refreshToken = void 0;
|
|
311
343
|
}
|
|
@@ -319,6 +351,7 @@ var BehioStorefront = class {
|
|
|
319
351
|
}
|
|
320
352
|
/** Set cart session token (e.g. from cookie) */
|
|
321
353
|
setCartSession(token) {
|
|
354
|
+
if (this.cartSession !== token) this.requestContextVersion++;
|
|
322
355
|
this.cartSession = token;
|
|
323
356
|
}
|
|
324
357
|
/** Get cart session token */
|
|
@@ -327,6 +360,7 @@ var BehioStorefront = class {
|
|
|
327
360
|
}
|
|
328
361
|
/** Clear cart session */
|
|
329
362
|
clearCartSession() {
|
|
363
|
+
if (this.cartSession) this.requestContextVersion++;
|
|
330
364
|
this.cartSession = void 0;
|
|
331
365
|
}
|
|
332
366
|
// --- Default currency / locale (runtime-switchable) ---
|
|
@@ -337,6 +371,7 @@ var BehioStorefront = class {
|
|
|
337
371
|
* (falls back to the shop's default currency server-side).
|
|
338
372
|
*/
|
|
339
373
|
setCurrency(currency) {
|
|
374
|
+
if (this.defaultCurrency !== (currency || void 0)) this.requestContextVersion++;
|
|
340
375
|
this.defaultCurrency = currency || void 0;
|
|
341
376
|
}
|
|
342
377
|
/** Get the current default currency, if any. */
|
|
@@ -346,13 +381,16 @@ var BehioStorefront = class {
|
|
|
346
381
|
/** Set the catalog's delivery country. Use cart.setDestination separately for the cart. */
|
|
347
382
|
setCountry(country) {
|
|
348
383
|
const normalized = country?.trim().toUpperCase();
|
|
349
|
-
|
|
384
|
+
const next = normalized && /^[A-Z]{2}$/.test(normalized) ? normalized : void 0;
|
|
385
|
+
if (this.defaultCountry !== next) this.requestContextVersion++;
|
|
386
|
+
this.defaultCountry = next;
|
|
350
387
|
}
|
|
351
388
|
getCountry() {
|
|
352
389
|
return this.defaultCountry;
|
|
353
390
|
}
|
|
354
391
|
/** Set the default locale sent on every catalog request (per-call wins). */
|
|
355
392
|
setLocale(locale) {
|
|
393
|
+
if (this.defaultLocale !== (locale || void 0)) this.requestContextVersion++;
|
|
356
394
|
this.defaultLocale = locale || void 0;
|
|
357
395
|
}
|
|
358
396
|
/** Get the current default locale, if any. */
|
|
@@ -408,18 +446,17 @@ var BehioStorefront = class {
|
|
|
408
446
|
return;
|
|
409
447
|
}
|
|
410
448
|
this.isRefreshing = true;
|
|
449
|
+
const authVersion = this.authContextVersion;
|
|
411
450
|
this.refreshPromise = (async () => {
|
|
412
451
|
try {
|
|
413
452
|
const res = await this.auth.refresh();
|
|
414
|
-
if (res.error)
|
|
453
|
+
if (res.error) throw new BehioApiError(res.error.status ?? 401, res.error.body, res.error.message);
|
|
454
|
+
if (this.authContextVersion === authVersion) this.emit("auth:token-refresh");
|
|
455
|
+
} catch (err2) {
|
|
456
|
+
if (this.authContextVersion === authVersion) {
|
|
415
457
|
this.clearTokens();
|
|
416
458
|
this.emit("auth:token-refresh-failed");
|
|
417
|
-
throw new BehioApiError(401, null, "Token refresh failed");
|
|
418
459
|
}
|
|
419
|
-
this.emit("auth:token-refresh");
|
|
420
|
-
} catch (err2) {
|
|
421
|
-
this.clearTokens();
|
|
422
|
-
this.emit("auth:token-refresh-failed");
|
|
423
460
|
if (err2 instanceof BehioApiError) throw err2;
|
|
424
461
|
throw new BehioApiError(401, null, "Token refresh failed");
|
|
425
462
|
} finally {
|
|
@@ -456,6 +493,7 @@ var BehioStorefront = class {
|
|
|
456
493
|
* @internal — use the typed module methods (behio.certificates.downloadPdf).
|
|
457
494
|
*/
|
|
458
495
|
async requestBlob(path) {
|
|
496
|
+
const authVersion = this.authContextVersion;
|
|
459
497
|
try {
|
|
460
498
|
const headers = { "X-Api-Key": this.apiKey };
|
|
461
499
|
if (this.accessToken)
|
|
@@ -471,7 +509,9 @@ var BehioStorefront = class {
|
|
|
471
509
|
}
|
|
472
510
|
throw new BehioApiError(res.status, body);
|
|
473
511
|
}
|
|
474
|
-
|
|
512
|
+
const blob = await res.blob();
|
|
513
|
+
this.assertRequestContext(authVersion, true);
|
|
514
|
+
return ok(blob);
|
|
475
515
|
} catch (err2) {
|
|
476
516
|
if (this.throwOnAvailabilityError && isAvailabilityFailure(err2)) {
|
|
477
517
|
throw err2;
|
|
@@ -485,6 +525,8 @@ var BehioStorefront = class {
|
|
|
485
525
|
* public callers must go through `request()` which returns Result.
|
|
486
526
|
*/
|
|
487
527
|
async rawRequest(method, path, options) {
|
|
528
|
+
const authOnly = path.startsWith("/auth/");
|
|
529
|
+
const requestVersion = authOnly ? this.authContextVersion : this.requestContextVersion;
|
|
488
530
|
const params = new URLSearchParams();
|
|
489
531
|
if (options?.query) {
|
|
490
532
|
for (const [key, value] of Object.entries(options.query)) {
|
|
@@ -550,6 +592,7 @@ var BehioStorefront = class {
|
|
|
550
592
|
}
|
|
551
593
|
this.emit("request", { method, path });
|
|
552
594
|
for (let attempt = 0; attempt <= this.retries; attempt++) {
|
|
595
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
553
596
|
const controller = new AbortController();
|
|
554
597
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
555
598
|
if (options?.signal) {
|
|
@@ -571,6 +614,7 @@ var BehioStorefront = class {
|
|
|
571
614
|
});
|
|
572
615
|
} catch (err2) {
|
|
573
616
|
clearTimeout(timeoutId);
|
|
617
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
574
618
|
const isAbort = err2 instanceof DOMException && err2.name === "AbortError";
|
|
575
619
|
const networkErr = new BehioNetworkError(
|
|
576
620
|
isAbort ? "Request timed out" : err2.message || "Network error",
|
|
@@ -587,6 +631,7 @@ var BehioStorefront = class {
|
|
|
587
631
|
} finally {
|
|
588
632
|
clearTimeout(timeoutId);
|
|
589
633
|
}
|
|
634
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
590
635
|
const remaining = res.headers.get("X-RateLimit-Remaining");
|
|
591
636
|
const reset = res.headers.get("X-RateLimit-Reset");
|
|
592
637
|
if (remaining) this.rateLimitRemaining = parseInt(remaining, 10);
|
|
@@ -600,6 +645,7 @@ var BehioStorefront = class {
|
|
|
600
645
|
this.emit("response", { method, path, status: res.status });
|
|
601
646
|
if (!res.ok) {
|
|
602
647
|
const body = await res.json().catch(() => null);
|
|
648
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
603
649
|
const apiError = new BehioApiError(
|
|
604
650
|
res.status,
|
|
605
651
|
body,
|
|
@@ -608,11 +654,13 @@ var BehioStorefront = class {
|
|
|
608
654
|
if (res.status === 401 && this.refreshToken && options?.auth !== false && !options?._isRetryAfterRefresh) {
|
|
609
655
|
try {
|
|
610
656
|
await this.handleTokenRefresh();
|
|
657
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
611
658
|
return this.rawRequest(method, path, {
|
|
612
659
|
...options,
|
|
613
660
|
_isRetryAfterRefresh: true
|
|
614
661
|
});
|
|
615
|
-
} catch {
|
|
662
|
+
} catch (error) {
|
|
663
|
+
if (error instanceof BehioApiError && error.status === 409) throw error;
|
|
616
664
|
this.emit("error", apiError);
|
|
617
665
|
throw apiError;
|
|
618
666
|
}
|
|
@@ -637,6 +685,7 @@ var BehioStorefront = class {
|
|
|
637
685
|
} catch {
|
|
638
686
|
}
|
|
639
687
|
}
|
|
688
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
640
689
|
return responseData;
|
|
641
690
|
}
|
|
642
691
|
throw new BehioNetworkError("Request failed after retries");
|
|
@@ -981,17 +1030,21 @@ var AuthModule = class {
|
|
|
981
1030
|
}
|
|
982
1031
|
};
|
|
983
1032
|
}
|
|
1033
|
+
const authVersion = this.client.getAuthContextVersion();
|
|
984
1034
|
const res = await this.client.request("POST", "/auth/refresh", {
|
|
985
1035
|
body: { refreshToken: token },
|
|
986
1036
|
auth: false
|
|
987
1037
|
});
|
|
988
1038
|
if (res.error) return res;
|
|
989
|
-
this.client.
|
|
1039
|
+
if (!this.client.acceptRefreshedTokens(res.data, authVersion)) {
|
|
1040
|
+
return { data: null, error: toSdkError(new BehioApiError(409, null, "The customer session changed.")) };
|
|
1041
|
+
}
|
|
990
1042
|
return res;
|
|
991
1043
|
}
|
|
992
1044
|
/** Logout (invalidate refresh token) */
|
|
993
1045
|
async logout(refreshToken) {
|
|
994
1046
|
const token = refreshToken || this.client.getRefreshToken();
|
|
1047
|
+
const authVersion = this.client.getAuthContextVersion();
|
|
995
1048
|
const res = await this.client.request(
|
|
996
1049
|
"POST",
|
|
997
1050
|
"/auth/logout",
|
|
@@ -999,8 +1052,10 @@ var AuthModule = class {
|
|
|
999
1052
|
body: { refreshToken: token }
|
|
1000
1053
|
}
|
|
1001
1054
|
);
|
|
1002
|
-
this.client.
|
|
1003
|
-
|
|
1055
|
+
if (this.client.getAuthContextVersion() === authVersion) {
|
|
1056
|
+
this.client.clearTokens();
|
|
1057
|
+
this.client.emit("auth:logout");
|
|
1058
|
+
}
|
|
1004
1059
|
return res;
|
|
1005
1060
|
}
|
|
1006
1061
|
/** Request password reset email */
|
|
@@ -165,6 +165,8 @@ var BehioStorefront = class {
|
|
|
165
165
|
// Token refresh lock
|
|
166
166
|
this.isRefreshing = false;
|
|
167
167
|
this.refreshPromise = null;
|
|
168
|
+
this.requestContextVersion = 0;
|
|
169
|
+
this.authContextVersion = 0;
|
|
168
170
|
// Event emitter
|
|
169
171
|
this.listeners = /* @__PURE__ */ new Map();
|
|
170
172
|
// Interceptors
|
|
@@ -208,6 +210,28 @@ var BehioStorefront = class {
|
|
|
208
210
|
this.subscriptions = new SubscriptionsModule(this);
|
|
209
211
|
this.certificates = new CourseCertificatesModule(this);
|
|
210
212
|
}
|
|
213
|
+
/** @internal Opaque generation, never a token or customer identifier. */
|
|
214
|
+
getRequestContextVersion() {
|
|
215
|
+
return this.requestContextVersion;
|
|
216
|
+
}
|
|
217
|
+
/** @internal Refreshes must not restore a session that has been replaced. */
|
|
218
|
+
getAuthContextVersion() {
|
|
219
|
+
return this.authContextVersion;
|
|
220
|
+
}
|
|
221
|
+
/** @internal A refresh rotates credentials within the same customer session. */
|
|
222
|
+
acceptRefreshedTokens(tokens, expectedVersion) {
|
|
223
|
+
if (this.authContextVersion !== expectedVersion) return false;
|
|
224
|
+
if (!this.accessToken) this.setTokens(tokens);
|
|
225
|
+
else {
|
|
226
|
+
this.accessToken = tokens.accessToken;
|
|
227
|
+
this.refreshToken = tokens.refreshToken;
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
/** @internal An obsolete response must not update cache, session or retries. */
|
|
232
|
+
assertRequestContext(version, authOnly = false) {
|
|
233
|
+
if (version !== (authOnly ? this.authContextVersion : this.requestContextVersion)) throw new BehioApiError(409, null, "The storefront session or pricing context changed. Please retry in the current context.");
|
|
234
|
+
}
|
|
211
235
|
// --- Public methods ---
|
|
212
236
|
/**
|
|
213
237
|
* Called by the analytics tracker when the visitor grants (id) or revokes
|
|
@@ -301,11 +325,19 @@ var BehioStorefront = class {
|
|
|
301
325
|
}
|
|
302
326
|
/** Set auth tokens (e.g. from localStorage) */
|
|
303
327
|
setTokens(tokens) {
|
|
328
|
+
if (this.accessToken !== tokens.accessToken || this.refreshToken !== tokens.refreshToken) {
|
|
329
|
+
this.authContextVersion++;
|
|
330
|
+
this.requestContextVersion++;
|
|
331
|
+
}
|
|
304
332
|
this.accessToken = tokens.accessToken;
|
|
305
333
|
this.refreshToken = tokens.refreshToken;
|
|
306
334
|
}
|
|
307
335
|
/** Clear auth tokens */
|
|
308
336
|
clearTokens() {
|
|
337
|
+
if (this.accessToken || this.refreshToken) {
|
|
338
|
+
this.authContextVersion++;
|
|
339
|
+
this.requestContextVersion++;
|
|
340
|
+
}
|
|
309
341
|
this.accessToken = void 0;
|
|
310
342
|
this.refreshToken = void 0;
|
|
311
343
|
}
|
|
@@ -319,6 +351,7 @@ var BehioStorefront = class {
|
|
|
319
351
|
}
|
|
320
352
|
/** Set cart session token (e.g. from cookie) */
|
|
321
353
|
setCartSession(token) {
|
|
354
|
+
if (this.cartSession !== token) this.requestContextVersion++;
|
|
322
355
|
this.cartSession = token;
|
|
323
356
|
}
|
|
324
357
|
/** Get cart session token */
|
|
@@ -327,6 +360,7 @@ var BehioStorefront = class {
|
|
|
327
360
|
}
|
|
328
361
|
/** Clear cart session */
|
|
329
362
|
clearCartSession() {
|
|
363
|
+
if (this.cartSession) this.requestContextVersion++;
|
|
330
364
|
this.cartSession = void 0;
|
|
331
365
|
}
|
|
332
366
|
// --- Default currency / locale (runtime-switchable) ---
|
|
@@ -337,6 +371,7 @@ var BehioStorefront = class {
|
|
|
337
371
|
* (falls back to the shop's default currency server-side).
|
|
338
372
|
*/
|
|
339
373
|
setCurrency(currency) {
|
|
374
|
+
if (this.defaultCurrency !== (currency || void 0)) this.requestContextVersion++;
|
|
340
375
|
this.defaultCurrency = currency || void 0;
|
|
341
376
|
}
|
|
342
377
|
/** Get the current default currency, if any. */
|
|
@@ -346,13 +381,16 @@ var BehioStorefront = class {
|
|
|
346
381
|
/** Set the catalog's delivery country. Use cart.setDestination separately for the cart. */
|
|
347
382
|
setCountry(country) {
|
|
348
383
|
const normalized = _optionalChain([country, 'optionalAccess', _3 => _3.trim, 'call', _4 => _4(), 'access', _5 => _5.toUpperCase, 'call', _6 => _6()]);
|
|
349
|
-
|
|
384
|
+
const next = normalized && /^[A-Z]{2}$/.test(normalized) ? normalized : void 0;
|
|
385
|
+
if (this.defaultCountry !== next) this.requestContextVersion++;
|
|
386
|
+
this.defaultCountry = next;
|
|
350
387
|
}
|
|
351
388
|
getCountry() {
|
|
352
389
|
return this.defaultCountry;
|
|
353
390
|
}
|
|
354
391
|
/** Set the default locale sent on every catalog request (per-call wins). */
|
|
355
392
|
setLocale(locale) {
|
|
393
|
+
if (this.defaultLocale !== (locale || void 0)) this.requestContextVersion++;
|
|
356
394
|
this.defaultLocale = locale || void 0;
|
|
357
395
|
}
|
|
358
396
|
/** Get the current default locale, if any. */
|
|
@@ -408,18 +446,17 @@ var BehioStorefront = class {
|
|
|
408
446
|
return;
|
|
409
447
|
}
|
|
410
448
|
this.isRefreshing = true;
|
|
449
|
+
const authVersion = this.authContextVersion;
|
|
411
450
|
this.refreshPromise = (async () => {
|
|
412
451
|
try {
|
|
413
452
|
const res = await this.auth.refresh();
|
|
414
|
-
if (res.error)
|
|
453
|
+
if (res.error) throw new BehioApiError(_nullishCoalesce(res.error.status, () => ( 401)), res.error.body, res.error.message);
|
|
454
|
+
if (this.authContextVersion === authVersion) this.emit("auth:token-refresh");
|
|
455
|
+
} catch (err2) {
|
|
456
|
+
if (this.authContextVersion === authVersion) {
|
|
415
457
|
this.clearTokens();
|
|
416
458
|
this.emit("auth:token-refresh-failed");
|
|
417
|
-
throw new BehioApiError(401, null, "Token refresh failed");
|
|
418
459
|
}
|
|
419
|
-
this.emit("auth:token-refresh");
|
|
420
|
-
} catch (err2) {
|
|
421
|
-
this.clearTokens();
|
|
422
|
-
this.emit("auth:token-refresh-failed");
|
|
423
460
|
if (err2 instanceof BehioApiError) throw err2;
|
|
424
461
|
throw new BehioApiError(401, null, "Token refresh failed");
|
|
425
462
|
} finally {
|
|
@@ -456,6 +493,7 @@ var BehioStorefront = class {
|
|
|
456
493
|
* @internal — use the typed module methods (behio.certificates.downloadPdf).
|
|
457
494
|
*/
|
|
458
495
|
async requestBlob(path) {
|
|
496
|
+
const authVersion = this.authContextVersion;
|
|
459
497
|
try {
|
|
460
498
|
const headers = { "X-Api-Key": this.apiKey };
|
|
461
499
|
if (this.accessToken)
|
|
@@ -471,7 +509,9 @@ var BehioStorefront = class {
|
|
|
471
509
|
}
|
|
472
510
|
throw new BehioApiError(res.status, body);
|
|
473
511
|
}
|
|
474
|
-
|
|
512
|
+
const blob = await res.blob();
|
|
513
|
+
this.assertRequestContext(authVersion, true);
|
|
514
|
+
return ok(blob);
|
|
475
515
|
} catch (err2) {
|
|
476
516
|
if (this.throwOnAvailabilityError && isAvailabilityFailure(err2)) {
|
|
477
517
|
throw err2;
|
|
@@ -485,6 +525,8 @@ var BehioStorefront = class {
|
|
|
485
525
|
* public callers must go through `request()` which returns Result.
|
|
486
526
|
*/
|
|
487
527
|
async rawRequest(method, path, options) {
|
|
528
|
+
const authOnly = path.startsWith("/auth/");
|
|
529
|
+
const requestVersion = authOnly ? this.authContextVersion : this.requestContextVersion;
|
|
488
530
|
const params = new URLSearchParams();
|
|
489
531
|
if (_optionalChain([options, 'optionalAccess', _17 => _17.query])) {
|
|
490
532
|
for (const [key, value] of Object.entries(options.query)) {
|
|
@@ -550,6 +592,7 @@ var BehioStorefront = class {
|
|
|
550
592
|
}
|
|
551
593
|
this.emit("request", { method, path });
|
|
552
594
|
for (let attempt = 0; attempt <= this.retries; attempt++) {
|
|
595
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
553
596
|
const controller = new AbortController();
|
|
554
597
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
555
598
|
if (_optionalChain([options, 'optionalAccess', _21 => _21.signal])) {
|
|
@@ -571,6 +614,7 @@ var BehioStorefront = class {
|
|
|
571
614
|
});
|
|
572
615
|
} catch (err2) {
|
|
573
616
|
clearTimeout(timeoutId);
|
|
617
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
574
618
|
const isAbort = err2 instanceof DOMException && err2.name === "AbortError";
|
|
575
619
|
const networkErr = new BehioNetworkError(
|
|
576
620
|
isAbort ? "Request timed out" : err2.message || "Network error",
|
|
@@ -587,6 +631,7 @@ var BehioStorefront = class {
|
|
|
587
631
|
} finally {
|
|
588
632
|
clearTimeout(timeoutId);
|
|
589
633
|
}
|
|
634
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
590
635
|
const remaining = res.headers.get("X-RateLimit-Remaining");
|
|
591
636
|
const reset = res.headers.get("X-RateLimit-Reset");
|
|
592
637
|
if (remaining) this.rateLimitRemaining = parseInt(remaining, 10);
|
|
@@ -600,6 +645,7 @@ var BehioStorefront = class {
|
|
|
600
645
|
this.emit("response", { method, path, status: res.status });
|
|
601
646
|
if (!res.ok) {
|
|
602
647
|
const body = await res.json().catch(() => null);
|
|
648
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
603
649
|
const apiError = new BehioApiError(
|
|
604
650
|
res.status,
|
|
605
651
|
body,
|
|
@@ -608,11 +654,13 @@ var BehioStorefront = class {
|
|
|
608
654
|
if (res.status === 401 && this.refreshToken && _optionalChain([options, 'optionalAccess', _23 => _23.auth]) !== false && !_optionalChain([options, 'optionalAccess', _24 => _24._isRetryAfterRefresh])) {
|
|
609
655
|
try {
|
|
610
656
|
await this.handleTokenRefresh();
|
|
657
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
611
658
|
return this.rawRequest(method, path, {
|
|
612
659
|
...options,
|
|
613
660
|
_isRetryAfterRefresh: true
|
|
614
661
|
});
|
|
615
|
-
} catch (
|
|
662
|
+
} catch (error) {
|
|
663
|
+
if (error instanceof BehioApiError && error.status === 409) throw error;
|
|
616
664
|
this.emit("error", apiError);
|
|
617
665
|
throw apiError;
|
|
618
666
|
}
|
|
@@ -634,9 +682,10 @@ var BehioStorefront = class {
|
|
|
634
682
|
data: responseData,
|
|
635
683
|
headers: res.headers
|
|
636
684
|
});
|
|
637
|
-
} catch (
|
|
685
|
+
} catch (e5) {
|
|
638
686
|
}
|
|
639
687
|
}
|
|
688
|
+
this.assertRequestContext(requestVersion, authOnly);
|
|
640
689
|
return responseData;
|
|
641
690
|
}
|
|
642
691
|
throw new BehioNetworkError("Request failed after retries");
|
|
@@ -981,17 +1030,21 @@ var AuthModule = class {
|
|
|
981
1030
|
}
|
|
982
1031
|
};
|
|
983
1032
|
}
|
|
1033
|
+
const authVersion = this.client.getAuthContextVersion();
|
|
984
1034
|
const res = await this.client.request("POST", "/auth/refresh", {
|
|
985
1035
|
body: { refreshToken: token },
|
|
986
1036
|
auth: false
|
|
987
1037
|
});
|
|
988
1038
|
if (res.error) return res;
|
|
989
|
-
this.client.
|
|
1039
|
+
if (!this.client.acceptRefreshedTokens(res.data, authVersion)) {
|
|
1040
|
+
return { data: null, error: toSdkError(new BehioApiError(409, null, "The customer session changed.")) };
|
|
1041
|
+
}
|
|
990
1042
|
return res;
|
|
991
1043
|
}
|
|
992
1044
|
/** Logout (invalidate refresh token) */
|
|
993
1045
|
async logout(refreshToken) {
|
|
994
1046
|
const token = refreshToken || this.client.getRefreshToken();
|
|
1047
|
+
const authVersion = this.client.getAuthContextVersion();
|
|
995
1048
|
const res = await this.client.request(
|
|
996
1049
|
"POST",
|
|
997
1050
|
"/auth/logout",
|
|
@@ -999,8 +1052,10 @@ var AuthModule = class {
|
|
|
999
1052
|
body: { refreshToken: token }
|
|
1000
1053
|
}
|
|
1001
1054
|
);
|
|
1002
|
-
this.client.
|
|
1003
|
-
|
|
1055
|
+
if (this.client.getAuthContextVersion() === authVersion) {
|
|
1056
|
+
this.client.clearTokens();
|
|
1057
|
+
this.client.emit("auth:logout");
|
|
1058
|
+
}
|
|
1004
1059
|
return res;
|
|
1005
1060
|
}
|
|
1006
1061
|
/** Request password reset email */
|
|
@@ -2837,6 +2837,19 @@ declare class BehioStorefront {
|
|
|
2837
2837
|
private isRefreshing;
|
|
2838
2838
|
private refreshPromise;
|
|
2839
2839
|
private cartSession?;
|
|
2840
|
+
private requestContextVersion;
|
|
2841
|
+
private authContextVersion;
|
|
2842
|
+
/** @internal Opaque generation, never a token or customer identifier. */
|
|
2843
|
+
getRequestContextVersion(): number;
|
|
2844
|
+
/** @internal Refreshes must not restore a session that has been replaced. */
|
|
2845
|
+
getAuthContextVersion(): number;
|
|
2846
|
+
/** @internal A refresh rotates credentials within the same customer session. */
|
|
2847
|
+
acceptRefreshedTokens(tokens: {
|
|
2848
|
+
accessToken: string;
|
|
2849
|
+
refreshToken: string;
|
|
2850
|
+
}, expectedVersion: number): boolean;
|
|
2851
|
+
/** @internal An obsolete response must not update cache, session or retries. */
|
|
2852
|
+
assertRequestContext(version: number, authOnly?: boolean): void;
|
|
2840
2853
|
private listeners;
|
|
2841
2854
|
private requestInterceptors;
|
|
2842
2855
|
private responseInterceptors;
|
|
@@ -2837,6 +2837,19 @@ declare class BehioStorefront {
|
|
|
2837
2837
|
private isRefreshing;
|
|
2838
2838
|
private refreshPromise;
|
|
2839
2839
|
private cartSession?;
|
|
2840
|
+
private requestContextVersion;
|
|
2841
|
+
private authContextVersion;
|
|
2842
|
+
/** @internal Opaque generation, never a token or customer identifier. */
|
|
2843
|
+
getRequestContextVersion(): number;
|
|
2844
|
+
/** @internal Refreshes must not restore a session that has been replaced. */
|
|
2845
|
+
getAuthContextVersion(): number;
|
|
2846
|
+
/** @internal A refresh rotates credentials within the same customer session. */
|
|
2847
|
+
acceptRefreshedTokens(tokens: {
|
|
2848
|
+
accessToken: string;
|
|
2849
|
+
refreshToken: string;
|
|
2850
|
+
}, expectedVersion: number): boolean;
|
|
2851
|
+
/** @internal An obsolete response must not update cache, session or retries. */
|
|
2852
|
+
assertRequestContext(version: number, authOnly?: boolean): void;
|
|
2840
2853
|
private listeners;
|
|
2841
2854
|
private requestInterceptors;
|
|
2842
2855
|
private responseInterceptors;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent, b as StorefrontFormFieldError } from './client-
|
|
2
|
-
export { A as ActivePromotion, c as AddToCartInput, d as AddressDetail, e as AddressSuggestion, f as AddressType, g as AddressTypes, h as AuthTokens, i as BackInStockSubscription, j as BadgeTone, k as BehioApiError, l as BehioErrorCode, m as BehioEventHandler, n as BehioEventType, o as BehioNetworkError, p as BehioStorefrontConfig, q as Blog, r as BlogPostDetail, s as BlogPostListItem, t as BlogPostsPage, u as BlogPostsQuery, v as BlogSettings, w as BlogTag, x as Bundle, y as BundleCatalogQuery, z as BundleItem, D as Cart, E as CartBundleLine, F as CartBundleLineItem, G as CartDiscount, H as CartItem, I as CartItemProduct, J as CartPromotion, K as Category, L as CategoryDetail, M as CertificateVerification, N as CheckoutAddress, O as CheckoutInput, Q as CheckoutPaymentMethod, R as CheckoutPreview, T as CheckoutResult, U as CheckoutSettings, V as CookieConsentInput, W as CourseAttachment, X as CourseCertificate, Y as CourseComment, Z as CourseCommentReply, _ as CourseCommentsList, $ as CourseDetail, a0 as CourseLesson, a1 as CourseListItem, a2 as CourseModule, a3 as CoursePostedComment, a4 as CourseProgress, a5 as CourseTutorMessage, a6 as CourseTutorThread, a7 as CrossSellItem, a8 as CurrencyDisplayFormat, a9 as CustomerAddress, aa as CustomerProfile, ab as DigitalDownload, ac as DownloadUrl, ad as Facet, ae as FacetAvailability, af as FacetCategory, ag as FacetLabel, ah as FacetPriceRange, ai as FacetRange, aj as FacetRatingBucket, ak as FacetValue, al as FacetsResponse, am as FilterField, an as FulfillmentStatus, ao as FulfillmentStatuses, ap as GiftCardBalance, aq as GiftCardPurchaseInput, ar as GiftCardPurchaseResult, as as GiftCardSummary, at as LessonNote, au as LessonQuiz, av as LoginInput, aw as LoyaltyBalance, ax as LoyaltyNextTier, ay as LoyaltyProgram, az as LoyaltySummary, aA as LoyaltyTier, aB as LoyaltyTierPerks, aC as LoyaltyTransaction, aD as Menu, aE as MenuItem, aF as MenuItemRef, aG as MenuItemType, aH as MessageResponse, aI as NewsletterOptInDefault, aJ as NewsletterSubscribeInput, aK as NewsletterSubscribeResult, aL as NewsletterUnsubscribeResult, aM as OrderAccessRequestResponse, aN as OrderAccessVerifyResponse, aO as OrderDetail, aP as OrderItem, aQ as OrderListItem, aR as OrderStatus, aS as OrderStatusHistory, aT as OrderStatuses, aU as OrderTracking, aV as Page, aW as PageAttachment, aX as PageDetail, aY as PaginatedResponse, aZ as PaymentInstrument, a_ as PaymentStatus, a$ as PaymentStatuses, b0 as PaymentSwift, b1 as PickupPoint, b2 as PickupPointHours, b3 as PickupPointsInput, b4 as PickupWidgetConfig, b5 as PriceDisplay, b6 as ProductAssetGroup, b7 as ProductAssetItem, b8 as ProductAvailability, b9 as ProductGroup, ba as ProductLabel, bb as ProductListItem, bc as ProductMedia, bd as ProductMediaVariant, be as ProductParameter, bf as ProductParameterGroup, bg as ProductParametersResponse, bh as ProductPrice, bi as ProductPromotionSummary, bj as ProductReview, bk as ProductReviewsResponse, bl as ProductSibling, bm as ProductSort, bn as ProductSortValue, bo as ProductVolumePrice, bp as ProductsQuery, bq as QuizAnswerInput, br as QuizAnswerResult, bs as QuizQuestion, bt as QuizResult, bu as QuoteItem, bv as QuoteRequest, bw as RegisterInput, bx as RegisterResult, by as RequestInterceptor, bz as RequestInterceptorConfig, bA as ResponseInterceptor, bB as ResponseInterceptorData, bC as ReturnRequest, bD as ReturnRequestItem, bE as ReturnStatus, bF as ReturnStatusItem, bG as ReturnableOrder, bH as ReturnableOrderItem, bI as SdkError, bJ as ShippingMethodSummary, bK as ShippingQuote, bL as ShippingQuoteInput, bM as ShopAppearance, bN as ShopInfo, bO as ShopScript, bP as ShopScriptPlacement, bQ as ShopScriptType, bR as ShopScripts, bS as ShopSeo, bT as ShopSeoIdentity, bU as SiteFormField, bV as SiteFormFieldOption, bW as SiteFormFieldType, bX as Sitemap, bY as SitemapEntry, bZ as StockBehavior, b_ as StockMode, b$ as StorefrontForm, c0 as StorefrontFormFieldErrorCode, c1 as StorefrontFormSettings, c2 as StorefrontFormSubmitInput, c3 as StorefrontFormSubmitResult, c4 as SubmitQuoteInput, c5 as SubmitReturnInput, c6 as SubmitReviewInput, c7 as Subscription, c8 as SubscriptionAction, c9 as SubscriptionFrequency, ca as SubscriptionItem, cb as SubscriptionStatus, cc as TaxBreakdownLine, cd as VariantAxis, ce as VariantAxisValue, cf as WishlistItem, cg as err, ch as ok, ci as toSdkError } from './client-
|
|
1
|
+
import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent, b as StorefrontFormFieldError } from './client-Gf4MBpav.mjs';
|
|
2
|
+
export { A as ActivePromotion, c as AddToCartInput, d as AddressDetail, e as AddressSuggestion, f as AddressType, g as AddressTypes, h as AuthTokens, i as BackInStockSubscription, j as BadgeTone, k as BehioApiError, l as BehioErrorCode, m as BehioEventHandler, n as BehioEventType, o as BehioNetworkError, p as BehioStorefrontConfig, q as Blog, r as BlogPostDetail, s as BlogPostListItem, t as BlogPostsPage, u as BlogPostsQuery, v as BlogSettings, w as BlogTag, x as Bundle, y as BundleCatalogQuery, z as BundleItem, D as Cart, E as CartBundleLine, F as CartBundleLineItem, G as CartDiscount, H as CartItem, I as CartItemProduct, J as CartPromotion, K as Category, L as CategoryDetail, M as CertificateVerification, N as CheckoutAddress, O as CheckoutInput, Q as CheckoutPaymentMethod, R as CheckoutPreview, T as CheckoutResult, U as CheckoutSettings, V as CookieConsentInput, W as CourseAttachment, X as CourseCertificate, Y as CourseComment, Z as CourseCommentReply, _ as CourseCommentsList, $ as CourseDetail, a0 as CourseLesson, a1 as CourseListItem, a2 as CourseModule, a3 as CoursePostedComment, a4 as CourseProgress, a5 as CourseTutorMessage, a6 as CourseTutorThread, a7 as CrossSellItem, a8 as CurrencyDisplayFormat, a9 as CustomerAddress, aa as CustomerProfile, ab as DigitalDownload, ac as DownloadUrl, ad as Facet, ae as FacetAvailability, af as FacetCategory, ag as FacetLabel, ah as FacetPriceRange, ai as FacetRange, aj as FacetRatingBucket, ak as FacetValue, al as FacetsResponse, am as FilterField, an as FulfillmentStatus, ao as FulfillmentStatuses, ap as GiftCardBalance, aq as GiftCardPurchaseInput, ar as GiftCardPurchaseResult, as as GiftCardSummary, at as LessonNote, au as LessonQuiz, av as LoginInput, aw as LoyaltyBalance, ax as LoyaltyNextTier, ay as LoyaltyProgram, az as LoyaltySummary, aA as LoyaltyTier, aB as LoyaltyTierPerks, aC as LoyaltyTransaction, aD as Menu, aE as MenuItem, aF as MenuItemRef, aG as MenuItemType, aH as MessageResponse, aI as NewsletterOptInDefault, aJ as NewsletterSubscribeInput, aK as NewsletterSubscribeResult, aL as NewsletterUnsubscribeResult, aM as OrderAccessRequestResponse, aN as OrderAccessVerifyResponse, aO as OrderDetail, aP as OrderItem, aQ as OrderListItem, aR as OrderStatus, aS as OrderStatusHistory, aT as OrderStatuses, aU as OrderTracking, aV as Page, aW as PageAttachment, aX as PageDetail, aY as PaginatedResponse, aZ as PaymentInstrument, a_ as PaymentStatus, a$ as PaymentStatuses, b0 as PaymentSwift, b1 as PickupPoint, b2 as PickupPointHours, b3 as PickupPointsInput, b4 as PickupWidgetConfig, b5 as PriceDisplay, b6 as ProductAssetGroup, b7 as ProductAssetItem, b8 as ProductAvailability, b9 as ProductGroup, ba as ProductLabel, bb as ProductListItem, bc as ProductMedia, bd as ProductMediaVariant, be as ProductParameter, bf as ProductParameterGroup, bg as ProductParametersResponse, bh as ProductPrice, bi as ProductPromotionSummary, bj as ProductReview, bk as ProductReviewsResponse, bl as ProductSibling, bm as ProductSort, bn as ProductSortValue, bo as ProductVolumePrice, bp as ProductsQuery, bq as QuizAnswerInput, br as QuizAnswerResult, bs as QuizQuestion, bt as QuizResult, bu as QuoteItem, bv as QuoteRequest, bw as RegisterInput, bx as RegisterResult, by as RequestInterceptor, bz as RequestInterceptorConfig, bA as ResponseInterceptor, bB as ResponseInterceptorData, bC as ReturnRequest, bD as ReturnRequestItem, bE as ReturnStatus, bF as ReturnStatusItem, bG as ReturnableOrder, bH as ReturnableOrderItem, bI as SdkError, bJ as ShippingMethodSummary, bK as ShippingQuote, bL as ShippingQuoteInput, bM as ShopAppearance, bN as ShopInfo, bO as ShopScript, bP as ShopScriptPlacement, bQ as ShopScriptType, bR as ShopScripts, bS as ShopSeo, bT as ShopSeoIdentity, bU as SiteFormField, bV as SiteFormFieldOption, bW as SiteFormFieldType, bX as Sitemap, bY as SitemapEntry, bZ as StockBehavior, b_ as StockMode, b$ as StorefrontForm, c0 as StorefrontFormFieldErrorCode, c1 as StorefrontFormSettings, c2 as StorefrontFormSubmitInput, c3 as StorefrontFormSubmitResult, c4 as SubmitQuoteInput, c5 as SubmitReturnInput, c6 as SubmitReviewInput, c7 as Subscription, c8 as SubscriptionAction, c9 as SubscriptionFrequency, ca as SubscriptionItem, cb as SubscriptionStatus, cc as TaxBreakdownLine, cd as VariantAxis, ce as VariantAxisValue, cf as WishlistItem, cg as err, ch as ok, ci as toSdkError } from './client-Gf4MBpav.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Format a price amount with currency using Intl.NumberFormat.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent, b as StorefrontFormFieldError } from './client-
|
|
2
|
-
export { A as ActivePromotion, c as AddToCartInput, d as AddressDetail, e as AddressSuggestion, f as AddressType, g as AddressTypes, h as AuthTokens, i as BackInStockSubscription, j as BadgeTone, k as BehioApiError, l as BehioErrorCode, m as BehioEventHandler, n as BehioEventType, o as BehioNetworkError, p as BehioStorefrontConfig, q as Blog, r as BlogPostDetail, s as BlogPostListItem, t as BlogPostsPage, u as BlogPostsQuery, v as BlogSettings, w as BlogTag, x as Bundle, y as BundleCatalogQuery, z as BundleItem, D as Cart, E as CartBundleLine, F as CartBundleLineItem, G as CartDiscount, H as CartItem, I as CartItemProduct, J as CartPromotion, K as Category, L as CategoryDetail, M as CertificateVerification, N as CheckoutAddress, O as CheckoutInput, Q as CheckoutPaymentMethod, R as CheckoutPreview, T as CheckoutResult, U as CheckoutSettings, V as CookieConsentInput, W as CourseAttachment, X as CourseCertificate, Y as CourseComment, Z as CourseCommentReply, _ as CourseCommentsList, $ as CourseDetail, a0 as CourseLesson, a1 as CourseListItem, a2 as CourseModule, a3 as CoursePostedComment, a4 as CourseProgress, a5 as CourseTutorMessage, a6 as CourseTutorThread, a7 as CrossSellItem, a8 as CurrencyDisplayFormat, a9 as CustomerAddress, aa as CustomerProfile, ab as DigitalDownload, ac as DownloadUrl, ad as Facet, ae as FacetAvailability, af as FacetCategory, ag as FacetLabel, ah as FacetPriceRange, ai as FacetRange, aj as FacetRatingBucket, ak as FacetValue, al as FacetsResponse, am as FilterField, an as FulfillmentStatus, ao as FulfillmentStatuses, ap as GiftCardBalance, aq as GiftCardPurchaseInput, ar as GiftCardPurchaseResult, as as GiftCardSummary, at as LessonNote, au as LessonQuiz, av as LoginInput, aw as LoyaltyBalance, ax as LoyaltyNextTier, ay as LoyaltyProgram, az as LoyaltySummary, aA as LoyaltyTier, aB as LoyaltyTierPerks, aC as LoyaltyTransaction, aD as Menu, aE as MenuItem, aF as MenuItemRef, aG as MenuItemType, aH as MessageResponse, aI as NewsletterOptInDefault, aJ as NewsletterSubscribeInput, aK as NewsletterSubscribeResult, aL as NewsletterUnsubscribeResult, aM as OrderAccessRequestResponse, aN as OrderAccessVerifyResponse, aO as OrderDetail, aP as OrderItem, aQ as OrderListItem, aR as OrderStatus, aS as OrderStatusHistory, aT as OrderStatuses, aU as OrderTracking, aV as Page, aW as PageAttachment, aX as PageDetail, aY as PaginatedResponse, aZ as PaymentInstrument, a_ as PaymentStatus, a$ as PaymentStatuses, b0 as PaymentSwift, b1 as PickupPoint, b2 as PickupPointHours, b3 as PickupPointsInput, b4 as PickupWidgetConfig, b5 as PriceDisplay, b6 as ProductAssetGroup, b7 as ProductAssetItem, b8 as ProductAvailability, b9 as ProductGroup, ba as ProductLabel, bb as ProductListItem, bc as ProductMedia, bd as ProductMediaVariant, be as ProductParameter, bf as ProductParameterGroup, bg as ProductParametersResponse, bh as ProductPrice, bi as ProductPromotionSummary, bj as ProductReview, bk as ProductReviewsResponse, bl as ProductSibling, bm as ProductSort, bn as ProductSortValue, bo as ProductVolumePrice, bp as ProductsQuery, bq as QuizAnswerInput, br as QuizAnswerResult, bs as QuizQuestion, bt as QuizResult, bu as QuoteItem, bv as QuoteRequest, bw as RegisterInput, bx as RegisterResult, by as RequestInterceptor, bz as RequestInterceptorConfig, bA as ResponseInterceptor, bB as ResponseInterceptorData, bC as ReturnRequest, bD as ReturnRequestItem, bE as ReturnStatus, bF as ReturnStatusItem, bG as ReturnableOrder, bH as ReturnableOrderItem, bI as SdkError, bJ as ShippingMethodSummary, bK as ShippingQuote, bL as ShippingQuoteInput, bM as ShopAppearance, bN as ShopInfo, bO as ShopScript, bP as ShopScriptPlacement, bQ as ShopScriptType, bR as ShopScripts, bS as ShopSeo, bT as ShopSeoIdentity, bU as SiteFormField, bV as SiteFormFieldOption, bW as SiteFormFieldType, bX as Sitemap, bY as SitemapEntry, bZ as StockBehavior, b_ as StockMode, b$ as StorefrontForm, c0 as StorefrontFormFieldErrorCode, c1 as StorefrontFormSettings, c2 as StorefrontFormSubmitInput, c3 as StorefrontFormSubmitResult, c4 as SubmitQuoteInput, c5 as SubmitReturnInput, c6 as SubmitReviewInput, c7 as Subscription, c8 as SubscriptionAction, c9 as SubscriptionFrequency, ca as SubscriptionItem, cb as SubscriptionStatus, cc as TaxBreakdownLine, cd as VariantAxis, ce as VariantAxisValue, cf as WishlistItem, cg as err, ch as ok, ci as toSdkError } from './client-
|
|
1
|
+
import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent, b as StorefrontFormFieldError } from './client-Gf4MBpav.js';
|
|
2
|
+
export { A as ActivePromotion, c as AddToCartInput, d as AddressDetail, e as AddressSuggestion, f as AddressType, g as AddressTypes, h as AuthTokens, i as BackInStockSubscription, j as BadgeTone, k as BehioApiError, l as BehioErrorCode, m as BehioEventHandler, n as BehioEventType, o as BehioNetworkError, p as BehioStorefrontConfig, q as Blog, r as BlogPostDetail, s as BlogPostListItem, t as BlogPostsPage, u as BlogPostsQuery, v as BlogSettings, w as BlogTag, x as Bundle, y as BundleCatalogQuery, z as BundleItem, D as Cart, E as CartBundleLine, F as CartBundleLineItem, G as CartDiscount, H as CartItem, I as CartItemProduct, J as CartPromotion, K as Category, L as CategoryDetail, M as CertificateVerification, N as CheckoutAddress, O as CheckoutInput, Q as CheckoutPaymentMethod, R as CheckoutPreview, T as CheckoutResult, U as CheckoutSettings, V as CookieConsentInput, W as CourseAttachment, X as CourseCertificate, Y as CourseComment, Z as CourseCommentReply, _ as CourseCommentsList, $ as CourseDetail, a0 as CourseLesson, a1 as CourseListItem, a2 as CourseModule, a3 as CoursePostedComment, a4 as CourseProgress, a5 as CourseTutorMessage, a6 as CourseTutorThread, a7 as CrossSellItem, a8 as CurrencyDisplayFormat, a9 as CustomerAddress, aa as CustomerProfile, ab as DigitalDownload, ac as DownloadUrl, ad as Facet, ae as FacetAvailability, af as FacetCategory, ag as FacetLabel, ah as FacetPriceRange, ai as FacetRange, aj as FacetRatingBucket, ak as FacetValue, al as FacetsResponse, am as FilterField, an as FulfillmentStatus, ao as FulfillmentStatuses, ap as GiftCardBalance, aq as GiftCardPurchaseInput, ar as GiftCardPurchaseResult, as as GiftCardSummary, at as LessonNote, au as LessonQuiz, av as LoginInput, aw as LoyaltyBalance, ax as LoyaltyNextTier, ay as LoyaltyProgram, az as LoyaltySummary, aA as LoyaltyTier, aB as LoyaltyTierPerks, aC as LoyaltyTransaction, aD as Menu, aE as MenuItem, aF as MenuItemRef, aG as MenuItemType, aH as MessageResponse, aI as NewsletterOptInDefault, aJ as NewsletterSubscribeInput, aK as NewsletterSubscribeResult, aL as NewsletterUnsubscribeResult, aM as OrderAccessRequestResponse, aN as OrderAccessVerifyResponse, aO as OrderDetail, aP as OrderItem, aQ as OrderListItem, aR as OrderStatus, aS as OrderStatusHistory, aT as OrderStatuses, aU as OrderTracking, aV as Page, aW as PageAttachment, aX as PageDetail, aY as PaginatedResponse, aZ as PaymentInstrument, a_ as PaymentStatus, a$ as PaymentStatuses, b0 as PaymentSwift, b1 as PickupPoint, b2 as PickupPointHours, b3 as PickupPointsInput, b4 as PickupWidgetConfig, b5 as PriceDisplay, b6 as ProductAssetGroup, b7 as ProductAssetItem, b8 as ProductAvailability, b9 as ProductGroup, ba as ProductLabel, bb as ProductListItem, bc as ProductMedia, bd as ProductMediaVariant, be as ProductParameter, bf as ProductParameterGroup, bg as ProductParametersResponse, bh as ProductPrice, bi as ProductPromotionSummary, bj as ProductReview, bk as ProductReviewsResponse, bl as ProductSibling, bm as ProductSort, bn as ProductSortValue, bo as ProductVolumePrice, bp as ProductsQuery, bq as QuizAnswerInput, br as QuizAnswerResult, bs as QuizQuestion, bt as QuizResult, bu as QuoteItem, bv as QuoteRequest, bw as RegisterInput, bx as RegisterResult, by as RequestInterceptor, bz as RequestInterceptorConfig, bA as ResponseInterceptor, bB as ResponseInterceptorData, bC as ReturnRequest, bD as ReturnRequestItem, bE as ReturnStatus, bF as ReturnStatusItem, bG as ReturnableOrder, bH as ReturnableOrderItem, bI as SdkError, bJ as ShippingMethodSummary, bK as ShippingQuote, bL as ShippingQuoteInput, bM as ShopAppearance, bN as ShopInfo, bO as ShopScript, bP as ShopScriptPlacement, bQ as ShopScriptType, bR as ShopScripts, bS as ShopSeo, bT as ShopSeoIdentity, bU as SiteFormField, bV as SiteFormFieldOption, bW as SiteFormFieldType, bX as Sitemap, bY as SitemapEntry, bZ as StockBehavior, b_ as StockMode, b$ as StorefrontForm, c0 as StorefrontFormFieldErrorCode, c1 as StorefrontFormSettings, c2 as StorefrontFormSubmitInput, c3 as StorefrontFormSubmitResult, c4 as SubmitQuoteInput, c5 as SubmitReturnInput, c6 as SubmitReviewInput, c7 as Subscription, c8 as SubscriptionAction, c9 as SubscriptionFrequency, ca as SubscriptionItem, cb as SubscriptionStatus, cc as TaxBreakdownLine, cd as VariantAxis, ce as VariantAxisValue, cf as WishlistItem, cg as err, ch as ok, ci as toSdkError } from './client-Gf4MBpav.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Format a price amount with currency using Intl.NumberFormat.
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkSF7JTW3Yjs = require('./chunk-SF7JTW3Y.js');
|
|
14
14
|
|
|
15
15
|
// src/react/utils/format-price.ts
|
|
16
16
|
function formatPrice(amount, currency, locale, display) {
|
|
@@ -933,7 +933,7 @@ var GENERIC = {
|
|
|
933
933
|
en: "Something went wrong, please try again."
|
|
934
934
|
};
|
|
935
935
|
function bodyOf(err2) {
|
|
936
|
-
const body = err2 instanceof
|
|
936
|
+
const body = err2 instanceof _chunkSF7JTW3Yjs.BehioApiError ? err2.body : err2 && typeof err2 === "object" && "body" in err2 ? err2.body : err2;
|
|
937
937
|
return body && typeof body === "object" ? body : null;
|
|
938
938
|
}
|
|
939
939
|
function errorCode(err2) {
|
|
@@ -1045,4 +1045,4 @@ function formFieldErrors(err2) {
|
|
|
1045
1045
|
|
|
1046
1046
|
|
|
1047
1047
|
|
|
1048
|
-
exports.AddressTypes =
|
|
1048
|
+
exports.AddressTypes = _chunkSF7JTW3Yjs.AddressTypes; exports.BehioApiError = _chunkSF7JTW3Yjs.BehioApiError; exports.BehioNetworkError = _chunkSF7JTW3Yjs.BehioNetworkError; exports.BehioStorefront = _chunkSF7JTW3Yjs.BehioStorefront; exports.FulfillmentStatuses = _chunkSF7JTW3Yjs.FulfillmentStatuses; exports.OrderStatuses = _chunkSF7JTW3Yjs.OrderStatuses; exports.PaymentStatuses = _chunkSF7JTW3Yjs.PaymentStatuses; exports.ProductSort = _chunkSF7JTW3Yjs.ProductSort; exports.VARIANT_QUERY_PARAM = VARIANT_QUERY_PARAM; exports.availableAxisValues = availableAxisValues; exports.buildVariantComparison = buildVariantComparison; exports.err = _chunkSF7JTW3Yjs.err; exports.errorCode = errorCode; exports.errorMessage = errorMessage; exports.errorParams = errorParams; exports.findVariantByAttributes = findVariantByAttributes; exports.formFieldErrors = formFieldErrors; exports.formatPrice = formatPrice; exports.generateVisitorId = generateVisitorId; exports.getStoredVisitorId = getStoredVisitorId; exports.grantAnalyticsConsent = grantAnalyticsConsent; exports.ok = _chunkSF7JTW3Yjs.ok; exports.resolveVariantContent = resolveVariantContent; exports.revokeAnalyticsConsent = revokeAnalyticsConsent; exports.toSdkError = _chunkSF7JTW3Yjs.toSdkError; exports.trackEcommerceEvent = trackEcommerceEvent; exports.validationFieldMessages = validationFieldMessages; exports.variantFromQuery = variantFromQuery; exports.variantHref = variantHref;
|
package/dist/index.mjs
CHANGED
package/dist/next.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { p as BehioStorefrontConfig, B as BehioStorefront } from './client-
|
|
1
|
+
import { p as BehioStorefrontConfig, B as BehioStorefront } from './client-Gf4MBpav.mjs';
|
|
2
2
|
|
|
3
3
|
interface GetBehioOptions extends Partial<BehioStorefrontConfig> {
|
|
4
4
|
/** Override the cart session cookie name (default: "behio_cart_session"). */
|
package/dist/next.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { p as BehioStorefrontConfig, B as BehioStorefront } from './client-
|
|
1
|
+
import { p as BehioStorefrontConfig, B as BehioStorefront } from './client-Gf4MBpav.js';
|
|
2
2
|
|
|
3
3
|
interface GetBehioOptions extends Partial<BehioStorefrontConfig> {
|
|
4
4
|
/** Override the cart session cookie name (default: "behio_cart_session"). */
|
package/dist/next.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkSF7JTW3Yjs = require('./chunk-SF7JTW3Y.js');
|
|
4
4
|
|
|
5
5
|
// src/next.ts
|
|
6
6
|
var _headers = require('next/headers');
|
|
@@ -19,7 +19,7 @@ async function getBehio(options = {}) {
|
|
|
19
19
|
const locale = _nullishCoalesce(options.locale, () => ( process.env.BEHIO_LOCALE));
|
|
20
20
|
const currency = _nullishCoalesce(options.currency, () => ( process.env.BEHIO_CURRENCY));
|
|
21
21
|
const cookieName = _nullishCoalesce(options.cartCookieName, () => ( CART_COOKIE_NAME));
|
|
22
|
-
const client = new (0,
|
|
22
|
+
const client = new (0, _chunkSF7JTW3Yjs.BehioStorefront)({
|
|
23
23
|
apiKey,
|
|
24
24
|
...baseUrl ? { baseUrl } : {},
|
|
25
25
|
...locale ? { locale } : {},
|