@behio/storefront-sdk 2.29.0 → 2.31.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/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
- import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent, b as StorefrontFormFieldError } from './client-CAPtdqzd.js';
2
- export { A as ActivePromotion, c as AddToCartInput, d as AddToCartItemsInput, e as AddressDetail, f as AddressSuggestion, g as AddressType, h as AddressTypes, i as AuthTokens, j as BackInStockSubscription, k as BadgeTone, l as BehioApiError, m as BehioErrorCode, n as BehioEventHandler, o as BehioEventType, p as BehioNetworkError, q as BehioStorefrontConfig, r as Blog, s as BlogPostDetail, t as BlogPostListItem, u as BlogPostsPage, v as BlogPostsQuery, w as BlogSettings, x as BlogTag, y as Booking, z as BookingCategory, D as BookingConfig, E as BookingCreateInput, F as BookingCreated, G as BookingLocale, H as BookingLocation, I as BookingManageSlotsQuery, J as BookingService, K as BookingSlot, L as BookingSlots, M as BookingSlotsQuery, N as BookingStaff, O as BookingStatus, Q as Bundle, R as BundleCatalogQuery, T as BundleItem, U as Cart, V as CartBundleLine, W as CartBundleLineItem, X as CartDiscount, Y as CartItem, Z as CartItemProduct, _ as CartLinkClaimed, $ as CartPromotion, a0 as CartSummaryEvent, a1 as Category, a2 as CategoryDetail, a3 as CertificateVerification, a4 as CheckoutAddress, a5 as CheckoutInput, a6 as CheckoutPaymentMethod, a7 as CheckoutPreview, a8 as CheckoutResult, a9 as CheckoutSettings, aa as CookieConsentInput, ab as CourseAttachment, ac as CourseCertificate, ad as CourseComment, ae as CourseCommentReply, af as CourseCommentsList, ag as CourseDetail, ah as CourseLesson, ai as CourseListItem, aj as CourseModule, ak as CoursePostedComment, al as CourseProgress, am as CourseTutorMessage, an as CourseTutorThread, ao as CrossSellItem, ap as CurrencyDisplayFormat, aq as CustomerAddress, ar as CustomerBadge, as as CustomerChallenge, at as CustomerGamification, au as CustomerGamificationQuery, av as CustomerProfile, aw as DigitalDownload, ax as DownloadUrl, ay as Facet, az as FacetAvailability, aA as FacetCategory, aB as FacetLabel, aC as FacetPriceRange, aD as FacetRange, aE as FacetRatingBucket, aF as FacetValue, aG as FacetsResponse, aH as FilterField, aI as FulfillmentStatus, aJ as FulfillmentStatuses, aK as GamificationRefreshResult, aL as GiftCardBalance, aM as GiftCardPurchaseInput, aN as GiftCardPurchaseResult, aO as GiftCardSummary, aP as LessonNote, aQ as LessonQuiz, aR as LoginInput, aS as LoyaltyBalance, aT as LoyaltyNextTier, aU as LoyaltyProgram, aV as LoyaltyQuery, aW as LoyaltyReferralResult, aX as LoyaltySummary, aY as LoyaltyTier, aZ as LoyaltyTierPerks, a_ as LoyaltyTransaction, a$ as Menu, b0 as MenuItem, b1 as MenuItemRef, b2 as MenuItemType, b3 as MessageResponse, b4 as NewsletterConfirmResult, b5 as NewsletterOptInDefault, b6 as NewsletterSubscribeInput, b7 as NewsletterSubscribeResult, b8 as NewsletterUnsubscribeResult, b9 as OrderAccessRequestResponse, ba as OrderAccessVerifyResponse, bb as OrderDetail, bc as OrderDiscount, bd as OrderDocument, be as OrderItem, bf as OrderListItem, bg as OrderPaymentInstructions, bh as OrderPickupPoint, bi as OrderShipment, bj as OrderStatus, bk as OrderStatusHistory, bl as OrderStatuses, bm as OrderTracking, bn as Page, bo as PageAttachment, bp as PageDetail, bq as PaginatedResponse, br as PaymentInstrument, bs as PaymentStatus, bt as PaymentStatuses, bu as PaymentSwift, bv as PickupPoint, bw as PickupPointHours, bx as PickupPointsInput, by as PickupWidgetConfig, bz as PriceDisplay, bA as ProductAssetGroup, bB as ProductAssetItem, bC as ProductAvailability, bD as ProductGroup, bE as ProductLabel, bF as ProductListItem, bG as ProductMedia, bH as ProductMediaVariant, bI as ProductParameter, bJ as ProductParameterGroup, bK as ProductParametersResponse, bL as ProductPrice, bM as ProductPromotionSummary, bN as ProductReview, bO as ProductReviewsResponse, bP as ProductSibling, bQ as ProductSort, bR as ProductSortValue, bS as ProductVolumePrice, bT as ProductsQuery, bU as QuizAnswerInput, bV as QuizAnswerResult, bW as QuizQuestion, bX as QuizResult, bY as QuoteItem, bZ as QuoteRequest, b_ as RegisterInput, b$ as RegisterResult, c0 as RequestInterceptor, c1 as RequestInterceptorConfig, c2 as ResponseInterceptor, c3 as ResponseInterceptorData, c4 as ReturnRequest, c5 as ReturnRequestItem, c6 as ReturnStatus, c7 as ReturnStatusItem, c8 as ReturnableOrder, c9 as ReturnableOrderItem, ca as SdkError, cb as ShippingMethodSummary, cc as ShippingPublicConfig, cd as ShippingQuote, ce as ShippingQuoteInput, cf as ShopAppearance, cg as ShopCommerce, ch as ShopInfo, ci as ShopScript, cj as ShopScriptPlacement, ck as ShopScriptType, cl as ShopScripts, cm as ShopSeo, cn as ShopSeoIdentity, co as SiteFormField, cp as SiteFormFieldOption, cq as SiteFormFieldType, cr as Sitemap, cs as SitemapEntry, ct as StockBehavior, cu as StockMode, cv as StorefrontCollection, cw as StorefrontCollectionField, cx as StorefrontCollectionFieldType, cy as StorefrontCollectionItem, cz as StorefrontCollectionQuery, cA as StorefrontFaqGroup, cB as StorefrontFaqGroupSummary, cC as StorefrontFaqGroups, cD as StorefrontFaqItem, cE as StorefrontFaqQuery, cF as StorefrontForm, cG as StorefrontFormFieldErrorCode, cH as StorefrontFormFile, cI as StorefrontFormSettings, cJ as StorefrontFormSubmitInput, cK as StorefrontFormSubmitResult, cL as StorefrontFormUpload, cM as SubmitQuoteInput, cN as SubmitReturnInput, cO as SubmitReviewInput, cP as SubmitWithdrawalInput, cQ as Subscription, cR as SubscriptionAction, cS as SubscriptionFrequency, cT as SubscriptionItem, cU as SubscriptionStatus, cV as TaxBreakdownLine, cW as VariantAxis, cX as VariantAxisValue, cY as WishlistItem, cZ as WithdrawalAcknowledgement, c_ as WithdrawalFlag, c$ as WithdrawalSettings, d0 as WithdrawalWindow, d1 as clearCartSummary, d2 as err, d3 as ok, d4 as publishCartSummary, d5 as toSdkError } from './client-CAPtdqzd.js';
1
+ import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent, b as StorefrontFormFieldError, c as StorefrontFormPlacement } from './client-DeAREmgD.js';
2
+ export { A as ActivePromotion, d as AddToCartInput, e as AddToCartItemsInput, f as AddressDetail, g as AddressSuggestion, h as AddressType, i as AddressTypes, j as AuthTokens, k as BackInStockSubscription, l as BadgeTone, m as BehioApiError, n as BehioErrorCode, o as BehioEventHandler, p as BehioEventType, q as BehioNetworkError, r as BehioStorefrontConfig, s as Blog, t as BlogPostDetail, u as BlogPostListItem, v as BlogPostsPage, w as BlogPostsQuery, x as BlogSettings, y as BlogTag, z as Booking, D as BookingCategory, E as BookingConfig, F as BookingCreateInput, G as BookingCreated, H as BookingLocale, I as BookingLocation, J as BookingManageSlotsQuery, K as BookingService, L as BookingSlot, M as BookingSlots, N as BookingSlotsQuery, O as BookingStaff, Q as BookingStatus, R as Bundle, T as BundleCatalogQuery, U as BundleItem, V as Cart, W as CartBundleLine, X as CartBundleLineItem, Y as CartDiscount, Z as CartItem, _ as CartItemProduct, $ as CartLinkClaimed, a0 as CartPromotion, a1 as CartSummaryEvent, a2 as Category, a3 as CategoryDetail, a4 as CertificateVerification, a5 as CheckoutAddress, a6 as CheckoutInput, a7 as CheckoutPaymentMethod, a8 as CheckoutPreview, a9 as CheckoutResult, aa as CheckoutSettings, ab as CookieConsentInput, ac as CourseAttachment, ad as CourseCertificate, ae as CourseComment, af as CourseCommentReply, ag as CourseCommentsList, ah as CourseDetail, ai as CourseLesson, aj as CourseListItem, ak as CourseModule, al as CoursePostedComment, am as CourseProgress, an as CourseTutorMessage, ao as CourseTutorThread, ap as CrossSellItem, aq as CurrencyDisplayFormat, ar as CustomerAddress, as as CustomerBadge, at as CustomerChallenge, au as CustomerGamification, av as CustomerGamificationQuery, aw as CustomerProfile, ax as DigitalDownload, ay as DownloadUrl, az as Facet, aA as FacetAvailability, aB as FacetCategory, aC as FacetLabel, aD as FacetPriceRange, aE as FacetRange, aF as FacetRatingBucket, aG as FacetValue, aH as FacetsResponse, aI as FilterField, aJ as FulfillmentStatus, aK as FulfillmentStatuses, aL as GamificationRefreshResult, aM as GiftCardBalance, aN as GiftCardPurchaseInput, aO as GiftCardPurchaseResult, aP as GiftCardSummary, aQ as LessonNote, aR as LessonQuiz, aS as LoginInput, aT as LoyaltyBalance, aU as LoyaltyNextTier, aV as LoyaltyProgram, aW as LoyaltyQuery, aX as LoyaltyReferralResult, aY as LoyaltySummary, aZ as LoyaltyTier, a_ as LoyaltyTierPerks, a$ as LoyaltyTransaction, b0 as Menu, b1 as MenuItem, b2 as MenuItemRef, b3 as MenuItemType, b4 as MessageResponse, b5 as NewsletterConfirmResult, b6 as NewsletterOptInDefault, b7 as NewsletterSubscribeInput, b8 as NewsletterSubscribeResult, b9 as NewsletterUnsubscribeInput, ba as NewsletterUnsubscribeResult, bb as OrderAccessRequestResponse, bc as OrderAccessVerifyResponse, bd as OrderDetail, be as OrderDiscount, bf as OrderDocument, bg as OrderItem, bh as OrderListItem, bi as OrderPaymentInstructions, bj as OrderPickupPoint, bk as OrderShipment, bl as OrderStatus, bm as OrderStatusHistory, bn as OrderStatuses, bo as OrderTracking, bp as Page, bq as PageAttachment, br as PageDetail, bs as PaginatedResponse, bt as PaymentInstrument, bu as PaymentStatus, bv as PaymentStatuses, bw as PaymentSwift, bx as PickupPoint, by as PickupPointHours, bz as PickupPointsInput, bA as PickupWidgetConfig, bB as PriceDisplay, bC as ProductAssetGroup, bD as ProductAssetItem, bE as ProductAvailability, bF as ProductGroup, bG as ProductLabel, bH as ProductListItem, bI as ProductMedia, bJ as ProductMediaVariant, bK as ProductParameter, bL as ProductParameterGroup, bM as ProductParametersResponse, bN as ProductPrice, bO as ProductPromotionSummary, bP as ProductReview, bQ as ProductReviewsResponse, bR as ProductSibling, bS as ProductSort, bT as ProductSortValue, bU as ProductVolumePrice, bV as ProductsQuery, bW as QuizAnswerInput, bX as QuizAnswerResult, bY as QuizQuestion, bZ as QuizResult, b_ as QuoteItem, b$ as QuoteRequest, c0 as RegisterInput, c1 as RegisterResult, c2 as RequestInterceptor, c3 as RequestInterceptorConfig, c4 as ResponseInterceptor, c5 as ResponseInterceptorData, c6 as ReturnRequest, c7 as ReturnRequestItem, c8 as ReturnStatus, c9 as ReturnStatusItem, ca as ReturnableOrder, cb as ReturnableOrderItem, cc as SdkError, cd as ShippingMethodSummary, ce as ShippingPublicConfig, cf as ShippingQuote, cg as ShippingQuoteInput, ch as ShopAppearance, ci as ShopCommerce, cj as ShopInfo, ck as ShopScript, cl as ShopScriptPlacement, cm as ShopScriptType, cn as ShopScripts, co as ShopSeo, cp as ShopSeoIdentity, cq as SiteFormField, cr as SiteFormFieldOption, cs as SiteFormFieldType, ct as Sitemap, cu as SitemapEntry, cv as StockBehavior, cw as StockMode, cx as StorefrontCollection, cy as StorefrontCollectionField, cz as StorefrontCollectionFieldType, cA as StorefrontCollectionItem, cB as StorefrontCollectionQuery, cC as StorefrontFaqGroup, cD as StorefrontFaqGroupSummary, cE as StorefrontFaqGroups, cF as StorefrontFaqItem, cG as StorefrontFaqQuery, cH as StorefrontForm, cI as StorefrontFormFieldErrorCode, cJ as StorefrontFormFile, cK as StorefrontFormPresentation, cL as StorefrontFormSettings, cM as StorefrontFormSubmitInput, cN as StorefrontFormSubmitResult, cO as StorefrontFormUpload, cP as SubmitQuoteInput, cQ as SubmitReturnInput, cR as SubmitReviewInput, cS as SubmitWithdrawalInput, cT as Subscription, cU as SubscriptionAction, cV as SubscriptionFrequency, cW as SubscriptionItem, cX as SubscriptionStatus, cY as TaxBreakdownLine, cZ as VariantAxis, c_ as VariantAxisValue, c$ as WishlistItem, d0 as WithdrawalAcknowledgement, d1 as WithdrawalFlag, d2 as WithdrawalSettings, d3 as WithdrawalWindow, d4 as clearCartSummary, d5 as err, d6 as ok, d7 as publishCartSummary, d8 as toSdkError } from './client-DeAREmgD.js';
3
+
4
+ interface HeaderReader {
5
+ get(name: string): string | null;
6
+ }
7
+ declare function trustedVisitorIp(headers: HeaderReader, originSecret?: string | null): string | undefined;
3
8
 
4
9
  /**
5
10
  * Format a price amount with currency using Intl.NumberFormat.
@@ -140,7 +145,7 @@ declare function buildVariantComparison(product: ProductDetail, labels: {
140
145
  * Consent stays the script layer's job: this helper never loads anything, it
141
146
  * only talks to runtimes that already exist on the page.
142
147
  */
143
- type EcommerceEventName = "view_item" | "view_item_list" | "select_item" | "add_to_cart" | "remove_from_cart" | "view_cart" | "add_to_wishlist" | "view_promotion" | "select_promotion" | "begin_checkout" | "add_payment_info" | "add_shipping_info" | "search" | "generate_lead" | "purchase" | "variant_selected" | "newsletter_signup";
148
+ type EcommerceEventName = "view_item" | "view_item_list" | "select_item" | "add_to_cart" | "remove_from_cart" | "view_cart" | "add_to_wishlist" | "view_promotion" | "select_promotion" | "begin_checkout" | "add_payment_info" | "add_shipping_info" | "search" | "generate_lead" | "purchase" | "variant_selected" | "newsletter_signup" | "newsletter_request" | "form_popup_view";
144
149
  type EcommerceItem = {
145
150
  item_id: string;
146
151
  item_name: string;
@@ -269,4 +274,38 @@ declare function validationFieldMessages(err: unknown, locale?: ErrorMessageLoca
269
274
  */
270
275
  declare function formFieldErrors(err: unknown): StorefrontFormFieldError[];
271
276
 
272
- export { BehioStorefront, CookieConsent, type EcommerceEventName, type EcommerceItem, type EcommercePayload, type ErrorMessageLocale, ProductDetail, ProductVariant, type ResolvedVariantContent, SdkResult, StorefrontFormFieldError, VARIANT_QUERY_PARAM, type VariantComparisonRow, availableAxisValues, buildVariantComparison, errorCode, errorMessage, errorParams, findVariantByAttributes, formFieldErrors, formatPrice, generateVisitorId, getStoredVisitorId, grantAnalyticsConsent, resolveVariantContent, revokeAnalyticsConsent, trackEcommerceEvent, validationFieldMessages, variantFromQuery, variantHref };
277
+ interface StorageAdapter {
278
+ get(key: string): string | null;
279
+ set(key: string, value: string): void;
280
+ remove(key: string): void;
281
+ }
282
+
283
+ declare const NEWSLETTER_REQUESTED_EVENT = "behio:newsletter-requested";
284
+ /** A preference only, no email, subscriber lookup, visitor id or fingerprint. Pending confirmation counts too. */
285
+ declare function markNewsletterRequested(): void;
286
+ declare function newsletterWasRequested(): boolean;
287
+ declare function matchesFormPath(rule: string, pathname: string): boolean;
288
+ declare function formPopupRouteAllowed(pathname: string, placement: StorefrontFormPlacement): boolean;
289
+ /** Visible time survives hard navigation. Hidden time is never persisted as active time. */
290
+ declare class FormPopupClock {
291
+ elapsedMs: number;
292
+ private since;
293
+ constructor(elapsedMs?: number);
294
+ setVisible(visible: boolean, now: number): void;
295
+ elapsed(now: number): number;
296
+ }
297
+ declare class FormPopupPreferences {
298
+ private session;
299
+ private persistent;
300
+ private now;
301
+ private shownInVisit;
302
+ constructor(session?: StorageAdapter, persistent?: StorageAdapter, now?: () => number);
303
+ private number;
304
+ visibleMs(): number;
305
+ saveTime(visible: number): void;
306
+ suppressed(slug: string, newsletter?: boolean): boolean;
307
+ shown(): void;
308
+ dismiss(slug: string, days: number): void;
309
+ }
310
+
311
+ export { BehioStorefront, CookieConsent, type EcommerceEventName, type EcommerceItem, type EcommercePayload, type ErrorMessageLocale, FormPopupClock, FormPopupPreferences, type HeaderReader, NEWSLETTER_REQUESTED_EVENT, ProductDetail, ProductVariant, type ResolvedVariantContent, SdkResult, StorefrontFormFieldError, StorefrontFormPlacement, VARIANT_QUERY_PARAM, type VariantComparisonRow, availableAxisValues, buildVariantComparison, errorCode, errorMessage, errorParams, findVariantByAttributes, formFieldErrors, formPopupRouteAllowed, formatPrice, generateVisitorId, getStoredVisitorId, grantAnalyticsConsent, markNewsletterRequested, matchesFormPath, newsletterWasRequested, resolveVariantContent, revokeAnalyticsConsent, trackEcommerceEvent, trustedVisitorIp, validationFieldMessages, variantFromQuery, variantHref };
package/dist/index.js CHANGED
@@ -12,7 +12,8 @@
12
12
 
13
13
 
14
14
 
15
- var _chunkSBPQZG4Yjs = require('./chunk-SBPQZG4Y.js');
15
+
16
+ var _chunkQU4OFGKKjs = require('./chunk-QU4OFGKK.js');
16
17
 
17
18
  // src/react/utils/format-price.ts
18
19
  function formatPrice(amount, currency, locale, display) {
@@ -1118,7 +1119,7 @@ var GENERIC = {
1118
1119
  en: "Something went wrong, please try again."
1119
1120
  };
1120
1121
  function bodyOf(err2) {
1121
- const body = err2 instanceof _chunkSBPQZG4Yjs.BehioApiError ? err2.body : err2 && typeof err2 === "object" && "body" in err2 ? err2.body : err2;
1122
+ const body = err2 instanceof _chunkQU4OFGKKjs.BehioApiError ? err2.body : err2 && typeof err2 === "object" && "body" in err2 ? err2.body : err2;
1122
1123
  return body && typeof body === "object" ? body : null;
1123
1124
  }
1124
1125
  function errorCode(err2) {
@@ -1204,6 +1205,156 @@ function formFieldErrors(err2) {
1204
1205
  return out;
1205
1206
  }
1206
1207
 
1208
+ // src/react/storage.ts
1209
+ var localStorageAdapter = {
1210
+ get(key) {
1211
+ try {
1212
+ return window.localStorage.getItem(key);
1213
+ } catch (e9) {
1214
+ return null;
1215
+ }
1216
+ },
1217
+ set(key, value) {
1218
+ try {
1219
+ window.localStorage.setItem(key, value);
1220
+ } catch (e10) {
1221
+ }
1222
+ },
1223
+ remove(key) {
1224
+ try {
1225
+ window.localStorage.removeItem(key);
1226
+ } catch (e11) {
1227
+ }
1228
+ }
1229
+ };
1230
+ function createMemoryStorage() {
1231
+ const store = /* @__PURE__ */ new Map();
1232
+ return {
1233
+ get(key) {
1234
+ return _nullishCoalesce(store.get(key), () => ( null));
1235
+ },
1236
+ set(key, value) {
1237
+ store.set(key, value);
1238
+ },
1239
+ remove(key) {
1240
+ store.delete(key);
1241
+ }
1242
+ };
1243
+ }
1244
+ var memoryStorage = createMemoryStorage();
1245
+
1246
+ // src/form-popup.ts
1247
+ function preferenceMemory() {
1248
+ if (typeof window === "undefined") return /* @__PURE__ */ new Map();
1249
+ const browser = window;
1250
+ return _nullishCoalesce(browser.__behioFormPreferences, () => ( (browser.__behioFormPreferences = /* @__PURE__ */ new Map())));
1251
+ }
1252
+ var memoryAdapter = { get: (k) => _nullishCoalesce(preferenceMemory().get(k), () => ( null)), set: (k, v) => {
1253
+ preferenceMemory().set(k, v);
1254
+ }, remove: (k) => {
1255
+ preferenceMemory().delete(k);
1256
+ } };
1257
+ var NEWSLETTER_REQUESTED_EVENT = "behio:newsletter-requested";
1258
+ var PREFIX = "behio:forms:";
1259
+ var VISIT_MS = 30 * 60 * 1e3;
1260
+ function sessionAdapter() {
1261
+ return { get: (key) => {
1262
+ try {
1263
+ return _nullishCoalesce(sessionStorage.getItem(key), () => ( memoryAdapter.get(key)));
1264
+ } catch (e12) {
1265
+ return memoryAdapter.get(key);
1266
+ }
1267
+ }, set: (key, value) => {
1268
+ memoryAdapter.set(key, value);
1269
+ try {
1270
+ sessionStorage.setItem(key, value);
1271
+ } catch (e13) {
1272
+ }
1273
+ }, remove: (key) => {
1274
+ memoryAdapter.remove(key);
1275
+ try {
1276
+ sessionStorage.removeItem(key);
1277
+ } catch (e14) {
1278
+ }
1279
+ } };
1280
+ }
1281
+ function markNewsletterRequested() {
1282
+ if (typeof window === "undefined") return;
1283
+ memoryAdapter.set(PREFIX + "newsletter", "1");
1284
+ localStorageAdapter.set(PREFIX + "newsletter", "1");
1285
+ if (typeof window !== "undefined") window.dispatchEvent(new Event(NEWSLETTER_REQUESTED_EVENT));
1286
+ }
1287
+ function newsletterWasRequested() {
1288
+ return memoryAdapter.get(PREFIX + "newsletter") === "1" || localStorageAdapter.get(PREFIX + "newsletter") === "1";
1289
+ }
1290
+ function matchesFormPath(rule, pathname) {
1291
+ return rule.endsWith("*") ? pathname.startsWith(rule.slice(0, -1)) : pathname === rule;
1292
+ }
1293
+ function formPopupRouteAllowed(pathname, placement) {
1294
+ if (/^\/(cart|checkout|account|order|newsletter|login|register|forgot-password|reset-password|verify-email|session)(\/|$)/.test(pathname)) return false;
1295
+ return (!placement.includePaths.length || placement.includePaths.some((rule) => matchesFormPath(rule, pathname))) && !placement.excludePaths.some((rule) => matchesFormPath(rule, pathname));
1296
+ }
1297
+ var FormPopupClock = class {
1298
+ constructor(elapsedMs = 0) {
1299
+ this.since = null;
1300
+ this.elapsedMs = Math.max(0, elapsedMs);
1301
+ }
1302
+ setVisible(visible, now) {
1303
+ if (this.since !== null) this.elapsedMs += Math.max(0, now - this.since);
1304
+ this.since = visible ? now : null;
1305
+ }
1306
+ elapsed(now) {
1307
+ return this.elapsedMs + (this.since === null ? 0 : Math.max(0, now - this.since));
1308
+ }
1309
+ };
1310
+ var FormPopupPreferences = class {
1311
+ constructor(session = sessionAdapter(), persistent = localStorageAdapter, now = () => Date.now()) {
1312
+ this.session = session;
1313
+ this.persistent = persistent;
1314
+ this.now = now;
1315
+ this.shownInVisit = this.number("shown", this.session) > this.now() || this.number("shown", this.persistent) > this.now();
1316
+ }
1317
+ number(key, storage) {
1318
+ const n = Number(storage.get(PREFIX + key));
1319
+ return Number.isFinite(n) && n >= 0 ? n : 0;
1320
+ }
1321
+ visibleMs() {
1322
+ return this.now() - this.number("activity", this.session) < VISIT_MS ? this.number("visible", this.session) : 0;
1323
+ }
1324
+ saveTime(visible) {
1325
+ if (this.shownInVisit) {
1326
+ const until = String(this.now() + VISIT_MS);
1327
+ this.session.set(PREFIX + "shown", until);
1328
+ this.persistent.set(PREFIX + "shown", until);
1329
+ }
1330
+ this.session.set(PREFIX + "visible", String(visible));
1331
+ this.session.set(PREFIX + "activity", String(this.now()));
1332
+ }
1333
+ suppressed(slug, newsletter = false) {
1334
+ return newsletter && newsletterWasRequested() || this.shownInVisit || this.number("shown", this.session) > this.now() || this.number("shown", this.persistent) > this.now() || this.number("dismissed:" + slug, this.persistent) > this.now() || this.number("dismissed:" + slug, this.session) > this.now();
1335
+ }
1336
+ shown() {
1337
+ this.shownInVisit = true;
1338
+ const until = String(this.now() + VISIT_MS);
1339
+ this.session.set(PREFIX + "shown", until);
1340
+ this.persistent.set(PREFIX + "shown", until);
1341
+ }
1342
+ dismiss(slug, days) {
1343
+ const key = PREFIX + "dismissed:" + slug;
1344
+ const until = String(this.now() + days * 864e5);
1345
+ this.session.set(key, until);
1346
+ this.persistent.set(key, until);
1347
+ }
1348
+ };
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1207
1358
 
1208
1359
 
1209
1360
 
@@ -1235,4 +1386,4 @@ function formFieldErrors(err2) {
1235
1386
 
1236
1387
 
1237
1388
 
1238
- exports.AddressTypes = _chunkSBPQZG4Yjs.AddressTypes; exports.BehioApiError = _chunkSBPQZG4Yjs.BehioApiError; exports.BehioNetworkError = _chunkSBPQZG4Yjs.BehioNetworkError; exports.BehioStorefront = _chunkSBPQZG4Yjs.BehioStorefront; exports.FulfillmentStatuses = _chunkSBPQZG4Yjs.FulfillmentStatuses; exports.OrderStatuses = _chunkSBPQZG4Yjs.OrderStatuses; exports.PaymentStatuses = _chunkSBPQZG4Yjs.PaymentStatuses; exports.ProductSort = _chunkSBPQZG4Yjs.ProductSort; exports.VARIANT_QUERY_PARAM = VARIANT_QUERY_PARAM; exports.availableAxisValues = availableAxisValues; exports.buildVariantComparison = buildVariantComparison; exports.clearCartSummary = _chunkSBPQZG4Yjs.clearCartSummary; exports.err = _chunkSBPQZG4Yjs.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 = _chunkSBPQZG4Yjs.ok; exports.publishCartSummary = _chunkSBPQZG4Yjs.publishCartSummary; exports.resolveVariantContent = resolveVariantContent; exports.revokeAnalyticsConsent = revokeAnalyticsConsent; exports.toSdkError = _chunkSBPQZG4Yjs.toSdkError; exports.trackEcommerceEvent = trackEcommerceEvent; exports.validationFieldMessages = validationFieldMessages; exports.variantFromQuery = variantFromQuery; exports.variantHref = variantHref;
1389
+ exports.AddressTypes = _chunkQU4OFGKKjs.AddressTypes; exports.BehioApiError = _chunkQU4OFGKKjs.BehioApiError; exports.BehioNetworkError = _chunkQU4OFGKKjs.BehioNetworkError; exports.BehioStorefront = _chunkQU4OFGKKjs.BehioStorefront; exports.FormPopupClock = FormPopupClock; exports.FormPopupPreferences = FormPopupPreferences; exports.FulfillmentStatuses = _chunkQU4OFGKKjs.FulfillmentStatuses; exports.NEWSLETTER_REQUESTED_EVENT = NEWSLETTER_REQUESTED_EVENT; exports.OrderStatuses = _chunkQU4OFGKKjs.OrderStatuses; exports.PaymentStatuses = _chunkQU4OFGKKjs.PaymentStatuses; exports.ProductSort = _chunkQU4OFGKKjs.ProductSort; exports.VARIANT_QUERY_PARAM = VARIANT_QUERY_PARAM; exports.availableAxisValues = availableAxisValues; exports.buildVariantComparison = buildVariantComparison; exports.clearCartSummary = _chunkQU4OFGKKjs.clearCartSummary; exports.err = _chunkQU4OFGKKjs.err; exports.errorCode = errorCode; exports.errorMessage = errorMessage; exports.errorParams = errorParams; exports.findVariantByAttributes = findVariantByAttributes; exports.formFieldErrors = formFieldErrors; exports.formPopupRouteAllowed = formPopupRouteAllowed; exports.formatPrice = formatPrice; exports.generateVisitorId = generateVisitorId; exports.getStoredVisitorId = getStoredVisitorId; exports.grantAnalyticsConsent = grantAnalyticsConsent; exports.markNewsletterRequested = markNewsletterRequested; exports.matchesFormPath = matchesFormPath; exports.newsletterWasRequested = newsletterWasRequested; exports.ok = _chunkQU4OFGKKjs.ok; exports.publishCartSummary = _chunkQU4OFGKKjs.publishCartSummary; exports.resolveVariantContent = resolveVariantContent; exports.revokeAnalyticsConsent = revokeAnalyticsConsent; exports.toSdkError = _chunkQU4OFGKKjs.toSdkError; exports.trackEcommerceEvent = trackEcommerceEvent; exports.trustedVisitorIp = _chunkQU4OFGKKjs.trustedVisitorIp; exports.validationFieldMessages = validationFieldMessages; exports.variantFromQuery = variantFromQuery; exports.variantHref = variantHref;
package/dist/index.mjs CHANGED
@@ -11,8 +11,9 @@ import {
11
11
  err,
12
12
  ok,
13
13
  publishCartSummary,
14
- toSdkError
15
- } from "./chunk-YDZ2OF4O.mjs";
14
+ toSdkError,
15
+ trustedVisitorIp
16
+ } from "./chunk-SGMFDMIW.mjs";
16
17
 
17
18
  // src/react/utils/format-price.ts
18
19
  function formatPrice(amount, currency, locale, display) {
@@ -1203,12 +1204,157 @@ function formFieldErrors(err2) {
1203
1204
  }
1204
1205
  return out;
1205
1206
  }
1207
+
1208
+ // src/react/storage.ts
1209
+ var localStorageAdapter = {
1210
+ get(key) {
1211
+ try {
1212
+ return window.localStorage.getItem(key);
1213
+ } catch {
1214
+ return null;
1215
+ }
1216
+ },
1217
+ set(key, value) {
1218
+ try {
1219
+ window.localStorage.setItem(key, value);
1220
+ } catch {
1221
+ }
1222
+ },
1223
+ remove(key) {
1224
+ try {
1225
+ window.localStorage.removeItem(key);
1226
+ } catch {
1227
+ }
1228
+ }
1229
+ };
1230
+ function createMemoryStorage() {
1231
+ const store = /* @__PURE__ */ new Map();
1232
+ return {
1233
+ get(key) {
1234
+ return store.get(key) ?? null;
1235
+ },
1236
+ set(key, value) {
1237
+ store.set(key, value);
1238
+ },
1239
+ remove(key) {
1240
+ store.delete(key);
1241
+ }
1242
+ };
1243
+ }
1244
+ var memoryStorage = createMemoryStorage();
1245
+
1246
+ // src/form-popup.ts
1247
+ function preferenceMemory() {
1248
+ if (typeof window === "undefined") return /* @__PURE__ */ new Map();
1249
+ const browser = window;
1250
+ return browser.__behioFormPreferences ?? (browser.__behioFormPreferences = /* @__PURE__ */ new Map());
1251
+ }
1252
+ var memoryAdapter = { get: (k) => preferenceMemory().get(k) ?? null, set: (k, v) => {
1253
+ preferenceMemory().set(k, v);
1254
+ }, remove: (k) => {
1255
+ preferenceMemory().delete(k);
1256
+ } };
1257
+ var NEWSLETTER_REQUESTED_EVENT = "behio:newsletter-requested";
1258
+ var PREFIX = "behio:forms:";
1259
+ var VISIT_MS = 30 * 60 * 1e3;
1260
+ function sessionAdapter() {
1261
+ return { get: (key) => {
1262
+ try {
1263
+ return sessionStorage.getItem(key) ?? memoryAdapter.get(key);
1264
+ } catch {
1265
+ return memoryAdapter.get(key);
1266
+ }
1267
+ }, set: (key, value) => {
1268
+ memoryAdapter.set(key, value);
1269
+ try {
1270
+ sessionStorage.setItem(key, value);
1271
+ } catch {
1272
+ }
1273
+ }, remove: (key) => {
1274
+ memoryAdapter.remove(key);
1275
+ try {
1276
+ sessionStorage.removeItem(key);
1277
+ } catch {
1278
+ }
1279
+ } };
1280
+ }
1281
+ function markNewsletterRequested() {
1282
+ if (typeof window === "undefined") return;
1283
+ memoryAdapter.set(PREFIX + "newsletter", "1");
1284
+ localStorageAdapter.set(PREFIX + "newsletter", "1");
1285
+ if (typeof window !== "undefined") window.dispatchEvent(new Event(NEWSLETTER_REQUESTED_EVENT));
1286
+ }
1287
+ function newsletterWasRequested() {
1288
+ return memoryAdapter.get(PREFIX + "newsletter") === "1" || localStorageAdapter.get(PREFIX + "newsletter") === "1";
1289
+ }
1290
+ function matchesFormPath(rule, pathname) {
1291
+ return rule.endsWith("*") ? pathname.startsWith(rule.slice(0, -1)) : pathname === rule;
1292
+ }
1293
+ function formPopupRouteAllowed(pathname, placement) {
1294
+ if (/^\/(cart|checkout|account|order|newsletter|login|register|forgot-password|reset-password|verify-email|session)(\/|$)/.test(pathname)) return false;
1295
+ return (!placement.includePaths.length || placement.includePaths.some((rule) => matchesFormPath(rule, pathname))) && !placement.excludePaths.some((rule) => matchesFormPath(rule, pathname));
1296
+ }
1297
+ var FormPopupClock = class {
1298
+ constructor(elapsedMs = 0) {
1299
+ this.since = null;
1300
+ this.elapsedMs = Math.max(0, elapsedMs);
1301
+ }
1302
+ setVisible(visible, now) {
1303
+ if (this.since !== null) this.elapsedMs += Math.max(0, now - this.since);
1304
+ this.since = visible ? now : null;
1305
+ }
1306
+ elapsed(now) {
1307
+ return this.elapsedMs + (this.since === null ? 0 : Math.max(0, now - this.since));
1308
+ }
1309
+ };
1310
+ var FormPopupPreferences = class {
1311
+ constructor(session = sessionAdapter(), persistent = localStorageAdapter, now = () => Date.now()) {
1312
+ this.session = session;
1313
+ this.persistent = persistent;
1314
+ this.now = now;
1315
+ this.shownInVisit = this.number("shown", this.session) > this.now() || this.number("shown", this.persistent) > this.now();
1316
+ }
1317
+ number(key, storage) {
1318
+ const n = Number(storage.get(PREFIX + key));
1319
+ return Number.isFinite(n) && n >= 0 ? n : 0;
1320
+ }
1321
+ visibleMs() {
1322
+ return this.now() - this.number("activity", this.session) < VISIT_MS ? this.number("visible", this.session) : 0;
1323
+ }
1324
+ saveTime(visible) {
1325
+ if (this.shownInVisit) {
1326
+ const until = String(this.now() + VISIT_MS);
1327
+ this.session.set(PREFIX + "shown", until);
1328
+ this.persistent.set(PREFIX + "shown", until);
1329
+ }
1330
+ this.session.set(PREFIX + "visible", String(visible));
1331
+ this.session.set(PREFIX + "activity", String(this.now()));
1332
+ }
1333
+ suppressed(slug, newsletter = false) {
1334
+ return newsletter && newsletterWasRequested() || this.shownInVisit || this.number("shown", this.session) > this.now() || this.number("shown", this.persistent) > this.now() || this.number("dismissed:" + slug, this.persistent) > this.now() || this.number("dismissed:" + slug, this.session) > this.now();
1335
+ }
1336
+ shown() {
1337
+ this.shownInVisit = true;
1338
+ const until = String(this.now() + VISIT_MS);
1339
+ this.session.set(PREFIX + "shown", until);
1340
+ this.persistent.set(PREFIX + "shown", until);
1341
+ }
1342
+ dismiss(slug, days) {
1343
+ const key = PREFIX + "dismissed:" + slug;
1344
+ const until = String(this.now() + days * 864e5);
1345
+ this.session.set(key, until);
1346
+ this.persistent.set(key, until);
1347
+ }
1348
+ };
1206
1349
  export {
1207
1350
  AddressTypes,
1208
1351
  BehioApiError,
1209
1352
  BehioNetworkError,
1210
1353
  BehioStorefront,
1354
+ FormPopupClock,
1355
+ FormPopupPreferences,
1211
1356
  FulfillmentStatuses,
1357
+ NEWSLETTER_REQUESTED_EVENT,
1212
1358
  OrderStatuses,
1213
1359
  PaymentStatuses,
1214
1360
  ProductSort,
@@ -1222,16 +1368,21 @@ export {
1222
1368
  errorParams,
1223
1369
  findVariantByAttributes,
1224
1370
  formFieldErrors,
1371
+ formPopupRouteAllowed,
1225
1372
  formatPrice,
1226
1373
  generateVisitorId,
1227
1374
  getStoredVisitorId,
1228
1375
  grantAnalyticsConsent,
1376
+ markNewsletterRequested,
1377
+ matchesFormPath,
1378
+ newsletterWasRequested,
1229
1379
  ok,
1230
1380
  publishCartSummary,
1231
1381
  resolveVariantContent,
1232
1382
  revokeAnalyticsConsent,
1233
1383
  toSdkError,
1234
1384
  trackEcommerceEvent,
1385
+ trustedVisitorIp,
1235
1386
  validationFieldMessages,
1236
1387
  variantFromQuery,
1237
1388
  variantHref
package/dist/next.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { q as BehioStorefrontConfig, B as BehioStorefront } from './client-CAPtdqzd.mjs';
1
+ import { r as BehioStorefrontConfig, B as BehioStorefront } from './client-DeAREmgD.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 { q as BehioStorefrontConfig, B as BehioStorefront } from './client-CAPtdqzd.js';
1
+ import { r as BehioStorefrontConfig, B as BehioStorefront } from './client-DeAREmgD.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,7 @@
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 _chunkSBPQZG4Yjs = require('./chunk-SBPQZG4Y.js');
3
+
4
+ var _chunkQU4OFGKKjs = require('./chunk-QU4OFGKK.js');
4
5
 
5
6
  // src/next.ts
6
7
  var _headers = require('next/headers');
@@ -19,7 +20,7 @@ async function getBehio(options = {}) {
19
20
  const locale = _nullishCoalesce(options.locale, () => ( process.env.BEHIO_LOCALE));
20
21
  const currency = _nullishCoalesce(options.currency, () => ( process.env.BEHIO_CURRENCY));
21
22
  const cookieName = _nullishCoalesce(options.cartCookieName, () => ( CART_COOKIE_NAME));
22
- const client = new (0, _chunkSBPQZG4Yjs.BehioStorefront)({
23
+ const client = new (0, _chunkQU4OFGKKjs.BehioStorefront)({
23
24
  apiKey,
24
25
  ...baseUrl ? { baseUrl } : {},
25
26
  ...locale ? { locale } : {},
@@ -36,16 +37,14 @@ async function getBehio(options = {}) {
36
37
  }
37
38
  if (!options.visitorIp) {
38
39
  try {
39
- const h = await _headers.headers.call(void 0, );
40
- const xff = h.get("x-forwarded-for");
41
- const ip = (_nullishCoalesce(_nullishCoalesce(_optionalChain([xff, 'optionalAccess', _7 => _7.split, 'call', _8 => _8(","), 'access', _9 => _9[0]]), () => ( h.get("x-real-ip"))), () => ( ""))).trim();
40
+ const ip = _chunkQU4OFGKKjs.trustedVisitorIp.call(void 0, await _headers.headers.call(void 0, ), process.env.CF_ORIGIN_SECRET);
42
41
  if (ip) client.setVisitorIp(ip);
43
42
  } catch (e) {
44
43
  }
45
44
  }
46
45
  if (!currency) {
47
46
  const currencyCookieName = _nullishCoalesce(options.currencyCookieName, () => ( CURRENCY_COOKIE_NAME));
48
- const chosenCurrency = _optionalChain([cookieStore, 'access', _10 => _10.get, 'call', _11 => _11(currencyCookieName), 'optionalAccess', _12 => _12.value]);
47
+ const chosenCurrency = _optionalChain([cookieStore, 'access', _7 => _7.get, 'call', _8 => _8(currencyCookieName), 'optionalAccess', _9 => _9.value]);
49
48
  if (chosenCurrency) {
50
49
  client.setCurrency(chosenCurrency);
51
50
  }
package/dist/next.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
- BehioStorefront
3
- } from "./chunk-YDZ2OF4O.mjs";
2
+ BehioStorefront,
3
+ trustedVisitorIp
4
+ } from "./chunk-SGMFDMIW.mjs";
4
5
 
5
6
  // src/next.ts
6
7
  import { cookies, headers } from "next/headers";
@@ -36,9 +37,7 @@ async function getBehio(options = {}) {
36
37
  }
37
38
  if (!options.visitorIp) {
38
39
  try {
39
- const h = await headers();
40
- const xff = h.get("x-forwarded-for");
41
- const ip = (xff?.split(",")[0] ?? h.get("x-real-ip") ?? "").trim();
40
+ const ip = trustedVisitorIp(await headers(), process.env.CF_ORIGIN_SECRET);
42
41
  if (ip) client.setVisitorIp(ip);
43
42
  } catch {
44
43
  }