@behio/storefront-sdk 1.0.0 → 1.2.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.
@@ -271,7 +271,55 @@ interface ProductVariant {
271
271
  */
272
272
  id: string;
273
273
  sku: string;
274
+ /**
275
+ * Variant name in the requested locale. Before SDK 1.1.0 this was always the
276
+ * warehouse item name, so translated shops showed one language to everyone.
277
+ */
274
278
  name: string;
279
+ /**
280
+ * Deep-link token for this variant — NOT a URL of its own.
281
+ *
282
+ * A variant has no standalone product page: the catalog 404s its slug and
283
+ * every listing excludes it, because a variant is bought from the parent's
284
+ * detail page. Link to `/product/{product.slug}?variant={variant.variantSlug}`
285
+ * and preselect the variant from that query parameter.
286
+ *
287
+ * Added in SDK 1.1.0.
288
+ */
289
+ variantSlug: string;
290
+ /**
291
+ * Short description of THIS variant, or `null` when the merchant left it
292
+ * empty. `null` means INHERIT: fall back to `ProductDetail.shortDescription`
293
+ * instead of rendering an empty block. Sanitised HTML.
294
+ *
295
+ * Added in SDK 1.1.0.
296
+ */
297
+ shortDescription?: string | null;
298
+ /** Long description of THIS variant. Same inherit-on-null contract as
299
+ * `shortDescription`. Added in SDK 1.1.0. */
300
+ longDescription?: string | null;
301
+ /**
302
+ * Gallery of THIS variant, ordered. Empty means the variant has no photos of
303
+ * its own, so keep showing the parent's gallery.
304
+ *
305
+ * Added in SDK 1.1.0.
306
+ */
307
+ images: ProductDetail["images"];
308
+ /**
309
+ * Per-variant SEO/OG overrides, or `null` when the merchant wrote none. The
310
+ * canonical URL stays the parent's, so use these only when a variant is
311
+ * preselected via `?variant=`.
312
+ *
313
+ * Added in SDK 1.1.0.
314
+ */
315
+ seo?: {
316
+ title?: string | null;
317
+ description?: string | null;
318
+ keywords?: string | null;
319
+ ogTitle?: string | null;
320
+ ogDescription?: string | null;
321
+ ogImage?: string | null;
322
+ } | null;
275
323
  /**
276
324
  * Axis name/value pairs identifying this variant (e.g.
277
325
  * `[{name: 'Barva', value: 'červená'}]`) — matches the wire shape the API
@@ -513,6 +561,25 @@ interface VariantAxisValue {
513
561
  * configured the axis (the storefront's historical default). Join to
514
562
  * `variants[].attributes` by axis `name` + `value`.
515
563
  */
564
+ /**
565
+ * Sourozenecká karta při rozpadu katalogu podle osy (typicky barvy).
566
+ *
567
+ * Každá barva je samostatný produkt s vlastní adresou, fotkami a SEO, takže
568
+ * kolečka barev se vykreslují jako odkazy (`<a href>`), ne jako přepínač uvnitř
569
+ * stránky. Bez odkazu by je nešlo indexovat a nefungovaly by bez JavaScriptu.
570
+ */
571
+ interface ProductSibling {
572
+ productId: string;
573
+ /** Adresa karty; skládá se s cestou produktu ve storefrontu. */
574
+ slug: string;
575
+ name: string;
576
+ /** Hodnota osy ("Růžová"); null u hlavního produktu skupiny. */
577
+ axisValue: string | null;
578
+ swatchColor: string | null;
579
+ swatchImage: string | null;
580
+ /** Tahle karta je právě otevřená stránka. */
581
+ isCurrent: boolean;
582
+ }
516
583
  interface VariantAxis {
517
584
  name: string;
518
585
  displayType: "DROPDOWN" | "BUTTON" | "SWATCH_COLOR" | "SWATCH_IMAGE";
@@ -583,6 +650,11 @@ interface ProductDetail extends ProductListItem {
583
650
  * Empty when the product has no variants.
584
651
  */
585
652
  variantAxes: VariantAxis[];
653
+ /**
654
+ * Sourozenecké karty při rozpadu podle osy. Prázdné u e-shopu, který rozpad
655
+ * nepoužívá, tedy ve výchozím nastavení.
656
+ */
657
+ catalogSiblings: ProductSibling[];
586
658
  volumePricing: ProductVolumePrice[];
587
659
  /**
588
660
  * Curated parameter groups, already resolved. Empty when the merchant
@@ -892,7 +964,22 @@ interface LoginInput {
892
964
  password: string;
893
965
  }
894
966
  interface CartItemProduct {
967
+ /**
968
+ * Slug of the page this line links to. For a variant line this is the
969
+ * PARENT's slug: a variant has no page of its own, so linking to its own slug
970
+ * landed customers on a 404 (fixed 2026-08-03, SDK 1.1.0).
971
+ */
895
972
  slug: string;
973
+ /**
974
+ * Deep-link token of the variant on this line, `null` for a plain product.
975
+ * Build the link as `/product/{slug}?variant={variantSlug}` so the customer
976
+ * returns to the exact variant sitting in their cart.
977
+ *
978
+ * Added in SDK 1.1.0.
979
+ */
980
+ variantSlug?: string | null;
981
+ /** Product name in the CART's language. Before SDK 1.1.0 the API picked an
982
+ * arbitrary translation row, so this could come back in another language. */
896
983
  name: string;
897
984
  sku: string;
898
985
  imageUrl?: string;
@@ -2870,4 +2957,4 @@ declare class NewsletterModule {
2870
2957
  unsubscribe(email: string): Promise<SdkResult<NewsletterUnsubscribeResult>>;
2871
2958
  }
2872
2959
 
2873
- export { type Facet as $, type ActivePromotion as A, BehioStorefront as B, type CookieConsent as C, type CheckoutAddress as D, type CheckoutInput as E, type CheckoutPaymentMethod as F, type CheckoutSettings as G, type CookieConsentInput as H, type CourseAttachment as I, type CourseCertificate as J, type CourseComment as K, type CourseCommentReply as L, type CourseCommentsList as M, type CourseDetail as N, type CourseLesson as O, type CourseListItem as P, type CourseModule as Q, type CoursePostedComment as R, type SdkResult as S, type CourseProgress as T, type CourseTutorMessage as U, type CourseTutorThread as V, type CrossSellItem as W, type CustomerAddress as X, type CustomerProfile as Y, type DigitalDownload as Z, type DownloadUrl as _, type AddToCartInput as a, type ProductPrice as a$, type FacetAvailability as a0, type FacetCategory as a1, type FacetLabel as a2, type FacetPriceRange as a3, type FacetRange as a4, type FacetRatingBucket as a5, type FacetValue as a6, type FacetsResponse as a7, type FilterField as a8, type FulfillmentStatus as a9, type OrderDetail as aA, type OrderItem as aB, type OrderListItem as aC, type OrderStatus as aD, type OrderStatusHistory as aE, OrderStatuses as aF, type OrderTracking as aG, type Page as aH, type PageAttachment as aI, type PageDetail as aJ, type PaginatedResponse as aK, type PaymentStatus as aL, PaymentStatuses as aM, type PickupPoint as aN, type PickupPointHours as aO, type PickupPointsInput as aP, type PriceDisplay as aQ, type ProductAvailability as aR, type ProductDetail as aS, type ProductGroup as aT, type ProductLabel as aU, type ProductListItem as aV, type ProductMedia as aW, type ProductMediaVariant as aX, type ProductParameter as aY, type ProductParameterGroup as aZ, type ProductParametersResponse as a_, FulfillmentStatuses as aa, type GiftCardBalance as ab, type GiftCardPurchaseInput as ac, type GiftCardPurchaseResult as ad, type GiftCardSummary as ae, type LessonNote as af, type LessonQuiz as ag, type LoginInput as ah, type LoyaltyBalance as ai, type LoyaltyNextTier as aj, type LoyaltyProgram as ak, type LoyaltySummary as al, type LoyaltyTier as am, type LoyaltyTierPerks as an, type LoyaltyTransaction as ao, type Menu as ap, type MenuItem as aq, type MenuItemRef as ar, type MenuItemType as as, type MessageResponse as at, type NewsletterOptInDefault as au, type NewsletterSubscribeInput as av, type NewsletterSubscribeResult as aw, type NewsletterUnsubscribeResult as ax, type OrderAccessRequestResponse as ay, type OrderAccessVerifyResponse as az, type AddressDetail as b, type ProductPromotionSummary as b0, type ProductReview as b1, type ProductReviewsResponse as b2, ProductSort as b3, type ProductSortValue as b4, type ProductVariant as b5, type ProductVolumePrice as b6, type ProductsQuery as b7, type QuizAnswerInput as b8, type QuizAnswerResult as b9, type ShopSeoIdentity as bA, type StockBehavior as bB, type StockMode as bC, type SubmitQuoteInput as bD, type SubmitReturnInput as bE, type SubmitReviewInput as bF, type Subscription as bG, type SubscriptionAction as bH, type SubscriptionFrequency as bI, type SubscriptionItem as bJ, type SubscriptionStatus as bK, type TaxBreakdownLine as bL, type VariantAxis as bM, type VariantAxisValue as bN, type WishlistItem as bO, err as bP, ok as bQ, toSdkError as bR, type QuizQuestion as ba, type QuizResult as bb, type QuoteItem as bc, type QuoteRequest as bd, type RegisterInput as be, type RegisterResult as bf, type RequestInterceptor as bg, type RequestInterceptorConfig as bh, type ResponseInterceptor as bi, type ResponseInterceptorData as bj, type ReturnRequest as bk, type ReturnRequestItem as bl, type ReturnStatus as bm, type ReturnStatusItem as bn, type ReturnableOrder as bo, type ReturnableOrderItem as bp, type SdkError as bq, type ShippingMethodSummary as br, type ShippingQuote as bs, type ShippingQuoteInput as bt, type ShopInfo as bu, type ShopScript as bv, type ShopScriptPlacement as bw, type ShopScriptType as bx, type ShopScripts as by, type ShopSeo as bz, type AddressSuggestion as c, type AddressType as d, AddressTypes as e, type AuthTokens as f, type BackInStockSubscription as g, type BadgeTone as h, BehioApiError as i, type BehioErrorCode as j, type BehioEventHandler as k, type BehioEventType as l, BehioNetworkError as m, type BehioStorefrontConfig as n, type Bundle as o, type BundleItem as p, type Cart as q, type CartBundleLine as r, type CartBundleLineItem as s, type CartDiscount as t, type CartItem as u, type CartItemProduct as v, type CartPromotion as w, type Category as x, type CategoryDetail as y, type CertificateVerification as z };
2960
+ export { type DigitalDownload as $, type ActivePromotion as A, BehioStorefront as B, type CookieConsent as C, type CertificateVerification as D, type CheckoutAddress as E, type CheckoutInput as F, type CheckoutPaymentMethod as G, type CheckoutSettings as H, type CookieConsentInput as I, type CourseAttachment as J, type CourseCertificate as K, type CourseComment as L, type CourseCommentReply as M, type CourseCommentsList as N, type CourseDetail as O, type ProductDetail as P, type CourseLesson as Q, type CourseListItem as R, type SdkResult as S, type CourseModule as T, type CoursePostedComment as U, type CourseProgress as V, type CourseTutorMessage as W, type CourseTutorThread as X, type CrossSellItem as Y, type CustomerAddress as Z, type CustomerProfile as _, type ProductVariant as a, type ProductParametersResponse as a$, type DownloadUrl as a0, type Facet as a1, type FacetAvailability as a2, type FacetCategory as a3, type FacetLabel as a4, type FacetPriceRange as a5, type FacetRange as a6, type FacetRatingBucket as a7, type FacetValue as a8, type FacetsResponse as a9, type OrderAccessRequestResponse as aA, type OrderAccessVerifyResponse as aB, type OrderDetail as aC, type OrderItem as aD, type OrderListItem as aE, type OrderStatus as aF, type OrderStatusHistory as aG, OrderStatuses as aH, type OrderTracking as aI, type Page as aJ, type PageAttachment as aK, type PageDetail as aL, type PaginatedResponse as aM, type PaymentStatus as aN, PaymentStatuses as aO, type PickupPoint as aP, type PickupPointHours as aQ, type PickupPointsInput as aR, type PriceDisplay as aS, type ProductAvailability as aT, type ProductGroup as aU, type ProductLabel as aV, type ProductListItem as aW, type ProductMedia as aX, type ProductMediaVariant as aY, type ProductParameter as aZ, type ProductParameterGroup as a_, type FilterField as aa, type FulfillmentStatus as ab, FulfillmentStatuses as ac, type GiftCardBalance as ad, type GiftCardPurchaseInput as ae, type GiftCardPurchaseResult as af, type GiftCardSummary as ag, type LessonNote as ah, type LessonQuiz as ai, type LoginInput as aj, type LoyaltyBalance as ak, type LoyaltyNextTier as al, type LoyaltyProgram as am, type LoyaltySummary as an, type LoyaltyTier as ao, type LoyaltyTierPerks as ap, type LoyaltyTransaction as aq, type Menu as ar, type MenuItem as as, type MenuItemRef as at, type MenuItemType as au, type MessageResponse as av, type NewsletterOptInDefault as aw, type NewsletterSubscribeInput as ax, type NewsletterSubscribeResult as ay, type NewsletterUnsubscribeResult as az, type AddToCartInput as b, type ProductPrice as b0, type ProductPromotionSummary as b1, type ProductReview as b2, type ProductReviewsResponse as b3, type ProductSibling as b4, ProductSort as b5, type ProductSortValue as b6, type ProductVolumePrice as b7, type ProductsQuery as b8, type QuizAnswerInput as b9, type ShopSeo as bA, type ShopSeoIdentity as bB, type StockBehavior as bC, type StockMode as bD, type SubmitQuoteInput as bE, type SubmitReturnInput as bF, type SubmitReviewInput as bG, type Subscription as bH, type SubscriptionAction as bI, type SubscriptionFrequency as bJ, type SubscriptionItem as bK, type SubscriptionStatus as bL, type TaxBreakdownLine as bM, type VariantAxis as bN, type VariantAxisValue as bO, type WishlistItem as bP, err as bQ, ok as bR, toSdkError as bS, type QuizAnswerResult as ba, type QuizQuestion as bb, type QuizResult as bc, type QuoteItem as bd, type QuoteRequest as be, type RegisterInput as bf, type RegisterResult as bg, type RequestInterceptor as bh, type RequestInterceptorConfig as bi, type ResponseInterceptor as bj, type ResponseInterceptorData as bk, type ReturnRequest as bl, type ReturnRequestItem as bm, type ReturnStatus as bn, type ReturnStatusItem as bo, type ReturnableOrder as bp, type ReturnableOrderItem as bq, type SdkError as br, type ShippingMethodSummary as bs, type ShippingQuote as bt, type ShippingQuoteInput as bu, type ShopInfo as bv, type ShopScript as bw, type ShopScriptPlacement as bx, type ShopScriptType as by, type ShopScripts as bz, type AddressDetail as c, type AddressSuggestion as d, type AddressType as e, AddressTypes as f, type AuthTokens as g, type BackInStockSubscription as h, type BadgeTone as i, BehioApiError as j, type BehioErrorCode as k, type BehioEventHandler as l, type BehioEventType as m, BehioNetworkError as n, type BehioStorefrontConfig as o, type Bundle as p, type BundleItem as q, type Cart as r, type CartBundleLine as s, type CartBundleLineItem as t, type CartDiscount as u, type CartItem as v, type CartItemProduct as w, type CartPromotion as x, type Category as y, type CategoryDetail as z };
@@ -271,7 +271,55 @@ interface ProductVariant {
271
271
  */
272
272
  id: string;
273
273
  sku: string;
274
+ /**
275
+ * Variant name in the requested locale. Before SDK 1.1.0 this was always the
276
+ * warehouse item name, so translated shops showed one language to everyone.
277
+ */
274
278
  name: string;
279
+ /**
280
+ * Deep-link token for this variant — NOT a URL of its own.
281
+ *
282
+ * A variant has no standalone product page: the catalog 404s its slug and
283
+ * every listing excludes it, because a variant is bought from the parent's
284
+ * detail page. Link to `/product/{product.slug}?variant={variant.variantSlug}`
285
+ * and preselect the variant from that query parameter.
286
+ *
287
+ * Added in SDK 1.1.0.
288
+ */
289
+ variantSlug: string;
290
+ /**
291
+ * Short description of THIS variant, or `null` when the merchant left it
292
+ * empty. `null` means INHERIT: fall back to `ProductDetail.shortDescription`
293
+ * instead of rendering an empty block. Sanitised HTML.
294
+ *
295
+ * Added in SDK 1.1.0.
296
+ */
297
+ shortDescription?: string | null;
298
+ /** Long description of THIS variant. Same inherit-on-null contract as
299
+ * `shortDescription`. Added in SDK 1.1.0. */
300
+ longDescription?: string | null;
301
+ /**
302
+ * Gallery of THIS variant, ordered. Empty means the variant has no photos of
303
+ * its own, so keep showing the parent's gallery.
304
+ *
305
+ * Added in SDK 1.1.0.
306
+ */
307
+ images: ProductDetail["images"];
308
+ /**
309
+ * Per-variant SEO/OG overrides, or `null` when the merchant wrote none. The
310
+ * canonical URL stays the parent's, so use these only when a variant is
311
+ * preselected via `?variant=`.
312
+ *
313
+ * Added in SDK 1.1.0.
314
+ */
315
+ seo?: {
316
+ title?: string | null;
317
+ description?: string | null;
318
+ keywords?: string | null;
319
+ ogTitle?: string | null;
320
+ ogDescription?: string | null;
321
+ ogImage?: string | null;
322
+ } | null;
275
323
  /**
276
324
  * Axis name/value pairs identifying this variant (e.g.
277
325
  * `[{name: 'Barva', value: 'červená'}]`) — matches the wire shape the API
@@ -513,6 +561,25 @@ interface VariantAxisValue {
513
561
  * configured the axis (the storefront's historical default). Join to
514
562
  * `variants[].attributes` by axis `name` + `value`.
515
563
  */
564
+ /**
565
+ * Sourozenecká karta při rozpadu katalogu podle osy (typicky barvy).
566
+ *
567
+ * Každá barva je samostatný produkt s vlastní adresou, fotkami a SEO, takže
568
+ * kolečka barev se vykreslují jako odkazy (`<a href>`), ne jako přepínač uvnitř
569
+ * stránky. Bez odkazu by je nešlo indexovat a nefungovaly by bez JavaScriptu.
570
+ */
571
+ interface ProductSibling {
572
+ productId: string;
573
+ /** Adresa karty; skládá se s cestou produktu ve storefrontu. */
574
+ slug: string;
575
+ name: string;
576
+ /** Hodnota osy ("Růžová"); null u hlavního produktu skupiny. */
577
+ axisValue: string | null;
578
+ swatchColor: string | null;
579
+ swatchImage: string | null;
580
+ /** Tahle karta je právě otevřená stránka. */
581
+ isCurrent: boolean;
582
+ }
516
583
  interface VariantAxis {
517
584
  name: string;
518
585
  displayType: "DROPDOWN" | "BUTTON" | "SWATCH_COLOR" | "SWATCH_IMAGE";
@@ -583,6 +650,11 @@ interface ProductDetail extends ProductListItem {
583
650
  * Empty when the product has no variants.
584
651
  */
585
652
  variantAxes: VariantAxis[];
653
+ /**
654
+ * Sourozenecké karty při rozpadu podle osy. Prázdné u e-shopu, který rozpad
655
+ * nepoužívá, tedy ve výchozím nastavení.
656
+ */
657
+ catalogSiblings: ProductSibling[];
586
658
  volumePricing: ProductVolumePrice[];
587
659
  /**
588
660
  * Curated parameter groups, already resolved. Empty when the merchant
@@ -892,7 +964,22 @@ interface LoginInput {
892
964
  password: string;
893
965
  }
894
966
  interface CartItemProduct {
967
+ /**
968
+ * Slug of the page this line links to. For a variant line this is the
969
+ * PARENT's slug: a variant has no page of its own, so linking to its own slug
970
+ * landed customers on a 404 (fixed 2026-08-03, SDK 1.1.0).
971
+ */
895
972
  slug: string;
973
+ /**
974
+ * Deep-link token of the variant on this line, `null` for a plain product.
975
+ * Build the link as `/product/{slug}?variant={variantSlug}` so the customer
976
+ * returns to the exact variant sitting in their cart.
977
+ *
978
+ * Added in SDK 1.1.0.
979
+ */
980
+ variantSlug?: string | null;
981
+ /** Product name in the CART's language. Before SDK 1.1.0 the API picked an
982
+ * arbitrary translation row, so this could come back in another language. */
896
983
  name: string;
897
984
  sku: string;
898
985
  imageUrl?: string;
@@ -2870,4 +2957,4 @@ declare class NewsletterModule {
2870
2957
  unsubscribe(email: string): Promise<SdkResult<NewsletterUnsubscribeResult>>;
2871
2958
  }
2872
2959
 
2873
- export { type Facet as $, type ActivePromotion as A, BehioStorefront as B, type CookieConsent as C, type CheckoutAddress as D, type CheckoutInput as E, type CheckoutPaymentMethod as F, type CheckoutSettings as G, type CookieConsentInput as H, type CourseAttachment as I, type CourseCertificate as J, type CourseComment as K, type CourseCommentReply as L, type CourseCommentsList as M, type CourseDetail as N, type CourseLesson as O, type CourseListItem as P, type CourseModule as Q, type CoursePostedComment as R, type SdkResult as S, type CourseProgress as T, type CourseTutorMessage as U, type CourseTutorThread as V, type CrossSellItem as W, type CustomerAddress as X, type CustomerProfile as Y, type DigitalDownload as Z, type DownloadUrl as _, type AddToCartInput as a, type ProductPrice as a$, type FacetAvailability as a0, type FacetCategory as a1, type FacetLabel as a2, type FacetPriceRange as a3, type FacetRange as a4, type FacetRatingBucket as a5, type FacetValue as a6, type FacetsResponse as a7, type FilterField as a8, type FulfillmentStatus as a9, type OrderDetail as aA, type OrderItem as aB, type OrderListItem as aC, type OrderStatus as aD, type OrderStatusHistory as aE, OrderStatuses as aF, type OrderTracking as aG, type Page as aH, type PageAttachment as aI, type PageDetail as aJ, type PaginatedResponse as aK, type PaymentStatus as aL, PaymentStatuses as aM, type PickupPoint as aN, type PickupPointHours as aO, type PickupPointsInput as aP, type PriceDisplay as aQ, type ProductAvailability as aR, type ProductDetail as aS, type ProductGroup as aT, type ProductLabel as aU, type ProductListItem as aV, type ProductMedia as aW, type ProductMediaVariant as aX, type ProductParameter as aY, type ProductParameterGroup as aZ, type ProductParametersResponse as a_, FulfillmentStatuses as aa, type GiftCardBalance as ab, type GiftCardPurchaseInput as ac, type GiftCardPurchaseResult as ad, type GiftCardSummary as ae, type LessonNote as af, type LessonQuiz as ag, type LoginInput as ah, type LoyaltyBalance as ai, type LoyaltyNextTier as aj, type LoyaltyProgram as ak, type LoyaltySummary as al, type LoyaltyTier as am, type LoyaltyTierPerks as an, type LoyaltyTransaction as ao, type Menu as ap, type MenuItem as aq, type MenuItemRef as ar, type MenuItemType as as, type MessageResponse as at, type NewsletterOptInDefault as au, type NewsletterSubscribeInput as av, type NewsletterSubscribeResult as aw, type NewsletterUnsubscribeResult as ax, type OrderAccessRequestResponse as ay, type OrderAccessVerifyResponse as az, type AddressDetail as b, type ProductPromotionSummary as b0, type ProductReview as b1, type ProductReviewsResponse as b2, ProductSort as b3, type ProductSortValue as b4, type ProductVariant as b5, type ProductVolumePrice as b6, type ProductsQuery as b7, type QuizAnswerInput as b8, type QuizAnswerResult as b9, type ShopSeoIdentity as bA, type StockBehavior as bB, type StockMode as bC, type SubmitQuoteInput as bD, type SubmitReturnInput as bE, type SubmitReviewInput as bF, type Subscription as bG, type SubscriptionAction as bH, type SubscriptionFrequency as bI, type SubscriptionItem as bJ, type SubscriptionStatus as bK, type TaxBreakdownLine as bL, type VariantAxis as bM, type VariantAxisValue as bN, type WishlistItem as bO, err as bP, ok as bQ, toSdkError as bR, type QuizQuestion as ba, type QuizResult as bb, type QuoteItem as bc, type QuoteRequest as bd, type RegisterInput as be, type RegisterResult as bf, type RequestInterceptor as bg, type RequestInterceptorConfig as bh, type ResponseInterceptor as bi, type ResponseInterceptorData as bj, type ReturnRequest as bk, type ReturnRequestItem as bl, type ReturnStatus as bm, type ReturnStatusItem as bn, type ReturnableOrder as bo, type ReturnableOrderItem as bp, type SdkError as bq, type ShippingMethodSummary as br, type ShippingQuote as bs, type ShippingQuoteInput as bt, type ShopInfo as bu, type ShopScript as bv, type ShopScriptPlacement as bw, type ShopScriptType as bx, type ShopScripts as by, type ShopSeo as bz, type AddressSuggestion as c, type AddressType as d, AddressTypes as e, type AuthTokens as f, type BackInStockSubscription as g, type BadgeTone as h, BehioApiError as i, type BehioErrorCode as j, type BehioEventHandler as k, type BehioEventType as l, BehioNetworkError as m, type BehioStorefrontConfig as n, type Bundle as o, type BundleItem as p, type Cart as q, type CartBundleLine as r, type CartBundleLineItem as s, type CartDiscount as t, type CartItem as u, type CartItemProduct as v, type CartPromotion as w, type Category as x, type CategoryDetail as y, type CertificateVerification as z };
2960
+ export { type DigitalDownload as $, type ActivePromotion as A, BehioStorefront as B, type CookieConsent as C, type CertificateVerification as D, type CheckoutAddress as E, type CheckoutInput as F, type CheckoutPaymentMethod as G, type CheckoutSettings as H, type CookieConsentInput as I, type CourseAttachment as J, type CourseCertificate as K, type CourseComment as L, type CourseCommentReply as M, type CourseCommentsList as N, type CourseDetail as O, type ProductDetail as P, type CourseLesson as Q, type CourseListItem as R, type SdkResult as S, type CourseModule as T, type CoursePostedComment as U, type CourseProgress as V, type CourseTutorMessage as W, type CourseTutorThread as X, type CrossSellItem as Y, type CustomerAddress as Z, type CustomerProfile as _, type ProductVariant as a, type ProductParametersResponse as a$, type DownloadUrl as a0, type Facet as a1, type FacetAvailability as a2, type FacetCategory as a3, type FacetLabel as a4, type FacetPriceRange as a5, type FacetRange as a6, type FacetRatingBucket as a7, type FacetValue as a8, type FacetsResponse as a9, type OrderAccessRequestResponse as aA, type OrderAccessVerifyResponse as aB, type OrderDetail as aC, type OrderItem as aD, type OrderListItem as aE, type OrderStatus as aF, type OrderStatusHistory as aG, OrderStatuses as aH, type OrderTracking as aI, type Page as aJ, type PageAttachment as aK, type PageDetail as aL, type PaginatedResponse as aM, type PaymentStatus as aN, PaymentStatuses as aO, type PickupPoint as aP, type PickupPointHours as aQ, type PickupPointsInput as aR, type PriceDisplay as aS, type ProductAvailability as aT, type ProductGroup as aU, type ProductLabel as aV, type ProductListItem as aW, type ProductMedia as aX, type ProductMediaVariant as aY, type ProductParameter as aZ, type ProductParameterGroup as a_, type FilterField as aa, type FulfillmentStatus as ab, FulfillmentStatuses as ac, type GiftCardBalance as ad, type GiftCardPurchaseInput as ae, type GiftCardPurchaseResult as af, type GiftCardSummary as ag, type LessonNote as ah, type LessonQuiz as ai, type LoginInput as aj, type LoyaltyBalance as ak, type LoyaltyNextTier as al, type LoyaltyProgram as am, type LoyaltySummary as an, type LoyaltyTier as ao, type LoyaltyTierPerks as ap, type LoyaltyTransaction as aq, type Menu as ar, type MenuItem as as, type MenuItemRef as at, type MenuItemType as au, type MessageResponse as av, type NewsletterOptInDefault as aw, type NewsletterSubscribeInput as ax, type NewsletterSubscribeResult as ay, type NewsletterUnsubscribeResult as az, type AddToCartInput as b, type ProductPrice as b0, type ProductPromotionSummary as b1, type ProductReview as b2, type ProductReviewsResponse as b3, type ProductSibling as b4, ProductSort as b5, type ProductSortValue as b6, type ProductVolumePrice as b7, type ProductsQuery as b8, type QuizAnswerInput as b9, type ShopSeo as bA, type ShopSeoIdentity as bB, type StockBehavior as bC, type StockMode as bD, type SubmitQuoteInput as bE, type SubmitReturnInput as bF, type SubmitReviewInput as bG, type Subscription as bH, type SubscriptionAction as bI, type SubscriptionFrequency as bJ, type SubscriptionItem as bK, type SubscriptionStatus as bL, type TaxBreakdownLine as bM, type VariantAxis as bN, type VariantAxisValue as bO, type WishlistItem as bP, err as bQ, ok as bR, toSdkError as bS, type QuizAnswerResult as ba, type QuizQuestion as bb, type QuizResult as bc, type QuoteItem as bd, type QuoteRequest as be, type RegisterInput as bf, type RegisterResult as bg, type RequestInterceptor as bh, type RequestInterceptorConfig as bi, type ResponseInterceptor as bj, type ResponseInterceptorData as bk, type ReturnRequest as bl, type ReturnRequestItem as bm, type ReturnStatus as bn, type ReturnStatusItem as bo, type ReturnableOrder as bp, type ReturnableOrderItem as bq, type SdkError as br, type ShippingMethodSummary as bs, type ShippingQuote as bt, type ShippingQuoteInput as bu, type ShopInfo as bv, type ShopScript as bw, type ShopScriptPlacement as bx, type ShopScriptType as by, type ShopScripts as bz, type AddressDetail as c, type AddressSuggestion as d, type AddressType as e, AddressTypes as f, type AuthTokens as g, type BackInStockSubscription as h, type BadgeTone as i, BehioApiError as j, type BehioErrorCode as k, type BehioEventHandler as l, type BehioEventType as m, BehioNetworkError as n, type BehioStorefrontConfig as o, type Bundle as p, type BundleItem as q, type Cart as r, type CartBundleLine as s, type CartBundleLineItem as t, type CartDiscount as u, type CartItem as v, type CartItemProduct as w, type CartPromotion as x, type Category as y, type CategoryDetail as z };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BehioStorefront, S as SdkResult, C as CookieConsent } from './client-BKNtLTcu.mjs';
2
- export { A as ActivePromotion, a as AddToCartInput, b as AddressDetail, c as AddressSuggestion, d as AddressType, e as AddressTypes, f as AuthTokens, g as BackInStockSubscription, h as BadgeTone, i as BehioApiError, j as BehioErrorCode, k as BehioEventHandler, l as BehioEventType, m as BehioNetworkError, n as BehioStorefrontConfig, o as Bundle, p as BundleItem, q as Cart, r as CartBundleLine, s as CartBundleLineItem, t as CartDiscount, u as CartItem, v as CartItemProduct, w as CartPromotion, x as Category, y as CategoryDetail, z as CertificateVerification, D as CheckoutAddress, E as CheckoutInput, F as CheckoutPaymentMethod, G as CheckoutSettings, H as CookieConsentInput, I as CourseAttachment, J as CourseCertificate, K as CourseComment, L as CourseCommentReply, M as CourseCommentsList, N as CourseDetail, O as CourseLesson, P as CourseListItem, Q as CourseModule, R as CoursePostedComment, T as CourseProgress, U as CourseTutorMessage, V as CourseTutorThread, W as CrossSellItem, X as CustomerAddress, Y as CustomerProfile, Z as DigitalDownload, _ as DownloadUrl, $ as Facet, a0 as FacetAvailability, a1 as FacetCategory, a2 as FacetLabel, a3 as FacetPriceRange, a4 as FacetRange, a5 as FacetRatingBucket, a6 as FacetValue, a7 as FacetsResponse, a8 as FilterField, a9 as FulfillmentStatus, aa as FulfillmentStatuses, ab as GiftCardBalance, ac as GiftCardPurchaseInput, ad as GiftCardPurchaseResult, ae as GiftCardSummary, af as LessonNote, ag as LessonQuiz, ah as LoginInput, ai as LoyaltyBalance, aj as LoyaltyNextTier, ak as LoyaltyProgram, al as LoyaltySummary, am as LoyaltyTier, an as LoyaltyTierPerks, ao as LoyaltyTransaction, ap as Menu, aq as MenuItem, ar as MenuItemRef, as as MenuItemType, at as MessageResponse, au as NewsletterOptInDefault, av as NewsletterSubscribeInput, aw as NewsletterSubscribeResult, ax as NewsletterUnsubscribeResult, ay as OrderAccessRequestResponse, az as OrderAccessVerifyResponse, aA as OrderDetail, aB as OrderItem, aC as OrderListItem, aD as OrderStatus, aE as OrderStatusHistory, aF as OrderStatuses, aG as OrderTracking, aH as Page, aI as PageAttachment, aJ as PageDetail, aK as PaginatedResponse, aL as PaymentStatus, aM as PaymentStatuses, aN as PickupPoint, aO as PickupPointHours, aP as PickupPointsInput, aQ as PriceDisplay, aR as ProductAvailability, aS as ProductDetail, aT as ProductGroup, aU as ProductLabel, aV as ProductListItem, aW as ProductMedia, aX as ProductMediaVariant, aY as ProductParameter, aZ as ProductParameterGroup, a_ as ProductParametersResponse, a$ as ProductPrice, b0 as ProductPromotionSummary, b1 as ProductReview, b2 as ProductReviewsResponse, b3 as ProductSort, b4 as ProductSortValue, b5 as ProductVariant, b6 as ProductVolumePrice, b7 as ProductsQuery, b8 as QuizAnswerInput, b9 as QuizAnswerResult, ba as QuizQuestion, bb as QuizResult, bc as QuoteItem, bd as QuoteRequest, be as RegisterInput, bf as RegisterResult, bg as RequestInterceptor, bh as RequestInterceptorConfig, bi as ResponseInterceptor, bj as ResponseInterceptorData, bk as ReturnRequest, bl as ReturnRequestItem, bm as ReturnStatus, bn as ReturnStatusItem, bo as ReturnableOrder, bp as ReturnableOrderItem, bq as SdkError, br as ShippingMethodSummary, bs as ShippingQuote, bt as ShippingQuoteInput, bu as ShopInfo, bv as ShopScript, bw as ShopScriptPlacement, bx as ShopScriptType, by as ShopScripts, bz as ShopSeo, bA as ShopSeoIdentity, bB as StockBehavior, bC as StockMode, bD as SubmitQuoteInput, bE as SubmitReturnInput, bF as SubmitReviewInput, bG as Subscription, bH as SubscriptionAction, bI as SubscriptionFrequency, bJ as SubscriptionItem, bK as SubscriptionStatus, bL as TaxBreakdownLine, bM as VariantAxis, bN as VariantAxisValue, bO as WishlistItem, bP as err, bQ as ok, bR as toSdkError } from './client-BKNtLTcu.mjs';
1
+ import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent } from './client-BU8Kfb74.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 StockBehavior, bD as StockMode, bE as SubmitQuoteInput, bF as SubmitReturnInput, bG as SubmitReviewInput, bH as Subscription, bI as SubscriptionAction, bJ as SubscriptionFrequency, bK as SubscriptionItem, bL as SubscriptionStatus, bM as TaxBreakdownLine, bN as VariantAxis, bO as VariantAxisValue, bP as WishlistItem, bQ as err, bR as ok, bS as toSdkError } from './client-BU8Kfb74.mjs';
3
3
 
4
4
  /**
5
5
  * Format a price amount with currency using Intl.NumberFormat.
@@ -11,6 +11,106 @@ export { A as ActivePromotion, a as AddToCartInput, b as AddressDetail, c as Add
11
11
  */
12
12
  declare function formatPrice(amount: number, currency: string, locale?: string): string;
13
13
 
14
+ /**
15
+ * Variant selection helpers — server-safe (no React, no DOM).
16
+ *
17
+ * Every storefront that sells variants needs the same four decisions, and every
18
+ * one of them has a wrong answer that looks right on screen:
19
+ *
20
+ * 1. WHICH variant is selected on first render. It has to be decided on the
21
+ * server from `?variant=`, otherwise the page renders the parent's text and
22
+ * swaps it after hydration — a visible flash, and the wrong text in view
23
+ * source for crawlers.
24
+ * 2. WHAT the page shows for it. A variant carries its own name, descriptions
25
+ * and gallery, but only where the merchant filled them in; everywhere else
26
+ * it INHERITS the parent. Rendering the raw variant fields shows empty
27
+ * blocks on shops that only translated the name.
28
+ * 3. WHERE a variant links. A variant has no page of its own, so the link is
29
+ * always the parent's slug plus `?variant=` (see `variantHref`).
30
+ * 4. WHICH variant a click means when there are several axes (colour + size):
31
+ * the answer is "the one matching the whole selection", not "the one whose
32
+ * label I clicked".
33
+ */
34
+
35
+ /** Query parameter carrying the preselected variant. One name, everywhere. */
36
+ declare const VARIANT_QUERY_PARAM = "variant";
37
+ /**
38
+ * Content actually rendered for a product page: the variant's own values where
39
+ * it has them, the parent's everywhere else.
40
+ */
41
+ interface ResolvedVariantContent {
42
+ name: string;
43
+ shortDescription: string | null;
44
+ longDescription: string | null;
45
+ images: ProductDetail["images"];
46
+ /** `true` for each field the variant overrode — handy for debugging a shop. */
47
+ overrides: {
48
+ name: boolean;
49
+ shortDescription: boolean;
50
+ longDescription: boolean;
51
+ images: boolean;
52
+ };
53
+ }
54
+ /**
55
+ * Merge a variant onto its parent product for rendering.
56
+ *
57
+ * Pass `variant: null` (nothing selected yet) and you get the parent unchanged,
58
+ * so a page can call this unconditionally.
59
+ */
60
+ declare function resolveVariantContent(product: ProductDetail, variant: ProductVariant | null | undefined): ResolvedVariantContent;
61
+ /**
62
+ * Variant preselected by the URL.
63
+ *
64
+ * Accepts whatever the framework hands you (`string`, the array Next.js gives
65
+ * for repeated params, or nothing) and falls back to `null` when the token
66
+ * matches no variant — a stale link must render the parent page, never a 404
67
+ * and never a blank picker.
68
+ */
69
+ declare function variantFromQuery(product: ProductDetail, value: string | string[] | null | undefined): ProductVariant | null;
70
+ /**
71
+ * Link to a product, optionally with a variant preselected.
72
+ *
73
+ * ALWAYS goes through the parent's slug. Building `/product/${variant.slug}`
74
+ * is the single most repeated bug around variants: it looks correct, and it
75
+ * 404s for every visitor, in the cart, in the XML feeds and in the admin's
76
+ * "open on the web" button — all three of which had exactly that bug.
77
+ */
78
+ declare function variantHref(productSlug: string, variant?: Pick<ProductVariant, "variantSlug"> | null, basePath?: string): string;
79
+ /**
80
+ * The variant matching a full axis selection (e.g. `{Barva: "modrá", Velikost:
81
+ * "M"}`). Returns `null` while the selection is incomplete or names a
82
+ * combination the merchant never published, which is the moment to disable the
83
+ * buy button rather than to add "some" variant to the cart.
84
+ */
85
+ declare function findVariantByAttributes(product: ProductDetail, selection: Record<string, string>): ProductVariant | null;
86
+ /**
87
+ * Axis values that lead to an existing variant given what is already picked.
88
+ *
89
+ * Without this a shop happily offers "modrá + XXL", which no variant covers, and
90
+ * the customer finds out by clicking. Pass the current partial selection and the
91
+ * axis being rendered; you get the values worth showing as enabled.
92
+ */
93
+ declare function availableAxisValues(product: ProductDetail, axisName: string, selection: Record<string, string>): string[];
94
+ /**
95
+ * Rows for a "compare the editions side by side" table: every axis that
96
+ * actually differs between variants, plus price and availability.
97
+ *
98
+ * Built here rather than in each template because the interesting part is what
99
+ * to LEAVE OUT: an axis all variants share carries no information and only
100
+ * makes the table wider.
101
+ */
102
+ interface VariantComparisonRow {
103
+ label: string;
104
+ /** One cell per variant, in `product.variants` order. */
105
+ values: string[];
106
+ }
107
+ declare function buildVariantComparison(product: ProductDetail, labels: {
108
+ price: string;
109
+ availability: string;
110
+ inStock: string;
111
+ soldOut: string;
112
+ }, formatPriceValue: (variant: ProductVariant) => string): VariantComparisonRow[];
113
+
14
114
  /**
15
115
  * GA4 e-commerce event helper.
16
116
  *
@@ -124,4 +224,4 @@ declare function revokeAnalyticsConsent(client: BehioStorefront): Promise<SdkRes
124
224
  success: boolean;
125
225
  }>>;
126
226
 
127
- export { BehioStorefront, CookieConsent, type EcommerceEventName, type EcommerceItem, type EcommercePayload, SdkResult, formatPrice, generateVisitorId, getStoredVisitorId, grantAnalyticsConsent, revokeAnalyticsConsent, trackEcommerceEvent };
227
+ export { BehioStorefront, CookieConsent, type EcommerceEventName, type EcommerceItem, type EcommercePayload, ProductDetail, ProductVariant, type ResolvedVariantContent, SdkResult, VARIANT_QUERY_PARAM, type VariantComparisonRow, availableAxisValues, buildVariantComparison, findVariantByAttributes, formatPrice, generateVisitorId, getStoredVisitorId, grantAnalyticsConsent, resolveVariantContent, revokeAnalyticsConsent, trackEcommerceEvent, variantFromQuery, variantHref };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BehioStorefront, S as SdkResult, C as CookieConsent } from './client-BKNtLTcu.js';
2
- export { A as ActivePromotion, a as AddToCartInput, b as AddressDetail, c as AddressSuggestion, d as AddressType, e as AddressTypes, f as AuthTokens, g as BackInStockSubscription, h as BadgeTone, i as BehioApiError, j as BehioErrorCode, k as BehioEventHandler, l as BehioEventType, m as BehioNetworkError, n as BehioStorefrontConfig, o as Bundle, p as BundleItem, q as Cart, r as CartBundleLine, s as CartBundleLineItem, t as CartDiscount, u as CartItem, v as CartItemProduct, w as CartPromotion, x as Category, y as CategoryDetail, z as CertificateVerification, D as CheckoutAddress, E as CheckoutInput, F as CheckoutPaymentMethod, G as CheckoutSettings, H as CookieConsentInput, I as CourseAttachment, J as CourseCertificate, K as CourseComment, L as CourseCommentReply, M as CourseCommentsList, N as CourseDetail, O as CourseLesson, P as CourseListItem, Q as CourseModule, R as CoursePostedComment, T as CourseProgress, U as CourseTutorMessage, V as CourseTutorThread, W as CrossSellItem, X as CustomerAddress, Y as CustomerProfile, Z as DigitalDownload, _ as DownloadUrl, $ as Facet, a0 as FacetAvailability, a1 as FacetCategory, a2 as FacetLabel, a3 as FacetPriceRange, a4 as FacetRange, a5 as FacetRatingBucket, a6 as FacetValue, a7 as FacetsResponse, a8 as FilterField, a9 as FulfillmentStatus, aa as FulfillmentStatuses, ab as GiftCardBalance, ac as GiftCardPurchaseInput, ad as GiftCardPurchaseResult, ae as GiftCardSummary, af as LessonNote, ag as LessonQuiz, ah as LoginInput, ai as LoyaltyBalance, aj as LoyaltyNextTier, ak as LoyaltyProgram, al as LoyaltySummary, am as LoyaltyTier, an as LoyaltyTierPerks, ao as LoyaltyTransaction, ap as Menu, aq as MenuItem, ar as MenuItemRef, as as MenuItemType, at as MessageResponse, au as NewsletterOptInDefault, av as NewsletterSubscribeInput, aw as NewsletterSubscribeResult, ax as NewsletterUnsubscribeResult, ay as OrderAccessRequestResponse, az as OrderAccessVerifyResponse, aA as OrderDetail, aB as OrderItem, aC as OrderListItem, aD as OrderStatus, aE as OrderStatusHistory, aF as OrderStatuses, aG as OrderTracking, aH as Page, aI as PageAttachment, aJ as PageDetail, aK as PaginatedResponse, aL as PaymentStatus, aM as PaymentStatuses, aN as PickupPoint, aO as PickupPointHours, aP as PickupPointsInput, aQ as PriceDisplay, aR as ProductAvailability, aS as ProductDetail, aT as ProductGroup, aU as ProductLabel, aV as ProductListItem, aW as ProductMedia, aX as ProductMediaVariant, aY as ProductParameter, aZ as ProductParameterGroup, a_ as ProductParametersResponse, a$ as ProductPrice, b0 as ProductPromotionSummary, b1 as ProductReview, b2 as ProductReviewsResponse, b3 as ProductSort, b4 as ProductSortValue, b5 as ProductVariant, b6 as ProductVolumePrice, b7 as ProductsQuery, b8 as QuizAnswerInput, b9 as QuizAnswerResult, ba as QuizQuestion, bb as QuizResult, bc as QuoteItem, bd as QuoteRequest, be as RegisterInput, bf as RegisterResult, bg as RequestInterceptor, bh as RequestInterceptorConfig, bi as ResponseInterceptor, bj as ResponseInterceptorData, bk as ReturnRequest, bl as ReturnRequestItem, bm as ReturnStatus, bn as ReturnStatusItem, bo as ReturnableOrder, bp as ReturnableOrderItem, bq as SdkError, br as ShippingMethodSummary, bs as ShippingQuote, bt as ShippingQuoteInput, bu as ShopInfo, bv as ShopScript, bw as ShopScriptPlacement, bx as ShopScriptType, by as ShopScripts, bz as ShopSeo, bA as ShopSeoIdentity, bB as StockBehavior, bC as StockMode, bD as SubmitQuoteInput, bE as SubmitReturnInput, bF as SubmitReviewInput, bG as Subscription, bH as SubscriptionAction, bI as SubscriptionFrequency, bJ as SubscriptionItem, bK as SubscriptionStatus, bL as TaxBreakdownLine, bM as VariantAxis, bN as VariantAxisValue, bO as WishlistItem, bP as err, bQ as ok, bR as toSdkError } from './client-BKNtLTcu.js';
1
+ import { P as ProductDetail, a as ProductVariant, B as BehioStorefront, S as SdkResult, C as CookieConsent } from './client-BU8Kfb74.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 StockBehavior, bD as StockMode, bE as SubmitQuoteInput, bF as SubmitReturnInput, bG as SubmitReviewInput, bH as Subscription, bI as SubscriptionAction, bJ as SubscriptionFrequency, bK as SubscriptionItem, bL as SubscriptionStatus, bM as TaxBreakdownLine, bN as VariantAxis, bO as VariantAxisValue, bP as WishlistItem, bQ as err, bR as ok, bS as toSdkError } from './client-BU8Kfb74.js';
3
3
 
4
4
  /**
5
5
  * Format a price amount with currency using Intl.NumberFormat.
@@ -11,6 +11,106 @@ export { A as ActivePromotion, a as AddToCartInput, b as AddressDetail, c as Add
11
11
  */
12
12
  declare function formatPrice(amount: number, currency: string, locale?: string): string;
13
13
 
14
+ /**
15
+ * Variant selection helpers — server-safe (no React, no DOM).
16
+ *
17
+ * Every storefront that sells variants needs the same four decisions, and every
18
+ * one of them has a wrong answer that looks right on screen:
19
+ *
20
+ * 1. WHICH variant is selected on first render. It has to be decided on the
21
+ * server from `?variant=`, otherwise the page renders the parent's text and
22
+ * swaps it after hydration — a visible flash, and the wrong text in view
23
+ * source for crawlers.
24
+ * 2. WHAT the page shows for it. A variant carries its own name, descriptions
25
+ * and gallery, but only where the merchant filled them in; everywhere else
26
+ * it INHERITS the parent. Rendering the raw variant fields shows empty
27
+ * blocks on shops that only translated the name.
28
+ * 3. WHERE a variant links. A variant has no page of its own, so the link is
29
+ * always the parent's slug plus `?variant=` (see `variantHref`).
30
+ * 4. WHICH variant a click means when there are several axes (colour + size):
31
+ * the answer is "the one matching the whole selection", not "the one whose
32
+ * label I clicked".
33
+ */
34
+
35
+ /** Query parameter carrying the preselected variant. One name, everywhere. */
36
+ declare const VARIANT_QUERY_PARAM = "variant";
37
+ /**
38
+ * Content actually rendered for a product page: the variant's own values where
39
+ * it has them, the parent's everywhere else.
40
+ */
41
+ interface ResolvedVariantContent {
42
+ name: string;
43
+ shortDescription: string | null;
44
+ longDescription: string | null;
45
+ images: ProductDetail["images"];
46
+ /** `true` for each field the variant overrode — handy for debugging a shop. */
47
+ overrides: {
48
+ name: boolean;
49
+ shortDescription: boolean;
50
+ longDescription: boolean;
51
+ images: boolean;
52
+ };
53
+ }
54
+ /**
55
+ * Merge a variant onto its parent product for rendering.
56
+ *
57
+ * Pass `variant: null` (nothing selected yet) and you get the parent unchanged,
58
+ * so a page can call this unconditionally.
59
+ */
60
+ declare function resolveVariantContent(product: ProductDetail, variant: ProductVariant | null | undefined): ResolvedVariantContent;
61
+ /**
62
+ * Variant preselected by the URL.
63
+ *
64
+ * Accepts whatever the framework hands you (`string`, the array Next.js gives
65
+ * for repeated params, or nothing) and falls back to `null` when the token
66
+ * matches no variant — a stale link must render the parent page, never a 404
67
+ * and never a blank picker.
68
+ */
69
+ declare function variantFromQuery(product: ProductDetail, value: string | string[] | null | undefined): ProductVariant | null;
70
+ /**
71
+ * Link to a product, optionally with a variant preselected.
72
+ *
73
+ * ALWAYS goes through the parent's slug. Building `/product/${variant.slug}`
74
+ * is the single most repeated bug around variants: it looks correct, and it
75
+ * 404s for every visitor, in the cart, in the XML feeds and in the admin's
76
+ * "open on the web" button — all three of which had exactly that bug.
77
+ */
78
+ declare function variantHref(productSlug: string, variant?: Pick<ProductVariant, "variantSlug"> | null, basePath?: string): string;
79
+ /**
80
+ * The variant matching a full axis selection (e.g. `{Barva: "modrá", Velikost:
81
+ * "M"}`). Returns `null` while the selection is incomplete or names a
82
+ * combination the merchant never published, which is the moment to disable the
83
+ * buy button rather than to add "some" variant to the cart.
84
+ */
85
+ declare function findVariantByAttributes(product: ProductDetail, selection: Record<string, string>): ProductVariant | null;
86
+ /**
87
+ * Axis values that lead to an existing variant given what is already picked.
88
+ *
89
+ * Without this a shop happily offers "modrá + XXL", which no variant covers, and
90
+ * the customer finds out by clicking. Pass the current partial selection and the
91
+ * axis being rendered; you get the values worth showing as enabled.
92
+ */
93
+ declare function availableAxisValues(product: ProductDetail, axisName: string, selection: Record<string, string>): string[];
94
+ /**
95
+ * Rows for a "compare the editions side by side" table: every axis that
96
+ * actually differs between variants, plus price and availability.
97
+ *
98
+ * Built here rather than in each template because the interesting part is what
99
+ * to LEAVE OUT: an axis all variants share carries no information and only
100
+ * makes the table wider.
101
+ */
102
+ interface VariantComparisonRow {
103
+ label: string;
104
+ /** One cell per variant, in `product.variants` order. */
105
+ values: string[];
106
+ }
107
+ declare function buildVariantComparison(product: ProductDetail, labels: {
108
+ price: string;
109
+ availability: string;
110
+ inStock: string;
111
+ soldOut: string;
112
+ }, formatPriceValue: (variant: ProductVariant) => string): VariantComparisonRow[];
113
+
14
114
  /**
15
115
  * GA4 e-commerce event helper.
16
116
  *
@@ -124,4 +224,4 @@ declare function revokeAnalyticsConsent(client: BehioStorefront): Promise<SdkRes
124
224
  success: boolean;
125
225
  }>>;
126
226
 
127
- export { BehioStorefront, CookieConsent, type EcommerceEventName, type EcommerceItem, type EcommercePayload, SdkResult, formatPrice, generateVisitorId, getStoredVisitorId, grantAnalyticsConsent, revokeAnalyticsConsent, trackEcommerceEvent };
227
+ export { BehioStorefront, CookieConsent, type EcommerceEventName, type EcommerceItem, type EcommercePayload, ProductDetail, ProductVariant, type ResolvedVariantContent, SdkResult, VARIANT_QUERY_PARAM, type VariantComparisonRow, availableAxisValues, buildVariantComparison, findVariantByAttributes, formatPrice, generateVisitorId, getStoredVisitorId, grantAnalyticsConsent, resolveVariantContent, revokeAnalyticsConsent, trackEcommerceEvent, variantFromQuery, variantHref };
package/dist/index.js CHANGED
@@ -27,6 +27,103 @@ function formatPrice(amount, currency, locale) {
27
27
  }
28
28
  }
29
29
 
30
+ // src/variants.ts
31
+ var VARIANT_QUERY_PARAM = "variant";
32
+ var filled = (value) => {
33
+ const trimmed = _optionalChain([value, 'optionalAccess', _ => _.trim, 'call', _2 => _2()]);
34
+ return trimmed ? trimmed : null;
35
+ };
36
+ function resolveVariantContent(product, variant) {
37
+ const name = filled(_optionalChain([variant, 'optionalAccess', _3 => _3.name]));
38
+ const short = filled(_optionalChain([variant, 'optionalAccess', _4 => _4.shortDescription]));
39
+ const long = filled(_optionalChain([variant, 'optionalAccess', _5 => _5.longDescription]));
40
+ const images = _optionalChain([variant, 'optionalAccess', _6 => _6.images, 'optionalAccess', _7 => _7.length]) ? variant.images : null;
41
+ return {
42
+ name: _nullishCoalesce(name, () => ( product.name)),
43
+ shortDescription: _nullishCoalesce(_nullishCoalesce(short, () => ( product.shortDescription)), () => ( null)),
44
+ longDescription: _nullishCoalesce(_nullishCoalesce(long, () => ( product.longDescription)), () => ( null)),
45
+ images: _nullishCoalesce(images, () => ( product.images)),
46
+ overrides: {
47
+ name: !!name && name !== product.name,
48
+ shortDescription: !!short,
49
+ longDescription: !!long,
50
+ images: !!images
51
+ }
52
+ };
53
+ }
54
+ function variantFromQuery(product, value) {
55
+ const token = Array.isArray(value) ? value[0] : value;
56
+ if (!token) return null;
57
+ return _nullishCoalesce(product.variants.find((v) => v.variantSlug === token || v.id === token), () => ( null));
58
+ }
59
+ function variantHref(productSlug, variant, basePath = "/product") {
60
+ const base = `${basePath}/${productSlug}`;
61
+ if (!_optionalChain([variant, 'optionalAccess', _8 => _8.variantSlug])) return base;
62
+ return `${base}?${VARIANT_QUERY_PARAM}=${encodeURIComponent(variant.variantSlug)}`;
63
+ }
64
+ function findVariantByAttributes(product, selection) {
65
+ const axes = Object.keys(selection);
66
+ if (axes.length === 0) return null;
67
+ return _nullishCoalesce(product.variants.find(
68
+ (variant) => axes.every((axis) => variant.attributes.some((a) => a.name === axis && a.value === selection[axis]))
69
+ ), () => ( null));
70
+ }
71
+ function availableAxisValues(product, axisName, selection) {
72
+ const others = Object.entries(selection).filter(([name]) => name !== axisName);
73
+ const values = /* @__PURE__ */ new Set();
74
+ for (const variant of product.variants) {
75
+ const matchesOthers = others.every(
76
+ ([name, value]) => variant.attributes.some((a) => a.name === name && a.value === value)
77
+ );
78
+ if (!matchesOthers) continue;
79
+ const own = variant.attributes.find((a) => a.name === axisName);
80
+ if (own) values.add(own.value);
81
+ }
82
+ return [...values];
83
+ }
84
+ function buildVariantComparison(product, labels, formatPriceValue) {
85
+ const rows = [];
86
+ const axisNames = /* @__PURE__ */ new Set();
87
+ for (const variant of product.variants) {
88
+ for (const attribute of variant.attributes) axisNames.add(attribute.name);
89
+ }
90
+ for (const axis of axisNames) {
91
+ const values = product.variants.map(
92
+ (v) => _nullishCoalesce(_optionalChain([v, 'access', _9 => _9.attributes, 'access', _10 => _10.find, 'call', _11 => _11((a) => a.name === axis), 'optionalAccess', _12 => _12.value]), () => ( "-"))
93
+ );
94
+ if (new Set(values).size <= 1) continue;
95
+ rows.push({ label: axis, values });
96
+ }
97
+ rows.push({
98
+ label: labels.price,
99
+ values: product.variants.map((v) => formatPriceValue(v))
100
+ });
101
+ rows.push({
102
+ label: labels.availability,
103
+ values: product.variants.map((v) => v.inStock ? labels.inStock : labels.soldOut)
104
+ });
105
+ const parameterLabels = /* @__PURE__ */ new Set();
106
+ for (const variant of product.variants) {
107
+ for (const group of _nullishCoalesce(variant.parameterGroups, () => ( []))) {
108
+ for (const parameter of _nullishCoalesce(group.parameters, () => ( []))) parameterLabels.add(parameter.label);
109
+ }
110
+ }
111
+ for (const label of parameterLabels) {
112
+ const values = product.variants.map((variant) => {
113
+ for (const group of _nullishCoalesce(variant.parameterGroups, () => ( []))) {
114
+ const hit = _optionalChain([group, 'access', _13 => _13.parameters, 'optionalAccess', _14 => _14.find, 'call', _15 => _15((p) => p.label === label)]);
115
+ if (!hit) continue;
116
+ if (hit.value) return [hit.value, hit.unit].filter(Boolean).join(" ");
117
+ if (hit.booleanValue !== null) return hit.booleanValue ? "\u2713" : "-";
118
+ }
119
+ return "-";
120
+ });
121
+ if (new Set(values).size <= 1) continue;
122
+ rows.push({ label, values });
123
+ }
124
+ return rows;
125
+ }
126
+
30
127
  // src/analytics.ts
31
128
  var GA4_NAME_MAP = {
32
129
  newsletter_signup: "generate_lead"
@@ -35,7 +132,7 @@ function trackEcommerceEvent(event, payload) {
35
132
  if (typeof window === "undefined") return;
36
133
  const w = window;
37
134
  try {
38
- _optionalChain([w, 'access', _ => _.__behioEcommerceSink, 'optionalCall', _2 => _2(event, payload)]);
135
+ _optionalChain([w, 'access', _16 => _16.__behioEcommerceSink, 'optionalCall', _17 => _17(event, payload)]);
39
136
  } catch (e2) {
40
137
  }
41
138
  const gaName = _nullishCoalesce(GA4_NAME_MAP[event], () => ( event));
@@ -67,12 +164,12 @@ function getStoredVisitorId() {
67
164
  function generateVisitorId() {
68
165
  const bytes = new Uint8Array(18);
69
166
  try {
70
- _optionalChain([globalThis, 'access', _3 => _3.crypto, 'optionalAccess', _4 => _4.getRandomValues, 'optionalCall', _5 => _5(bytes)]);
167
+ _optionalChain([globalThis, 'access', _18 => _18.crypto, 'optionalAccess', _19 => _19.getRandomValues, 'optionalCall', _20 => _20(bytes)]);
71
168
  } catch (e5) {
72
169
  }
73
- let filled = false;
74
- for (const b of bytes) if (b !== 0) filled = true;
75
- if (!filled) for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
170
+ let filled2 = false;
171
+ for (const b of bytes) if (b !== 0) filled2 = true;
172
+ if (!filled2) for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
76
173
  let bin = "";
77
174
  for (const b of bytes) bin += String.fromCharCode(b);
78
175
  const b64 = typeof btoa === "function" ? btoa(bin) : Buffer.from(bytes).toString("base64");
@@ -108,8 +205,8 @@ async function grantAnalyticsConsent(client, categories) {
108
205
  const res = await client.consent.record({
109
206
  visitorId: id,
110
207
  analytics: true,
111
- marketing: _nullishCoalesce(_optionalChain([categories, 'optionalAccess', _6 => _6.marketing]), () => ( false)),
112
- preferences: _nullishCoalesce(_optionalChain([categories, 'optionalAccess', _7 => _7.preferences]), () => ( false))
208
+ marketing: _nullishCoalesce(_optionalChain([categories, 'optionalAccess', _21 => _21.marketing]), () => ( false)),
209
+ preferences: _nullishCoalesce(_optionalChain([categories, 'optionalAccess', _22 => _22.preferences]), () => ( false))
113
210
  });
114
211
  emitConsentChanged();
115
212
  return res;
@@ -139,4 +236,11 @@ async function revokeAnalyticsConsent(client) {
139
236
 
140
237
 
141
238
 
142
- exports.AddressTypes = _chunkODAMBLGYjs.AddressTypes; exports.BehioApiError = _chunkODAMBLGYjs.BehioApiError; exports.BehioNetworkError = _chunkODAMBLGYjs.BehioNetworkError; exports.BehioStorefront = _chunkODAMBLGYjs.BehioStorefront; exports.FulfillmentStatuses = _chunkODAMBLGYjs.FulfillmentStatuses; exports.OrderStatuses = _chunkODAMBLGYjs.OrderStatuses; exports.PaymentStatuses = _chunkODAMBLGYjs.PaymentStatuses; exports.ProductSort = _chunkODAMBLGYjs.ProductSort; exports.err = _chunkODAMBLGYjs.err; exports.formatPrice = formatPrice; exports.generateVisitorId = generateVisitorId; exports.getStoredVisitorId = getStoredVisitorId; exports.grantAnalyticsConsent = grantAnalyticsConsent; exports.ok = _chunkODAMBLGYjs.ok; exports.revokeAnalyticsConsent = revokeAnalyticsConsent; exports.toSdkError = _chunkODAMBLGYjs.toSdkError; exports.trackEcommerceEvent = trackEcommerceEvent;
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+ exports.AddressTypes = _chunkODAMBLGYjs.AddressTypes; exports.BehioApiError = _chunkODAMBLGYjs.BehioApiError; exports.BehioNetworkError = _chunkODAMBLGYjs.BehioNetworkError; exports.BehioStorefront = _chunkODAMBLGYjs.BehioStorefront; exports.FulfillmentStatuses = _chunkODAMBLGYjs.FulfillmentStatuses; exports.OrderStatuses = _chunkODAMBLGYjs.OrderStatuses; exports.PaymentStatuses = _chunkODAMBLGYjs.PaymentStatuses; exports.ProductSort = _chunkODAMBLGYjs.ProductSort; exports.VARIANT_QUERY_PARAM = VARIANT_QUERY_PARAM; exports.availableAxisValues = availableAxisValues; exports.buildVariantComparison = buildVariantComparison; exports.err = _chunkODAMBLGYjs.err; exports.findVariantByAttributes = findVariantByAttributes; exports.formatPrice = formatPrice; exports.generateVisitorId = generateVisitorId; exports.getStoredVisitorId = getStoredVisitorId; exports.grantAnalyticsConsent = grantAnalyticsConsent; exports.ok = _chunkODAMBLGYjs.ok; exports.resolveVariantContent = resolveVariantContent; exports.revokeAnalyticsConsent = revokeAnalyticsConsent; exports.toSdkError = _chunkODAMBLGYjs.toSdkError; exports.trackEcommerceEvent = trackEcommerceEvent; exports.variantFromQuery = variantFromQuery; exports.variantHref = variantHref;
package/dist/index.mjs CHANGED
@@ -27,6 +27,103 @@ function formatPrice(amount, currency, locale) {
27
27
  }
28
28
  }
29
29
 
30
+ // src/variants.ts
31
+ var VARIANT_QUERY_PARAM = "variant";
32
+ var filled = (value) => {
33
+ const trimmed = value?.trim();
34
+ return trimmed ? trimmed : null;
35
+ };
36
+ function resolveVariantContent(product, variant) {
37
+ const name = filled(variant?.name);
38
+ const short = filled(variant?.shortDescription);
39
+ const long = filled(variant?.longDescription);
40
+ const images = variant?.images?.length ? variant.images : null;
41
+ return {
42
+ name: name ?? product.name,
43
+ shortDescription: short ?? product.shortDescription ?? null,
44
+ longDescription: long ?? product.longDescription ?? null,
45
+ images: images ?? product.images,
46
+ overrides: {
47
+ name: !!name && name !== product.name,
48
+ shortDescription: !!short,
49
+ longDescription: !!long,
50
+ images: !!images
51
+ }
52
+ };
53
+ }
54
+ function variantFromQuery(product, value) {
55
+ const token = Array.isArray(value) ? value[0] : value;
56
+ if (!token) return null;
57
+ return product.variants.find((v) => v.variantSlug === token || v.id === token) ?? null;
58
+ }
59
+ function variantHref(productSlug, variant, basePath = "/product") {
60
+ const base = `${basePath}/${productSlug}`;
61
+ if (!variant?.variantSlug) return base;
62
+ return `${base}?${VARIANT_QUERY_PARAM}=${encodeURIComponent(variant.variantSlug)}`;
63
+ }
64
+ function findVariantByAttributes(product, selection) {
65
+ const axes = Object.keys(selection);
66
+ if (axes.length === 0) return null;
67
+ return product.variants.find(
68
+ (variant) => axes.every((axis) => variant.attributes.some((a) => a.name === axis && a.value === selection[axis]))
69
+ ) ?? null;
70
+ }
71
+ function availableAxisValues(product, axisName, selection) {
72
+ const others = Object.entries(selection).filter(([name]) => name !== axisName);
73
+ const values = /* @__PURE__ */ new Set();
74
+ for (const variant of product.variants) {
75
+ const matchesOthers = others.every(
76
+ ([name, value]) => variant.attributes.some((a) => a.name === name && a.value === value)
77
+ );
78
+ if (!matchesOthers) continue;
79
+ const own = variant.attributes.find((a) => a.name === axisName);
80
+ if (own) values.add(own.value);
81
+ }
82
+ return [...values];
83
+ }
84
+ function buildVariantComparison(product, labels, formatPriceValue) {
85
+ const rows = [];
86
+ const axisNames = /* @__PURE__ */ new Set();
87
+ for (const variant of product.variants) {
88
+ for (const attribute of variant.attributes) axisNames.add(attribute.name);
89
+ }
90
+ for (const axis of axisNames) {
91
+ const values = product.variants.map(
92
+ (v) => v.attributes.find((a) => a.name === axis)?.value ?? "-"
93
+ );
94
+ if (new Set(values).size <= 1) continue;
95
+ rows.push({ label: axis, values });
96
+ }
97
+ rows.push({
98
+ label: labels.price,
99
+ values: product.variants.map((v) => formatPriceValue(v))
100
+ });
101
+ rows.push({
102
+ label: labels.availability,
103
+ values: product.variants.map((v) => v.inStock ? labels.inStock : labels.soldOut)
104
+ });
105
+ const parameterLabels = /* @__PURE__ */ new Set();
106
+ for (const variant of product.variants) {
107
+ for (const group of variant.parameterGroups ?? []) {
108
+ for (const parameter of group.parameters ?? []) parameterLabels.add(parameter.label);
109
+ }
110
+ }
111
+ for (const label of parameterLabels) {
112
+ const values = product.variants.map((variant) => {
113
+ for (const group of variant.parameterGroups ?? []) {
114
+ const hit = group.parameters?.find((p) => p.label === label);
115
+ if (!hit) continue;
116
+ if (hit.value) return [hit.value, hit.unit].filter(Boolean).join(" ");
117
+ if (hit.booleanValue !== null) return hit.booleanValue ? "\u2713" : "-";
118
+ }
119
+ return "-";
120
+ });
121
+ if (new Set(values).size <= 1) continue;
122
+ rows.push({ label, values });
123
+ }
124
+ return rows;
125
+ }
126
+
30
127
  // src/analytics.ts
31
128
  var GA4_NAME_MAP = {
32
129
  newsletter_signup: "generate_lead"
@@ -70,9 +167,9 @@ function generateVisitorId() {
70
167
  globalThis.crypto?.getRandomValues?.(bytes);
71
168
  } catch {
72
169
  }
73
- let filled = false;
74
- for (const b of bytes) if (b !== 0) filled = true;
75
- if (!filled) for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
170
+ let filled2 = false;
171
+ for (const b of bytes) if (b !== 0) filled2 = true;
172
+ if (!filled2) for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
76
173
  let bin = "";
77
174
  for (const b of bytes) bin += String.fromCharCode(b);
78
175
  const b64 = typeof btoa === "function" ? btoa(bin) : Buffer.from(bytes).toString("base64");
@@ -130,13 +227,20 @@ export {
130
227
  OrderStatuses,
131
228
  PaymentStatuses,
132
229
  ProductSort,
230
+ VARIANT_QUERY_PARAM,
231
+ availableAxisValues,
232
+ buildVariantComparison,
133
233
  err,
234
+ findVariantByAttributes,
134
235
  formatPrice,
135
236
  generateVisitorId,
136
237
  getStoredVisitorId,
137
238
  grantAnalyticsConsent,
138
239
  ok,
240
+ resolveVariantContent,
139
241
  revokeAnalyticsConsent,
140
242
  toSdkError,
141
- trackEcommerceEvent
243
+ trackEcommerceEvent,
244
+ variantFromQuery,
245
+ variantHref
142
246
  };
package/dist/next.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as BehioStorefrontConfig, B as BehioStorefront } from './client-BKNtLTcu.mjs';
1
+ import { o as BehioStorefrontConfig, B as BehioStorefront } from './client-BU8Kfb74.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 { n as BehioStorefrontConfig, B as BehioStorefront } from './client-BKNtLTcu.js';
1
+ import { o as BehioStorefrontConfig, B as BehioStorefront } from './client-BU8Kfb74.js';
2
2
 
3
3
  interface GetBehioOptions extends Partial<BehioStorefrontConfig> {
4
4
  /** Override the cart session cookie name (default: "behio_cart_session"). */
package/dist/react.d.mts CHANGED
@@ -327,7 +327,55 @@ interface ProductVariant {
327
327
  */
328
328
  id: string;
329
329
  sku: string;
330
+ /**
331
+ * Variant name in the requested locale. Before SDK 1.1.0 this was always the
332
+ * warehouse item name, so translated shops showed one language to everyone.
333
+ */
330
334
  name: string;
335
+ /**
336
+ * Deep-link token for this variant — NOT a URL of its own.
337
+ *
338
+ * A variant has no standalone product page: the catalog 404s its slug and
339
+ * every listing excludes it, because a variant is bought from the parent's
340
+ * detail page. Link to `/product/{product.slug}?variant={variant.variantSlug}`
341
+ * and preselect the variant from that query parameter.
342
+ *
343
+ * Added in SDK 1.1.0.
344
+ */
345
+ variantSlug: string;
346
+ /**
347
+ * Short description of THIS variant, or `null` when the merchant left it
348
+ * empty. `null` means INHERIT: fall back to `ProductDetail.shortDescription`
349
+ * instead of rendering an empty block. Sanitised HTML.
350
+ *
351
+ * Added in SDK 1.1.0.
352
+ */
353
+ shortDescription?: string | null;
354
+ /** Long description of THIS variant. Same inherit-on-null contract as
355
+ * `shortDescription`. Added in SDK 1.1.0. */
356
+ longDescription?: string | null;
357
+ /**
358
+ * Gallery of THIS variant, ordered. Empty means the variant has no photos of
359
+ * its own, so keep showing the parent's gallery.
360
+ *
361
+ * Added in SDK 1.1.0.
362
+ */
363
+ images: ProductDetail["images"];
364
+ /**
365
+ * Per-variant SEO/OG overrides, or `null` when the merchant wrote none. The
366
+ * canonical URL stays the parent's, so use these only when a variant is
367
+ * preselected via `?variant=`.
368
+ *
369
+ * Added in SDK 1.1.0.
370
+ */
371
+ seo?: {
372
+ title?: string | null;
373
+ description?: string | null;
374
+ keywords?: string | null;
375
+ ogTitle?: string | null;
376
+ ogDescription?: string | null;
377
+ ogImage?: string | null;
378
+ } | null;
331
379
  /**
332
380
  * Axis name/value pairs identifying this variant (e.g.
333
381
  * `[{name: 'Barva', value: 'červená'}]`) — matches the wire shape the API
@@ -569,6 +617,25 @@ interface VariantAxisValue {
569
617
  * configured the axis (the storefront's historical default). Join to
570
618
  * `variants[].attributes` by axis `name` + `value`.
571
619
  */
620
+ /**
621
+ * Sourozenecká karta při rozpadu katalogu podle osy (typicky barvy).
622
+ *
623
+ * Každá barva je samostatný produkt s vlastní adresou, fotkami a SEO, takže
624
+ * kolečka barev se vykreslují jako odkazy (`<a href>`), ne jako přepínač uvnitř
625
+ * stránky. Bez odkazu by je nešlo indexovat a nefungovaly by bez JavaScriptu.
626
+ */
627
+ interface ProductSibling {
628
+ productId: string;
629
+ /** Adresa karty; skládá se s cestou produktu ve storefrontu. */
630
+ slug: string;
631
+ name: string;
632
+ /** Hodnota osy ("Růžová"); null u hlavního produktu skupiny. */
633
+ axisValue: string | null;
634
+ swatchColor: string | null;
635
+ swatchImage: string | null;
636
+ /** Tahle karta je právě otevřená stránka. */
637
+ isCurrent: boolean;
638
+ }
572
639
  interface VariantAxis {
573
640
  name: string;
574
641
  displayType: "DROPDOWN" | "BUTTON" | "SWATCH_COLOR" | "SWATCH_IMAGE";
@@ -639,6 +706,11 @@ interface ProductDetail extends ProductListItem {
639
706
  * Empty when the product has no variants.
640
707
  */
641
708
  variantAxes: VariantAxis[];
709
+ /**
710
+ * Sourozenecké karty při rozpadu podle osy. Prázdné u e-shopu, který rozpad
711
+ * nepoužívá, tedy ve výchozím nastavení.
712
+ */
713
+ catalogSiblings: ProductSibling[];
642
714
  volumePricing: ProductVolumePrice[];
643
715
  /**
644
716
  * Curated parameter groups, already resolved. Empty when the merchant
@@ -948,7 +1020,22 @@ interface LoginInput {
948
1020
  password: string;
949
1021
  }
950
1022
  interface CartItemProduct {
1023
+ /**
1024
+ * Slug of the page this line links to. For a variant line this is the
1025
+ * PARENT's slug: a variant has no page of its own, so linking to its own slug
1026
+ * landed customers on a 404 (fixed 2026-08-03, SDK 1.1.0).
1027
+ */
951
1028
  slug: string;
1029
+ /**
1030
+ * Deep-link token of the variant on this line, `null` for a plain product.
1031
+ * Build the link as `/product/{slug}?variant={variantSlug}` so the customer
1032
+ * returns to the exact variant sitting in their cart.
1033
+ *
1034
+ * Added in SDK 1.1.0.
1035
+ */
1036
+ variantSlug?: string | null;
1037
+ /** Product name in the CART's language. Before SDK 1.1.0 the API picked an
1038
+ * arbitrary translation row, so this could come back in another language. */
952
1039
  name: string;
953
1040
  sku: string;
954
1041
  imageUrl?: string;
package/dist/react.d.ts CHANGED
@@ -327,7 +327,55 @@ interface ProductVariant {
327
327
  */
328
328
  id: string;
329
329
  sku: string;
330
+ /**
331
+ * Variant name in the requested locale. Before SDK 1.1.0 this was always the
332
+ * warehouse item name, so translated shops showed one language to everyone.
333
+ */
330
334
  name: string;
335
+ /**
336
+ * Deep-link token for this variant — NOT a URL of its own.
337
+ *
338
+ * A variant has no standalone product page: the catalog 404s its slug and
339
+ * every listing excludes it, because a variant is bought from the parent's
340
+ * detail page. Link to `/product/{product.slug}?variant={variant.variantSlug}`
341
+ * and preselect the variant from that query parameter.
342
+ *
343
+ * Added in SDK 1.1.0.
344
+ */
345
+ variantSlug: string;
346
+ /**
347
+ * Short description of THIS variant, or `null` when the merchant left it
348
+ * empty. `null` means INHERIT: fall back to `ProductDetail.shortDescription`
349
+ * instead of rendering an empty block. Sanitised HTML.
350
+ *
351
+ * Added in SDK 1.1.0.
352
+ */
353
+ shortDescription?: string | null;
354
+ /** Long description of THIS variant. Same inherit-on-null contract as
355
+ * `shortDescription`. Added in SDK 1.1.0. */
356
+ longDescription?: string | null;
357
+ /**
358
+ * Gallery of THIS variant, ordered. Empty means the variant has no photos of
359
+ * its own, so keep showing the parent's gallery.
360
+ *
361
+ * Added in SDK 1.1.0.
362
+ */
363
+ images: ProductDetail["images"];
364
+ /**
365
+ * Per-variant SEO/OG overrides, or `null` when the merchant wrote none. The
366
+ * canonical URL stays the parent's, so use these only when a variant is
367
+ * preselected via `?variant=`.
368
+ *
369
+ * Added in SDK 1.1.0.
370
+ */
371
+ seo?: {
372
+ title?: string | null;
373
+ description?: string | null;
374
+ keywords?: string | null;
375
+ ogTitle?: string | null;
376
+ ogDescription?: string | null;
377
+ ogImage?: string | null;
378
+ } | null;
331
379
  /**
332
380
  * Axis name/value pairs identifying this variant (e.g.
333
381
  * `[{name: 'Barva', value: 'červená'}]`) — matches the wire shape the API
@@ -569,6 +617,25 @@ interface VariantAxisValue {
569
617
  * configured the axis (the storefront's historical default). Join to
570
618
  * `variants[].attributes` by axis `name` + `value`.
571
619
  */
620
+ /**
621
+ * Sourozenecká karta při rozpadu katalogu podle osy (typicky barvy).
622
+ *
623
+ * Každá barva je samostatný produkt s vlastní adresou, fotkami a SEO, takže
624
+ * kolečka barev se vykreslují jako odkazy (`<a href>`), ne jako přepínač uvnitř
625
+ * stránky. Bez odkazu by je nešlo indexovat a nefungovaly by bez JavaScriptu.
626
+ */
627
+ interface ProductSibling {
628
+ productId: string;
629
+ /** Adresa karty; skládá se s cestou produktu ve storefrontu. */
630
+ slug: string;
631
+ name: string;
632
+ /** Hodnota osy ("Růžová"); null u hlavního produktu skupiny. */
633
+ axisValue: string | null;
634
+ swatchColor: string | null;
635
+ swatchImage: string | null;
636
+ /** Tahle karta je právě otevřená stránka. */
637
+ isCurrent: boolean;
638
+ }
572
639
  interface VariantAxis {
573
640
  name: string;
574
641
  displayType: "DROPDOWN" | "BUTTON" | "SWATCH_COLOR" | "SWATCH_IMAGE";
@@ -639,6 +706,11 @@ interface ProductDetail extends ProductListItem {
639
706
  * Empty when the product has no variants.
640
707
  */
641
708
  variantAxes: VariantAxis[];
709
+ /**
710
+ * Sourozenecké karty při rozpadu podle osy. Prázdné u e-shopu, který rozpad
711
+ * nepoužívá, tedy ve výchozím nastavení.
712
+ */
713
+ catalogSiblings: ProductSibling[];
642
714
  volumePricing: ProductVolumePrice[];
643
715
  /**
644
716
  * Curated parameter groups, already resolved. Empty when the merchant
@@ -948,7 +1020,22 @@ interface LoginInput {
948
1020
  password: string;
949
1021
  }
950
1022
  interface CartItemProduct {
1023
+ /**
1024
+ * Slug of the page this line links to. For a variant line this is the
1025
+ * PARENT's slug: a variant has no page of its own, so linking to its own slug
1026
+ * landed customers on a 404 (fixed 2026-08-03, SDK 1.1.0).
1027
+ */
951
1028
  slug: string;
1029
+ /**
1030
+ * Deep-link token of the variant on this line, `null` for a plain product.
1031
+ * Build the link as `/product/{slug}?variant={variantSlug}` so the customer
1032
+ * returns to the exact variant sitting in their cart.
1033
+ *
1034
+ * Added in SDK 1.1.0.
1035
+ */
1036
+ variantSlug?: string | null;
1037
+ /** Product name in the CART's language. Before SDK 1.1.0 the API picked an
1038
+ * arbitrary translation row, so this could come back in another language. */
952
1039
  name: string;
953
1040
  sku: string;
954
1041
  imageUrl?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@behio/storefront-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "TypeScript SDK for Behio Headless E-Shop — core client + React hooks",
5
5
  "author": "Behio",
6
6
  "license": "MIT",