@behio/storefront-sdk 1.4.0 → 1.6.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.
- package/dist/{chunk-VI7OYYBD.js → chunk-TJ4TZ5FI.js} +42 -2
- package/dist/{chunk-SULHQV5R.mjs → chunk-TOSF3K7J.mjs} +40 -0
- package/dist/{client-YJtbTLts.d.mts → client-B9jHeWca.d.mts} +36 -0
- package/dist/{client-YJtbTLts.d.ts → client-B9jHeWca.d.ts} +36 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/next.d.mts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +14 -5
- package/dist/next.mjs +11 -2
- package/dist/react.d.mts +36 -0
- package/dist/react.d.ts +36 -0
- package/dist/react.js +49 -2
- package/dist/react.mjs +49 -2
- package/package.json +1 -1
|
@@ -143,6 +143,7 @@ var BehioStorefront = class {
|
|
|
143
143
|
this.timeout = _nullishCoalesce(config.timeout, () => ( 3e4));
|
|
144
144
|
this.retries = _nullishCoalesce(config.retries, () => ( 1));
|
|
145
145
|
this.retryDelay = _nullishCoalesce(config.retryDelay, () => ( 1e3));
|
|
146
|
+
this.visitorIp = config.visitorIp;
|
|
146
147
|
this.catalog = new CatalogModule(this);
|
|
147
148
|
this.auth = new AuthModule(this);
|
|
148
149
|
this.cart = new CartModule(this);
|
|
@@ -174,6 +175,15 @@ var BehioStorefront = class {
|
|
|
174
175
|
getAnalyticsVisitorId() {
|
|
175
176
|
return this.analyticsVisitorId;
|
|
176
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
180
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
181
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
182
|
+
* automatically for per-request clients.
|
|
183
|
+
*/
|
|
184
|
+
setVisitorIp(ip) {
|
|
185
|
+
this.visitorIp = _nullishCoalesce(ip, () => ( void 0));
|
|
186
|
+
}
|
|
177
187
|
/**
|
|
178
188
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
179
189
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -439,6 +449,13 @@ var BehioStorefront = class {
|
|
|
439
449
|
if (this.analyticsVisitorId) {
|
|
440
450
|
headers["X-Behio-Vid"] = this.analyticsVisitorId;
|
|
441
451
|
}
|
|
452
|
+
if (this.visitorIp) {
|
|
453
|
+
try {
|
|
454
|
+
const ip = typeof this.visitorIp === "function" ? await this.visitorIp() : this.visitorIp;
|
|
455
|
+
if (ip) headers["X-Behio-Visitor-Ip"] = ip;
|
|
456
|
+
} catch (e4) {
|
|
457
|
+
}
|
|
458
|
+
}
|
|
442
459
|
if (_optionalChain([options, 'optionalAccess', _14 => _14.headers])) {
|
|
443
460
|
Object.assign(headers, options.headers);
|
|
444
461
|
}
|
|
@@ -516,7 +533,7 @@ var BehioStorefront = class {
|
|
|
516
533
|
...options,
|
|
517
534
|
_isRetryAfterRefresh: true
|
|
518
535
|
});
|
|
519
|
-
} catch (
|
|
536
|
+
} catch (e5) {
|
|
520
537
|
this.emit("error", apiError);
|
|
521
538
|
throw apiError;
|
|
522
539
|
}
|
|
@@ -538,7 +555,7 @@ var BehioStorefront = class {
|
|
|
538
555
|
data: responseData,
|
|
539
556
|
headers: res.headers
|
|
540
557
|
});
|
|
541
|
-
} catch (
|
|
558
|
+
} catch (e6) {
|
|
542
559
|
}
|
|
543
560
|
}
|
|
544
561
|
return responseData;
|
|
@@ -955,6 +972,29 @@ var CartModule = class {
|
|
|
955
972
|
this.client.emit("cart:updated", res.data);
|
|
956
973
|
return res;
|
|
957
974
|
}
|
|
975
|
+
/**
|
|
976
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
977
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
978
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
979
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
980
|
+
* none exists yet.
|
|
981
|
+
*
|
|
982
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
983
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
984
|
+
*
|
|
985
|
+
* ```ts
|
|
986
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
987
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
async setCurrency(currency) {
|
|
991
|
+
const res = await this.client.request("PUT", "/cart/currency", {
|
|
992
|
+
body: { currency }
|
|
993
|
+
});
|
|
994
|
+
if (res.error) return res;
|
|
995
|
+
this.client.emit("cart:updated", res.data);
|
|
996
|
+
return res;
|
|
997
|
+
}
|
|
958
998
|
/** Update item quantity */
|
|
959
999
|
async updateQuantity(itemId, quantity) {
|
|
960
1000
|
const res = await this.client.request(
|
|
@@ -143,6 +143,7 @@ var BehioStorefront = class {
|
|
|
143
143
|
this.timeout = config.timeout ?? 3e4;
|
|
144
144
|
this.retries = config.retries ?? 1;
|
|
145
145
|
this.retryDelay = config.retryDelay ?? 1e3;
|
|
146
|
+
this.visitorIp = config.visitorIp;
|
|
146
147
|
this.catalog = new CatalogModule(this);
|
|
147
148
|
this.auth = new AuthModule(this);
|
|
148
149
|
this.cart = new CartModule(this);
|
|
@@ -174,6 +175,15 @@ var BehioStorefront = class {
|
|
|
174
175
|
getAnalyticsVisitorId() {
|
|
175
176
|
return this.analyticsVisitorId;
|
|
176
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
180
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
181
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
182
|
+
* automatically for per-request clients.
|
|
183
|
+
*/
|
|
184
|
+
setVisitorIp(ip) {
|
|
185
|
+
this.visitorIp = ip ?? void 0;
|
|
186
|
+
}
|
|
177
187
|
/**
|
|
178
188
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
179
189
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -439,6 +449,13 @@ var BehioStorefront = class {
|
|
|
439
449
|
if (this.analyticsVisitorId) {
|
|
440
450
|
headers["X-Behio-Vid"] = this.analyticsVisitorId;
|
|
441
451
|
}
|
|
452
|
+
if (this.visitorIp) {
|
|
453
|
+
try {
|
|
454
|
+
const ip = typeof this.visitorIp === "function" ? await this.visitorIp() : this.visitorIp;
|
|
455
|
+
if (ip) headers["X-Behio-Visitor-Ip"] = ip;
|
|
456
|
+
} catch {
|
|
457
|
+
}
|
|
458
|
+
}
|
|
442
459
|
if (options?.headers) {
|
|
443
460
|
Object.assign(headers, options.headers);
|
|
444
461
|
}
|
|
@@ -955,6 +972,29 @@ var CartModule = class {
|
|
|
955
972
|
this.client.emit("cart:updated", res.data);
|
|
956
973
|
return res;
|
|
957
974
|
}
|
|
975
|
+
/**
|
|
976
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
977
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
978
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
979
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
980
|
+
* none exists yet.
|
|
981
|
+
*
|
|
982
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
983
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
984
|
+
*
|
|
985
|
+
* ```ts
|
|
986
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
987
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
async setCurrency(currency) {
|
|
991
|
+
const res = await this.client.request("PUT", "/cart/currency", {
|
|
992
|
+
body: { currency }
|
|
993
|
+
});
|
|
994
|
+
if (res.error) return res;
|
|
995
|
+
this.client.emit("cart:updated", res.data);
|
|
996
|
+
return res;
|
|
997
|
+
}
|
|
958
998
|
/** Update item quantity */
|
|
959
999
|
async updateQuantity(itemId, quantity) {
|
|
960
1000
|
const res = await this.client.request(
|
|
@@ -17,6 +17,18 @@ interface BehioStorefrontConfig {
|
|
|
17
17
|
currency?: string;
|
|
18
18
|
/** Custom fetch implementation (for Node.js < 18 or testing) */
|
|
19
19
|
fetch?: typeof fetch;
|
|
20
|
+
/**
|
|
21
|
+
* Real visitor IP for server-side rendering. Sent as X-Behio-Visitor-Ip so
|
|
22
|
+
* the backend rate-limits per visitor instead of per server: all SSR
|
|
23
|
+
* requests of one deployment share the server's IP, so without this header
|
|
24
|
+
* the whole shop shares one rate-limit bucket. The backend only trusts the
|
|
25
|
+
* header from allow-listed hosting IPs, so a browser sending it gains
|
|
26
|
+
* nothing. Accepts a fixed string or a resolver called per request (use a
|
|
27
|
+
* resolver for a shared catalog client that serves many concurrent
|
|
28
|
+
* requests). The Next.js adapter (`@behio/storefront-sdk/next`) fills this
|
|
29
|
+
* automatically from the incoming request headers.
|
|
30
|
+
*/
|
|
31
|
+
visitorIp?: string | (() => string | null | undefined | Promise<string | null | undefined>);
|
|
20
32
|
/** Request timeout in milliseconds. Default: 30000 (30s) */
|
|
21
33
|
timeout?: number;
|
|
22
34
|
/** Number of retries on network/5xx errors. Default: 1 */
|
|
@@ -2267,6 +2279,7 @@ declare class BehioStorefront {
|
|
|
2267
2279
|
private responseInterceptors;
|
|
2268
2280
|
private rateLimitRemaining;
|
|
2269
2281
|
private rateLimitReset;
|
|
2282
|
+
private visitorIp?;
|
|
2270
2283
|
constructor(config: BehioStorefrontConfig);
|
|
2271
2284
|
readonly catalog: CatalogModule;
|
|
2272
2285
|
readonly auth: AuthModule;
|
|
@@ -2293,6 +2306,13 @@ declare class BehioStorefront {
|
|
|
2293
2306
|
setAnalyticsVisitorId(id: string | null): void;
|
|
2294
2307
|
/** The consent-gated visitor id, if analytics consent was granted. */
|
|
2295
2308
|
getAnalyticsVisitorId(): string | null;
|
|
2309
|
+
/**
|
|
2310
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
2311
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
2312
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
2313
|
+
* automatically for per-request clients.
|
|
2314
|
+
*/
|
|
2315
|
+
setVisitorIp(ip: string | null): void;
|
|
2296
2316
|
/**
|
|
2297
2317
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
2298
2318
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -2596,6 +2616,22 @@ declare class CartModule {
|
|
|
2596
2616
|
addItem(input: AddToCartInput): Promise<SdkResult<Cart & {
|
|
2597
2617
|
newSessionToken?: string;
|
|
2598
2618
|
}>>;
|
|
2619
|
+
/**
|
|
2620
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
2621
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
2622
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
2623
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
2624
|
+
* none exists yet.
|
|
2625
|
+
*
|
|
2626
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
2627
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
2628
|
+
*
|
|
2629
|
+
* ```ts
|
|
2630
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
2631
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
2632
|
+
* ```
|
|
2633
|
+
*/
|
|
2634
|
+
setCurrency(currency: string): Promise<SdkResult<Cart>>;
|
|
2599
2635
|
/** Update item quantity */
|
|
2600
2636
|
updateQuantity(itemId: string, quantity: number): Promise<SdkResult<Cart>>;
|
|
2601
2637
|
/** Remove item from cart */
|
|
@@ -17,6 +17,18 @@ interface BehioStorefrontConfig {
|
|
|
17
17
|
currency?: string;
|
|
18
18
|
/** Custom fetch implementation (for Node.js < 18 or testing) */
|
|
19
19
|
fetch?: typeof fetch;
|
|
20
|
+
/**
|
|
21
|
+
* Real visitor IP for server-side rendering. Sent as X-Behio-Visitor-Ip so
|
|
22
|
+
* the backend rate-limits per visitor instead of per server: all SSR
|
|
23
|
+
* requests of one deployment share the server's IP, so without this header
|
|
24
|
+
* the whole shop shares one rate-limit bucket. The backend only trusts the
|
|
25
|
+
* header from allow-listed hosting IPs, so a browser sending it gains
|
|
26
|
+
* nothing. Accepts a fixed string or a resolver called per request (use a
|
|
27
|
+
* resolver for a shared catalog client that serves many concurrent
|
|
28
|
+
* requests). The Next.js adapter (`@behio/storefront-sdk/next`) fills this
|
|
29
|
+
* automatically from the incoming request headers.
|
|
30
|
+
*/
|
|
31
|
+
visitorIp?: string | (() => string | null | undefined | Promise<string | null | undefined>);
|
|
20
32
|
/** Request timeout in milliseconds. Default: 30000 (30s) */
|
|
21
33
|
timeout?: number;
|
|
22
34
|
/** Number of retries on network/5xx errors. Default: 1 */
|
|
@@ -2267,6 +2279,7 @@ declare class BehioStorefront {
|
|
|
2267
2279
|
private responseInterceptors;
|
|
2268
2280
|
private rateLimitRemaining;
|
|
2269
2281
|
private rateLimitReset;
|
|
2282
|
+
private visitorIp?;
|
|
2270
2283
|
constructor(config: BehioStorefrontConfig);
|
|
2271
2284
|
readonly catalog: CatalogModule;
|
|
2272
2285
|
readonly auth: AuthModule;
|
|
@@ -2293,6 +2306,13 @@ declare class BehioStorefront {
|
|
|
2293
2306
|
setAnalyticsVisitorId(id: string | null): void;
|
|
2294
2307
|
/** The consent-gated visitor id, if analytics consent was granted. */
|
|
2295
2308
|
getAnalyticsVisitorId(): string | null;
|
|
2309
|
+
/**
|
|
2310
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
2311
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
2312
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
2313
|
+
* automatically for per-request clients.
|
|
2314
|
+
*/
|
|
2315
|
+
setVisitorIp(ip: string | null): void;
|
|
2296
2316
|
/**
|
|
2297
2317
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
2298
2318
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -2596,6 +2616,22 @@ declare class CartModule {
|
|
|
2596
2616
|
addItem(input: AddToCartInput): Promise<SdkResult<Cart & {
|
|
2597
2617
|
newSessionToken?: string;
|
|
2598
2618
|
}>>;
|
|
2619
|
+
/**
|
|
2620
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
2621
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
2622
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
2623
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
2624
|
+
* none exists yet.
|
|
2625
|
+
*
|
|
2626
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
2627
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
2628
|
+
*
|
|
2629
|
+
* ```ts
|
|
2630
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
2631
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
2632
|
+
* ```
|
|
2633
|
+
*/
|
|
2634
|
+
setCurrency(currency: string): Promise<SdkResult<Cart>>;
|
|
2599
2635
|
/** Update item quantity */
|
|
2600
2636
|
updateQuantity(itemId: string, quantity: number): Promise<SdkResult<Cart>>;
|
|
2601
2637
|
/** Remove item from cart */
|
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 } from './client-
|
|
2
|
-
export { A as ActivePromotion, b as AddToCartInput, c as AddressDetail, d as AddressSuggestion, e as AddressType, f as AddressTypes, g as AuthTokens, h as BackInStockSubscription, i as BadgeTone, j as BehioApiError, k as BehioErrorCode, l as BehioEventHandler, m as BehioEventType, n as BehioNetworkError, o as BehioStorefrontConfig, p as Bundle, q as BundleItem, r as Cart, s as CartBundleLine, t as CartBundleLineItem, u as CartDiscount, v as CartItem, w as CartItemProduct, x as CartPromotion, y as Category, z as CategoryDetail, D as CertificateVerification, E as CheckoutAddress, F as CheckoutInput, G as CheckoutPaymentMethod, H as CheckoutSettings, I as CookieConsentInput, J as CourseAttachment, K as CourseCertificate, L as CourseComment, M as CourseCommentReply, N as CourseCommentsList, O as CourseDetail, Q as CourseLesson, R as CourseListItem, T as CourseModule, U as CoursePostedComment, V as CourseProgress, W as CourseTutorMessage, X as CourseTutorThread, Y as CrossSellItem, Z as CustomerAddress, _ as CustomerProfile, $ as DigitalDownload, a0 as DownloadUrl, a1 as Facet, a2 as FacetAvailability, a3 as FacetCategory, a4 as FacetLabel, a5 as FacetPriceRange, a6 as FacetRange, a7 as FacetRatingBucket, a8 as FacetValue, a9 as FacetsResponse, aa as FilterField, ab as FulfillmentStatus, ac as FulfillmentStatuses, ad as GiftCardBalance, ae as GiftCardPurchaseInput, af as GiftCardPurchaseResult, ag as GiftCardSummary, ah as LessonNote, ai as LessonQuiz, aj as LoginInput, ak as LoyaltyBalance, al as LoyaltyNextTier, am as LoyaltyProgram, an as LoyaltySummary, ao as LoyaltyTier, ap as LoyaltyTierPerks, aq as LoyaltyTransaction, ar as Menu, as as MenuItem, at as MenuItemRef, au as MenuItemType, av as MessageResponse, aw as NewsletterOptInDefault, ax as NewsletterSubscribeInput, ay as NewsletterSubscribeResult, az as NewsletterUnsubscribeResult, aA as OrderAccessRequestResponse, aB as OrderAccessVerifyResponse, aC as OrderDetail, aD as OrderItem, aE as OrderListItem, aF as OrderStatus, aG as OrderStatusHistory, aH as OrderStatuses, aI as OrderTracking, aJ as Page, aK as PageAttachment, aL as PageDetail, aM as PaginatedResponse, aN as PaymentStatus, aO as PaymentStatuses, aP as PickupPoint, aQ as PickupPointHours, aR as PickupPointsInput, aS as PriceDisplay, aT as ProductAvailability, aU as ProductGroup, aV as ProductLabel, aW as ProductListItem, aX as ProductMedia, aY as ProductMediaVariant, aZ as ProductParameter, a_ as ProductParameterGroup, a$ as ProductParametersResponse, b0 as ProductPrice, b1 as ProductPromotionSummary, b2 as ProductReview, b3 as ProductReviewsResponse, b4 as ProductSibling, b5 as ProductSort, b6 as ProductSortValue, b7 as ProductVolumePrice, b8 as ProductsQuery, b9 as QuizAnswerInput, ba as QuizAnswerResult, bb as QuizQuestion, bc as QuizResult, bd as QuoteItem, be as QuoteRequest, bf as RegisterInput, bg as RegisterResult, bh as RequestInterceptor, bi as RequestInterceptorConfig, bj as ResponseInterceptor, bk as ResponseInterceptorData, bl as ReturnRequest, bm as ReturnRequestItem, bn as ReturnStatus, bo as ReturnStatusItem, bp as ReturnableOrder, bq as ReturnableOrderItem, br as SdkError, bs as ShippingMethodSummary, bt as ShippingQuote, bu as ShippingQuoteInput, bv as ShopInfo, bw as ShopScript, bx as ShopScriptPlacement, by as ShopScriptType, bz as ShopScripts, bA as ShopSeo, bB as ShopSeoIdentity, bC as Sitemap, bD as SitemapEntry, bE as StockBehavior, bF as StockMode, bG as SubmitQuoteInput, bH as SubmitReturnInput, bI as SubmitReviewInput, bJ as Subscription, bK as SubscriptionAction, bL as SubscriptionFrequency, bM as SubscriptionItem, bN as SubscriptionStatus, bO as TaxBreakdownLine, bP as VariantAxis, bQ as VariantAxisValue, bR as WishlistItem, bS as err, bT as ok, bU as toSdkError } from './client-
|
|
1
|
+
import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent } from './client-B9jHeWca.mjs';
|
|
2
|
+
export { A as ActivePromotion, b as AddToCartInput, c as AddressDetail, d as AddressSuggestion, e as AddressType, f as AddressTypes, g as AuthTokens, h as BackInStockSubscription, i as BadgeTone, j as BehioApiError, k as BehioErrorCode, l as BehioEventHandler, m as BehioEventType, n as BehioNetworkError, o as BehioStorefrontConfig, p as Bundle, q as BundleItem, r as Cart, s as CartBundleLine, t as CartBundleLineItem, u as CartDiscount, v as CartItem, w as CartItemProduct, x as CartPromotion, y as Category, z as CategoryDetail, D as CertificateVerification, E as CheckoutAddress, F as CheckoutInput, G as CheckoutPaymentMethod, H as CheckoutSettings, I as CookieConsentInput, J as CourseAttachment, K as CourseCertificate, L as CourseComment, M as CourseCommentReply, N as CourseCommentsList, O as CourseDetail, Q as CourseLesson, R as CourseListItem, T as CourseModule, U as CoursePostedComment, V as CourseProgress, W as CourseTutorMessage, X as CourseTutorThread, Y as CrossSellItem, Z as CustomerAddress, _ as CustomerProfile, $ as DigitalDownload, a0 as DownloadUrl, a1 as Facet, a2 as FacetAvailability, a3 as FacetCategory, a4 as FacetLabel, a5 as FacetPriceRange, a6 as FacetRange, a7 as FacetRatingBucket, a8 as FacetValue, a9 as FacetsResponse, aa as FilterField, ab as FulfillmentStatus, ac as FulfillmentStatuses, ad as GiftCardBalance, ae as GiftCardPurchaseInput, af as GiftCardPurchaseResult, ag as GiftCardSummary, ah as LessonNote, ai as LessonQuiz, aj as LoginInput, ak as LoyaltyBalance, al as LoyaltyNextTier, am as LoyaltyProgram, an as LoyaltySummary, ao as LoyaltyTier, ap as LoyaltyTierPerks, aq as LoyaltyTransaction, ar as Menu, as as MenuItem, at as MenuItemRef, au as MenuItemType, av as MessageResponse, aw as NewsletterOptInDefault, ax as NewsletterSubscribeInput, ay as NewsletterSubscribeResult, az as NewsletterUnsubscribeResult, aA as OrderAccessRequestResponse, aB as OrderAccessVerifyResponse, aC as OrderDetail, aD as OrderItem, aE as OrderListItem, aF as OrderStatus, aG as OrderStatusHistory, aH as OrderStatuses, aI as OrderTracking, aJ as Page, aK as PageAttachment, aL as PageDetail, aM as PaginatedResponse, aN as PaymentStatus, aO as PaymentStatuses, aP as PickupPoint, aQ as PickupPointHours, aR as PickupPointsInput, aS as PriceDisplay, aT as ProductAvailability, aU as ProductGroup, aV as ProductLabel, aW as ProductListItem, aX as ProductMedia, aY as ProductMediaVariant, aZ as ProductParameter, a_ as ProductParameterGroup, a$ as ProductParametersResponse, b0 as ProductPrice, b1 as ProductPromotionSummary, b2 as ProductReview, b3 as ProductReviewsResponse, b4 as ProductSibling, b5 as ProductSort, b6 as ProductSortValue, b7 as ProductVolumePrice, b8 as ProductsQuery, b9 as QuizAnswerInput, ba as QuizAnswerResult, bb as QuizQuestion, bc as QuizResult, bd as QuoteItem, be as QuoteRequest, bf as RegisterInput, bg as RegisterResult, bh as RequestInterceptor, bi as RequestInterceptorConfig, bj as ResponseInterceptor, bk as ResponseInterceptorData, bl as ReturnRequest, bm as ReturnRequestItem, bn as ReturnStatus, bo as ReturnStatusItem, bp as ReturnableOrder, bq as ReturnableOrderItem, br as SdkError, bs as ShippingMethodSummary, bt as ShippingQuote, bu as ShippingQuoteInput, bv as ShopInfo, bw as ShopScript, bx as ShopScriptPlacement, by as ShopScriptType, bz as ShopScripts, bA as ShopSeo, bB as ShopSeoIdentity, bC as Sitemap, bD as SitemapEntry, bE as StockBehavior, bF as StockMode, bG as SubmitQuoteInput, bH as SubmitReturnInput, bI as SubmitReviewInput, bJ as Subscription, bK as SubscriptionAction, bL as SubscriptionFrequency, bM as SubscriptionItem, bN as SubscriptionStatus, bO as TaxBreakdownLine, bP as VariantAxis, bQ as VariantAxisValue, bR as WishlistItem, bS as err, bT as ok, bU as toSdkError } from './client-B9jHeWca.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 } from './client-
|
|
2
|
-
export { A as ActivePromotion, b as AddToCartInput, c as AddressDetail, d as AddressSuggestion, e as AddressType, f as AddressTypes, g as AuthTokens, h as BackInStockSubscription, i as BadgeTone, j as BehioApiError, k as BehioErrorCode, l as BehioEventHandler, m as BehioEventType, n as BehioNetworkError, o as BehioStorefrontConfig, p as Bundle, q as BundleItem, r as Cart, s as CartBundleLine, t as CartBundleLineItem, u as CartDiscount, v as CartItem, w as CartItemProduct, x as CartPromotion, y as Category, z as CategoryDetail, D as CertificateVerification, E as CheckoutAddress, F as CheckoutInput, G as CheckoutPaymentMethod, H as CheckoutSettings, I as CookieConsentInput, J as CourseAttachment, K as CourseCertificate, L as CourseComment, M as CourseCommentReply, N as CourseCommentsList, O as CourseDetail, Q as CourseLesson, R as CourseListItem, T as CourseModule, U as CoursePostedComment, V as CourseProgress, W as CourseTutorMessage, X as CourseTutorThread, Y as CrossSellItem, Z as CustomerAddress, _ as CustomerProfile, $ as DigitalDownload, a0 as DownloadUrl, a1 as Facet, a2 as FacetAvailability, a3 as FacetCategory, a4 as FacetLabel, a5 as FacetPriceRange, a6 as FacetRange, a7 as FacetRatingBucket, a8 as FacetValue, a9 as FacetsResponse, aa as FilterField, ab as FulfillmentStatus, ac as FulfillmentStatuses, ad as GiftCardBalance, ae as GiftCardPurchaseInput, af as GiftCardPurchaseResult, ag as GiftCardSummary, ah as LessonNote, ai as LessonQuiz, aj as LoginInput, ak as LoyaltyBalance, al as LoyaltyNextTier, am as LoyaltyProgram, an as LoyaltySummary, ao as LoyaltyTier, ap as LoyaltyTierPerks, aq as LoyaltyTransaction, ar as Menu, as as MenuItem, at as MenuItemRef, au as MenuItemType, av as MessageResponse, aw as NewsletterOptInDefault, ax as NewsletterSubscribeInput, ay as NewsletterSubscribeResult, az as NewsletterUnsubscribeResult, aA as OrderAccessRequestResponse, aB as OrderAccessVerifyResponse, aC as OrderDetail, aD as OrderItem, aE as OrderListItem, aF as OrderStatus, aG as OrderStatusHistory, aH as OrderStatuses, aI as OrderTracking, aJ as Page, aK as PageAttachment, aL as PageDetail, aM as PaginatedResponse, aN as PaymentStatus, aO as PaymentStatuses, aP as PickupPoint, aQ as PickupPointHours, aR as PickupPointsInput, aS as PriceDisplay, aT as ProductAvailability, aU as ProductGroup, aV as ProductLabel, aW as ProductListItem, aX as ProductMedia, aY as ProductMediaVariant, aZ as ProductParameter, a_ as ProductParameterGroup, a$ as ProductParametersResponse, b0 as ProductPrice, b1 as ProductPromotionSummary, b2 as ProductReview, b3 as ProductReviewsResponse, b4 as ProductSibling, b5 as ProductSort, b6 as ProductSortValue, b7 as ProductVolumePrice, b8 as ProductsQuery, b9 as QuizAnswerInput, ba as QuizAnswerResult, bb as QuizQuestion, bc as QuizResult, bd as QuoteItem, be as QuoteRequest, bf as RegisterInput, bg as RegisterResult, bh as RequestInterceptor, bi as RequestInterceptorConfig, bj as ResponseInterceptor, bk as ResponseInterceptorData, bl as ReturnRequest, bm as ReturnRequestItem, bn as ReturnStatus, bo as ReturnStatusItem, bp as ReturnableOrder, bq as ReturnableOrderItem, br as SdkError, bs as ShippingMethodSummary, bt as ShippingQuote, bu as ShippingQuoteInput, bv as ShopInfo, bw as ShopScript, bx as ShopScriptPlacement, by as ShopScriptType, bz as ShopScripts, bA as ShopSeo, bB as ShopSeoIdentity, bC as Sitemap, bD as SitemapEntry, bE as StockBehavior, bF as StockMode, bG as SubmitQuoteInput, bH as SubmitReturnInput, bI as SubmitReviewInput, bJ as Subscription, bK as SubscriptionAction, bL as SubscriptionFrequency, bM as SubscriptionItem, bN as SubscriptionStatus, bO as TaxBreakdownLine, bP as VariantAxis, bQ as VariantAxisValue, bR as WishlistItem, bS as err, bT as ok, bU as toSdkError } from './client-
|
|
1
|
+
import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent } from './client-B9jHeWca.js';
|
|
2
|
+
export { A as ActivePromotion, b as AddToCartInput, c as AddressDetail, d as AddressSuggestion, e as AddressType, f as AddressTypes, g as AuthTokens, h as BackInStockSubscription, i as BadgeTone, j as BehioApiError, k as BehioErrorCode, l as BehioEventHandler, m as BehioEventType, n as BehioNetworkError, o as BehioStorefrontConfig, p as Bundle, q as BundleItem, r as Cart, s as CartBundleLine, t as CartBundleLineItem, u as CartDiscount, v as CartItem, w as CartItemProduct, x as CartPromotion, y as Category, z as CategoryDetail, D as CertificateVerification, E as CheckoutAddress, F as CheckoutInput, G as CheckoutPaymentMethod, H as CheckoutSettings, I as CookieConsentInput, J as CourseAttachment, K as CourseCertificate, L as CourseComment, M as CourseCommentReply, N as CourseCommentsList, O as CourseDetail, Q as CourseLesson, R as CourseListItem, T as CourseModule, U as CoursePostedComment, V as CourseProgress, W as CourseTutorMessage, X as CourseTutorThread, Y as CrossSellItem, Z as CustomerAddress, _ as CustomerProfile, $ as DigitalDownload, a0 as DownloadUrl, a1 as Facet, a2 as FacetAvailability, a3 as FacetCategory, a4 as FacetLabel, a5 as FacetPriceRange, a6 as FacetRange, a7 as FacetRatingBucket, a8 as FacetValue, a9 as FacetsResponse, aa as FilterField, ab as FulfillmentStatus, ac as FulfillmentStatuses, ad as GiftCardBalance, ae as GiftCardPurchaseInput, af as GiftCardPurchaseResult, ag as GiftCardSummary, ah as LessonNote, ai as LessonQuiz, aj as LoginInput, ak as LoyaltyBalance, al as LoyaltyNextTier, am as LoyaltyProgram, an as LoyaltySummary, ao as LoyaltyTier, ap as LoyaltyTierPerks, aq as LoyaltyTransaction, ar as Menu, as as MenuItem, at as MenuItemRef, au as MenuItemType, av as MessageResponse, aw as NewsletterOptInDefault, ax as NewsletterSubscribeInput, ay as NewsletterSubscribeResult, az as NewsletterUnsubscribeResult, aA as OrderAccessRequestResponse, aB as OrderAccessVerifyResponse, aC as OrderDetail, aD as OrderItem, aE as OrderListItem, aF as OrderStatus, aG as OrderStatusHistory, aH as OrderStatuses, aI as OrderTracking, aJ as Page, aK as PageAttachment, aL as PageDetail, aM as PaginatedResponse, aN as PaymentStatus, aO as PaymentStatuses, aP as PickupPoint, aQ as PickupPointHours, aR as PickupPointsInput, aS as PriceDisplay, aT as ProductAvailability, aU as ProductGroup, aV as ProductLabel, aW as ProductListItem, aX as ProductMedia, aY as ProductMediaVariant, aZ as ProductParameter, a_ as ProductParameterGroup, a$ as ProductParametersResponse, b0 as ProductPrice, b1 as ProductPromotionSummary, b2 as ProductReview, b3 as ProductReviewsResponse, b4 as ProductSibling, b5 as ProductSort, b6 as ProductSortValue, b7 as ProductVolumePrice, b8 as ProductsQuery, b9 as QuizAnswerInput, ba as QuizAnswerResult, bb as QuizQuestion, bc as QuizResult, bd as QuoteItem, be as QuoteRequest, bf as RegisterInput, bg as RegisterResult, bh as RequestInterceptor, bi as RequestInterceptorConfig, bj as ResponseInterceptor, bk as ResponseInterceptorData, bl as ReturnRequest, bm as ReturnRequestItem, bn as ReturnStatus, bo as ReturnStatusItem, bp as ReturnableOrder, bq as ReturnableOrderItem, br as SdkError, bs as ShippingMethodSummary, bt as ShippingQuote, bu as ShippingQuoteInput, bv as ShopInfo, bw as ShopScript, bx as ShopScriptPlacement, by as ShopScriptType, bz as ShopScripts, bA as ShopSeo, bB as ShopSeoIdentity, bC as Sitemap, bD as SitemapEntry, bE as StockBehavior, bF as StockMode, bG as SubmitQuoteInput, bH as SubmitReturnInput, bI as SubmitReviewInput, bJ as Subscription, bK as SubscriptionAction, bL as SubscriptionFrequency, bM as SubscriptionItem, bN as SubscriptionStatus, bO as TaxBreakdownLine, bP as VariantAxis, bQ as VariantAxisValue, bR as WishlistItem, bS as err, bT as ok, bU as toSdkError } from './client-B9jHeWca.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 _chunkTJ4TZ5FIjs = require('./chunk-TJ4TZ5FI.js');
|
|
14
14
|
|
|
15
15
|
// src/react/utils/format-price.ts
|
|
16
16
|
function formatPrice(amount, currency, locale) {
|
|
@@ -243,4 +243,4 @@ async function revokeAnalyticsConsent(client) {
|
|
|
243
243
|
|
|
244
244
|
|
|
245
245
|
|
|
246
|
-
exports.AddressTypes =
|
|
246
|
+
exports.AddressTypes = _chunkTJ4TZ5FIjs.AddressTypes; exports.BehioApiError = _chunkTJ4TZ5FIjs.BehioApiError; exports.BehioNetworkError = _chunkTJ4TZ5FIjs.BehioNetworkError; exports.BehioStorefront = _chunkTJ4TZ5FIjs.BehioStorefront; exports.FulfillmentStatuses = _chunkTJ4TZ5FIjs.FulfillmentStatuses; exports.OrderStatuses = _chunkTJ4TZ5FIjs.OrderStatuses; exports.PaymentStatuses = _chunkTJ4TZ5FIjs.PaymentStatuses; exports.ProductSort = _chunkTJ4TZ5FIjs.ProductSort; exports.VARIANT_QUERY_PARAM = VARIANT_QUERY_PARAM; exports.availableAxisValues = availableAxisValues; exports.buildVariantComparison = buildVariantComparison; exports.err = _chunkTJ4TZ5FIjs.err; exports.findVariantByAttributes = findVariantByAttributes; exports.formatPrice = formatPrice; exports.generateVisitorId = generateVisitorId; exports.getStoredVisitorId = getStoredVisitorId; exports.grantAnalyticsConsent = grantAnalyticsConsent; exports.ok = _chunkTJ4TZ5FIjs.ok; exports.resolveVariantContent = resolveVariantContent; exports.revokeAnalyticsConsent = revokeAnalyticsConsent; exports.toSdkError = _chunkTJ4TZ5FIjs.toSdkError; exports.trackEcommerceEvent = trackEcommerceEvent; exports.variantFromQuery = variantFromQuery; exports.variantHref = variantHref;
|
package/dist/index.mjs
CHANGED
package/dist/next.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as BehioStorefrontConfig, B as BehioStorefront } from './client-
|
|
1
|
+
import { o as BehioStorefrontConfig, B as BehioStorefront } from './client-B9jHeWca.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 { o as BehioStorefrontConfig, B as BehioStorefront } from './client-
|
|
1
|
+
import { o as BehioStorefrontConfig, B as BehioStorefront } from './client-B9jHeWca.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 _chunkTJ4TZ5FIjs = require('./chunk-TJ4TZ5FI.js');
|
|
4
4
|
|
|
5
5
|
// src/next.ts
|
|
6
6
|
var _headers = require('next/headers');
|
|
@@ -18,7 +18,7 @@ async function getBehio(options = {}) {
|
|
|
18
18
|
const locale = _nullishCoalesce(options.locale, () => ( process.env.BEHIO_LOCALE));
|
|
19
19
|
const currency = _nullishCoalesce(options.currency, () => ( process.env.BEHIO_CURRENCY));
|
|
20
20
|
const cookieName = _nullishCoalesce(options.cartCookieName, () => ( CART_COOKIE_NAME));
|
|
21
|
-
const client = new (0,
|
|
21
|
+
const client = new (0, _chunkTJ4TZ5FIjs.BehioStorefront)({
|
|
22
22
|
apiKey,
|
|
23
23
|
...baseUrl ? { baseUrl } : {},
|
|
24
24
|
...locale ? { locale } : {},
|
|
@@ -30,9 +30,18 @@ async function getBehio(options = {}) {
|
|
|
30
30
|
if (existing) {
|
|
31
31
|
client.setCartSession(existing);
|
|
32
32
|
}
|
|
33
|
+
if (!options.visitorIp) {
|
|
34
|
+
try {
|
|
35
|
+
const h = await _headers.headers.call(void 0, );
|
|
36
|
+
const xff = h.get("x-forwarded-for");
|
|
37
|
+
const ip = (_nullishCoalesce(_nullishCoalesce(_optionalChain([xff, 'optionalAccess', _4 => _4.split, 'call', _5 => _5(","), 'access', _6 => _6[0]]), () => ( h.get("x-real-ip"))), () => ( ""))).trim();
|
|
38
|
+
if (ip) client.setVisitorIp(ip);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
33
42
|
if (!currency) {
|
|
34
43
|
const currencyCookieName = _nullishCoalesce(options.currencyCookieName, () => ( CURRENCY_COOKIE_NAME));
|
|
35
|
-
const chosenCurrency = _optionalChain([cookieStore, 'access',
|
|
44
|
+
const chosenCurrency = _optionalChain([cookieStore, 'access', _7 => _7.get, 'call', _8 => _8(currencyCookieName), 'optionalAccess', _9 => _9.value]);
|
|
36
45
|
if (chosenCurrency) {
|
|
37
46
|
client.setCurrency(chosenCurrency);
|
|
38
47
|
}
|
|
@@ -48,14 +57,14 @@ async function getBehio(options = {}) {
|
|
|
48
57
|
path: "/",
|
|
49
58
|
maxAge: CART_COOKIE_MAX_AGE
|
|
50
59
|
});
|
|
51
|
-
} catch (
|
|
60
|
+
} catch (e2) {
|
|
52
61
|
}
|
|
53
62
|
};
|
|
54
63
|
client.clearCartSession = () => {
|
|
55
64
|
originalClear();
|
|
56
65
|
try {
|
|
57
66
|
cookieStore.delete(cookieName);
|
|
58
|
-
} catch (
|
|
67
|
+
} catch (e3) {
|
|
59
68
|
}
|
|
60
69
|
};
|
|
61
70
|
return client;
|
package/dist/next.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BehioStorefront
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TOSF3K7J.mjs";
|
|
4
4
|
|
|
5
5
|
// src/next.ts
|
|
6
|
-
import { cookies } from "next/headers";
|
|
6
|
+
import { cookies, headers } from "next/headers";
|
|
7
7
|
var CART_COOKIE_NAME = "behio_cart_session";
|
|
8
8
|
var CURRENCY_COOKIE_NAME = "behio_currency";
|
|
9
9
|
var CART_COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
|
|
@@ -30,6 +30,15 @@ async function getBehio(options = {}) {
|
|
|
30
30
|
if (existing) {
|
|
31
31
|
client.setCartSession(existing);
|
|
32
32
|
}
|
|
33
|
+
if (!options.visitorIp) {
|
|
34
|
+
try {
|
|
35
|
+
const h = await headers();
|
|
36
|
+
const xff = h.get("x-forwarded-for");
|
|
37
|
+
const ip = (xff?.split(",")[0] ?? h.get("x-real-ip") ?? "").trim();
|
|
38
|
+
if (ip) client.setVisitorIp(ip);
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
33
42
|
if (!currency) {
|
|
34
43
|
const currencyCookieName = options.currencyCookieName ?? CURRENCY_COOKIE_NAME;
|
|
35
44
|
const chosenCurrency = cookieStore.get(currencyCookieName)?.value;
|
package/dist/react.d.mts
CHANGED
|
@@ -73,6 +73,18 @@ interface BehioStorefrontConfig {
|
|
|
73
73
|
currency?: string;
|
|
74
74
|
/** Custom fetch implementation (for Node.js < 18 or testing) */
|
|
75
75
|
fetch?: typeof fetch;
|
|
76
|
+
/**
|
|
77
|
+
* Real visitor IP for server-side rendering. Sent as X-Behio-Visitor-Ip so
|
|
78
|
+
* the backend rate-limits per visitor instead of per server: all SSR
|
|
79
|
+
* requests of one deployment share the server's IP, so without this header
|
|
80
|
+
* the whole shop shares one rate-limit bucket. The backend only trusts the
|
|
81
|
+
* header from allow-listed hosting IPs, so a browser sending it gains
|
|
82
|
+
* nothing. Accepts a fixed string or a resolver called per request (use a
|
|
83
|
+
* resolver for a shared catalog client that serves many concurrent
|
|
84
|
+
* requests). The Next.js adapter (`@behio/storefront-sdk/next`) fills this
|
|
85
|
+
* automatically from the incoming request headers.
|
|
86
|
+
*/
|
|
87
|
+
visitorIp?: string | (() => string | null | undefined | Promise<string | null | undefined>);
|
|
76
88
|
/** Request timeout in milliseconds. Default: 30000 (30s) */
|
|
77
89
|
timeout?: number;
|
|
78
90
|
/** Number of retries on network/5xx errors. Default: 1 */
|
|
@@ -2311,6 +2323,7 @@ declare class BehioStorefront {
|
|
|
2311
2323
|
private responseInterceptors;
|
|
2312
2324
|
private rateLimitRemaining;
|
|
2313
2325
|
private rateLimitReset;
|
|
2326
|
+
private visitorIp?;
|
|
2314
2327
|
constructor(config: BehioStorefrontConfig);
|
|
2315
2328
|
readonly catalog: CatalogModule;
|
|
2316
2329
|
readonly auth: AuthModule;
|
|
@@ -2337,6 +2350,13 @@ declare class BehioStorefront {
|
|
|
2337
2350
|
setAnalyticsVisitorId(id: string | null): void;
|
|
2338
2351
|
/** The consent-gated visitor id, if analytics consent was granted. */
|
|
2339
2352
|
getAnalyticsVisitorId(): string | null;
|
|
2353
|
+
/**
|
|
2354
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
2355
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
2356
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
2357
|
+
* automatically for per-request clients.
|
|
2358
|
+
*/
|
|
2359
|
+
setVisitorIp(ip: string | null): void;
|
|
2340
2360
|
/**
|
|
2341
2361
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
2342
2362
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -2640,6 +2660,22 @@ declare class CartModule {
|
|
|
2640
2660
|
addItem(input: AddToCartInput): Promise<SdkResult<Cart & {
|
|
2641
2661
|
newSessionToken?: string;
|
|
2642
2662
|
}>>;
|
|
2663
|
+
/**
|
|
2664
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
2665
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
2666
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
2667
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
2668
|
+
* none exists yet.
|
|
2669
|
+
*
|
|
2670
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
2671
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
2672
|
+
*
|
|
2673
|
+
* ```ts
|
|
2674
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
2675
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
2676
|
+
* ```
|
|
2677
|
+
*/
|
|
2678
|
+
setCurrency(currency: string): Promise<SdkResult<Cart>>;
|
|
2643
2679
|
/** Update item quantity */
|
|
2644
2680
|
updateQuantity(itemId: string, quantity: number): Promise<SdkResult<Cart>>;
|
|
2645
2681
|
/** Remove item from cart */
|
package/dist/react.d.ts
CHANGED
|
@@ -73,6 +73,18 @@ interface BehioStorefrontConfig {
|
|
|
73
73
|
currency?: string;
|
|
74
74
|
/** Custom fetch implementation (for Node.js < 18 or testing) */
|
|
75
75
|
fetch?: typeof fetch;
|
|
76
|
+
/**
|
|
77
|
+
* Real visitor IP for server-side rendering. Sent as X-Behio-Visitor-Ip so
|
|
78
|
+
* the backend rate-limits per visitor instead of per server: all SSR
|
|
79
|
+
* requests of one deployment share the server's IP, so without this header
|
|
80
|
+
* the whole shop shares one rate-limit bucket. The backend only trusts the
|
|
81
|
+
* header from allow-listed hosting IPs, so a browser sending it gains
|
|
82
|
+
* nothing. Accepts a fixed string or a resolver called per request (use a
|
|
83
|
+
* resolver for a shared catalog client that serves many concurrent
|
|
84
|
+
* requests). The Next.js adapter (`@behio/storefront-sdk/next`) fills this
|
|
85
|
+
* automatically from the incoming request headers.
|
|
86
|
+
*/
|
|
87
|
+
visitorIp?: string | (() => string | null | undefined | Promise<string | null | undefined>);
|
|
76
88
|
/** Request timeout in milliseconds. Default: 30000 (30s) */
|
|
77
89
|
timeout?: number;
|
|
78
90
|
/** Number of retries on network/5xx errors. Default: 1 */
|
|
@@ -2311,6 +2323,7 @@ declare class BehioStorefront {
|
|
|
2311
2323
|
private responseInterceptors;
|
|
2312
2324
|
private rateLimitRemaining;
|
|
2313
2325
|
private rateLimitReset;
|
|
2326
|
+
private visitorIp?;
|
|
2314
2327
|
constructor(config: BehioStorefrontConfig);
|
|
2315
2328
|
readonly catalog: CatalogModule;
|
|
2316
2329
|
readonly auth: AuthModule;
|
|
@@ -2337,6 +2350,13 @@ declare class BehioStorefront {
|
|
|
2337
2350
|
setAnalyticsVisitorId(id: string | null): void;
|
|
2338
2351
|
/** The consent-gated visitor id, if analytics consent was granted. */
|
|
2339
2352
|
getAnalyticsVisitorId(): string | null;
|
|
2353
|
+
/**
|
|
2354
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
2355
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
2356
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
2357
|
+
* automatically for per-request clients.
|
|
2358
|
+
*/
|
|
2359
|
+
setVisitorIp(ip: string | null): void;
|
|
2340
2360
|
/**
|
|
2341
2361
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
2342
2362
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -2640,6 +2660,22 @@ declare class CartModule {
|
|
|
2640
2660
|
addItem(input: AddToCartInput): Promise<SdkResult<Cart & {
|
|
2641
2661
|
newSessionToken?: string;
|
|
2642
2662
|
}>>;
|
|
2663
|
+
/**
|
|
2664
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
2665
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
2666
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
2667
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
2668
|
+
* none exists yet.
|
|
2669
|
+
*
|
|
2670
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
2671
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
2672
|
+
*
|
|
2673
|
+
* ```ts
|
|
2674
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
2675
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
2676
|
+
* ```
|
|
2677
|
+
*/
|
|
2678
|
+
setCurrency(currency: string): Promise<SdkResult<Cart>>;
|
|
2643
2679
|
/** Update item quantity */
|
|
2644
2680
|
updateQuantity(itemId: string, quantity: number): Promise<SdkResult<Cart>>;
|
|
2645
2681
|
/** Remove item from cart */
|
package/dist/react.js
CHANGED
|
@@ -215,6 +215,7 @@ var BehioStorefront = class {
|
|
|
215
215
|
this.timeout = config.timeout ?? 3e4;
|
|
216
216
|
this.retries = config.retries ?? 1;
|
|
217
217
|
this.retryDelay = config.retryDelay ?? 1e3;
|
|
218
|
+
this.visitorIp = config.visitorIp;
|
|
218
219
|
this.catalog = new CatalogModule(this);
|
|
219
220
|
this.auth = new AuthModule(this);
|
|
220
221
|
this.cart = new CartModule(this);
|
|
@@ -246,6 +247,15 @@ var BehioStorefront = class {
|
|
|
246
247
|
getAnalyticsVisitorId() {
|
|
247
248
|
return this.analyticsVisitorId;
|
|
248
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
252
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
253
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
254
|
+
* automatically for per-request clients.
|
|
255
|
+
*/
|
|
256
|
+
setVisitorIp(ip) {
|
|
257
|
+
this.visitorIp = ip ?? void 0;
|
|
258
|
+
}
|
|
249
259
|
/**
|
|
250
260
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
251
261
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -511,6 +521,13 @@ var BehioStorefront = class {
|
|
|
511
521
|
if (this.analyticsVisitorId) {
|
|
512
522
|
headers["X-Behio-Vid"] = this.analyticsVisitorId;
|
|
513
523
|
}
|
|
524
|
+
if (this.visitorIp) {
|
|
525
|
+
try {
|
|
526
|
+
const ip = typeof this.visitorIp === "function" ? await this.visitorIp() : this.visitorIp;
|
|
527
|
+
if (ip) headers["X-Behio-Visitor-Ip"] = ip;
|
|
528
|
+
} catch {
|
|
529
|
+
}
|
|
530
|
+
}
|
|
514
531
|
if (options?.headers) {
|
|
515
532
|
Object.assign(headers, options.headers);
|
|
516
533
|
}
|
|
@@ -1027,6 +1044,29 @@ var CartModule = class {
|
|
|
1027
1044
|
this.client.emit("cart:updated", res.data);
|
|
1028
1045
|
return res;
|
|
1029
1046
|
}
|
|
1047
|
+
/**
|
|
1048
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
1049
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
1050
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
1051
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
1052
|
+
* none exists yet.
|
|
1053
|
+
*
|
|
1054
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
1055
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
1056
|
+
*
|
|
1057
|
+
* ```ts
|
|
1058
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
1059
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
1060
|
+
* ```
|
|
1061
|
+
*/
|
|
1062
|
+
async setCurrency(currency) {
|
|
1063
|
+
const res = await this.client.request("PUT", "/cart/currency", {
|
|
1064
|
+
body: { currency }
|
|
1065
|
+
});
|
|
1066
|
+
if (res.error) return res;
|
|
1067
|
+
this.client.emit("cart:updated", res.data);
|
|
1068
|
+
return res;
|
|
1069
|
+
}
|
|
1030
1070
|
/** Update item quantity */
|
|
1031
1071
|
async updateQuantity(itemId, quantity) {
|
|
1032
1072
|
const res = await this.client.request(
|
|
@@ -2025,9 +2065,16 @@ function BehioProvider({
|
|
|
2025
2065
|
else cookieStorage.remove(currencyCookieName);
|
|
2026
2066
|
}
|
|
2027
2067
|
onCurrencyChange?.(next);
|
|
2028
|
-
|
|
2068
|
+
const cartTarget = next ?? defaultCurrency;
|
|
2069
|
+
if (cartTarget && (client.getCartSession() || client.auth.isLoggedIn())) {
|
|
2070
|
+
void client.cart.setCurrency(cartTarget).finally(() => {
|
|
2071
|
+
void qc.invalidateQueries({ queryKey: ["behio"] });
|
|
2072
|
+
});
|
|
2073
|
+
} else {
|
|
2074
|
+
void qc.invalidateQueries({ queryKey: ["behio"] });
|
|
2075
|
+
}
|
|
2029
2076
|
},
|
|
2030
|
-
[client, qc, persistCurrency, currencyCookieName, onCurrencyChange]
|
|
2077
|
+
[client, qc, persistCurrency, currencyCookieName, onCurrencyChange, defaultCurrency]
|
|
2031
2078
|
);
|
|
2032
2079
|
const ctxValue = (0, import_react2.useMemo)(
|
|
2033
2080
|
() => ({
|
package/dist/react.mjs
CHANGED
|
@@ -112,6 +112,7 @@ var BehioStorefront = class {
|
|
|
112
112
|
this.timeout = config.timeout ?? 3e4;
|
|
113
113
|
this.retries = config.retries ?? 1;
|
|
114
114
|
this.retryDelay = config.retryDelay ?? 1e3;
|
|
115
|
+
this.visitorIp = config.visitorIp;
|
|
115
116
|
this.catalog = new CatalogModule(this);
|
|
116
117
|
this.auth = new AuthModule(this);
|
|
117
118
|
this.cart = new CartModule(this);
|
|
@@ -143,6 +144,15 @@ var BehioStorefront = class {
|
|
|
143
144
|
getAnalyticsVisitorId() {
|
|
144
145
|
return this.analyticsVisitorId;
|
|
145
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Set (or clear with null) the real visitor IP forwarded as
|
|
149
|
+
* X-Behio-Visitor-Ip on server-side requests. See
|
|
150
|
+
* `BehioStorefrontConfig.visitorIp` for why. The Next.js adapter calls this
|
|
151
|
+
* automatically for per-request clients.
|
|
152
|
+
*/
|
|
153
|
+
setVisitorIp(ip) {
|
|
154
|
+
this.visitorIp = ip ?? void 0;
|
|
155
|
+
}
|
|
146
156
|
/**
|
|
147
157
|
* Fire-and-forget Behio Analytics ingest. Uses a bare keepalive fetch (not
|
|
148
158
|
* the interceptor pipeline) so flushes on pagehide still land, and swallows
|
|
@@ -408,6 +418,13 @@ var BehioStorefront = class {
|
|
|
408
418
|
if (this.analyticsVisitorId) {
|
|
409
419
|
headers["X-Behio-Vid"] = this.analyticsVisitorId;
|
|
410
420
|
}
|
|
421
|
+
if (this.visitorIp) {
|
|
422
|
+
try {
|
|
423
|
+
const ip = typeof this.visitorIp === "function" ? await this.visitorIp() : this.visitorIp;
|
|
424
|
+
if (ip) headers["X-Behio-Visitor-Ip"] = ip;
|
|
425
|
+
} catch {
|
|
426
|
+
}
|
|
427
|
+
}
|
|
411
428
|
if (options?.headers) {
|
|
412
429
|
Object.assign(headers, options.headers);
|
|
413
430
|
}
|
|
@@ -924,6 +941,29 @@ var CartModule = class {
|
|
|
924
941
|
this.client.emit("cart:updated", res.data);
|
|
925
942
|
return res;
|
|
926
943
|
}
|
|
944
|
+
/**
|
|
945
|
+
* Switch the CART currency server-side. The backend re-prices every line in
|
|
946
|
+
* the new currency (no FX conversion: a product must have a price configured
|
|
947
|
+
* in that currency, otherwise the call fails with 400 listing the items and
|
|
948
|
+
* the cart stays unchanged). Creates an empty cart in that currency when
|
|
949
|
+
* none exists yet.
|
|
950
|
+
*
|
|
951
|
+
* This is the money-path counterpart of `client.setCurrency()` (which only
|
|
952
|
+
* affects catalog display). Call BOTH from a currency switcher:
|
|
953
|
+
*
|
|
954
|
+
* ```ts
|
|
955
|
+
* client.setCurrency("EUR"); // catalog prices
|
|
956
|
+
* await client.cart.setCurrency("EUR"); // cart + checkout prices
|
|
957
|
+
* ```
|
|
958
|
+
*/
|
|
959
|
+
async setCurrency(currency) {
|
|
960
|
+
const res = await this.client.request("PUT", "/cart/currency", {
|
|
961
|
+
body: { currency }
|
|
962
|
+
});
|
|
963
|
+
if (res.error) return res;
|
|
964
|
+
this.client.emit("cart:updated", res.data);
|
|
965
|
+
return res;
|
|
966
|
+
}
|
|
927
967
|
/** Update item quantity */
|
|
928
968
|
async updateQuantity(itemId, quantity) {
|
|
929
969
|
const res = await this.client.request(
|
|
@@ -1922,9 +1962,16 @@ function BehioProvider({
|
|
|
1922
1962
|
else cookieStorage.remove(currencyCookieName);
|
|
1923
1963
|
}
|
|
1924
1964
|
onCurrencyChange?.(next);
|
|
1925
|
-
|
|
1965
|
+
const cartTarget = next ?? defaultCurrency;
|
|
1966
|
+
if (cartTarget && (client.getCartSession() || client.auth.isLoggedIn())) {
|
|
1967
|
+
void client.cart.setCurrency(cartTarget).finally(() => {
|
|
1968
|
+
void qc.invalidateQueries({ queryKey: ["behio"] });
|
|
1969
|
+
});
|
|
1970
|
+
} else {
|
|
1971
|
+
void qc.invalidateQueries({ queryKey: ["behio"] });
|
|
1972
|
+
}
|
|
1926
1973
|
},
|
|
1927
|
-
[client, qc, persistCurrency, currencyCookieName, onCurrencyChange]
|
|
1974
|
+
[client, qc, persistCurrency, currencyCookieName, onCurrencyChange, defaultCurrency]
|
|
1928
1975
|
);
|
|
1929
1976
|
const ctxValue = useMemo(
|
|
1930
1977
|
() => ({
|