@behio/storefront-sdk 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -509,6 +509,7 @@ const tracked = await shop.orders.track('tracking-token-uuid');
509
509
  | Hook | Purpose | Auth required |
510
510
  |------|---------|---------------|
511
511
  | [`useShopInfo()`](#useshopinfo) | E-shop info (name, currencies, languages) | No |
512
+ | [`useShopSeo(opts?)`](#useshopseo) | Per-locale SEO metadata for the homepage | No |
512
513
  | [`useProducts(query?)`](#useproducts) | Product list with filters, pagination, search | No |
513
514
  | [`useProduct(slug)`](#useproduct) | Product detail | No |
514
515
  | [`useCategories(locale?)`](#usecategories) | Category tree | No |
@@ -525,6 +526,9 @@ const tracked = await shop.orders.track('tracking-token-uuid');
525
526
  | [`useCustomer()`](#usecustomer) | Profile + update | Yes |
526
527
  | [`useAddresses()`](#useaddresses) | Address CRUD | Yes |
527
528
  | [`usePages()` / `usePage(slug)`](#usepages) | CMS pages | No |
529
+ | [`useBundles()` / `useBundle(slug)`](#usebundles) | Active bundles (sets) with auto-computed savings | No |
530
+ | [`useCrossSell(productSlug)`](#usecrosssell) | Related / upsell / cross-sell products per product | No |
531
+ | [`useProductPromotions(productSlug)`](#useproductpromotions) | Active promotions applicable to a product (with countdown) | No |
528
532
 
529
533
  \* Guest checkout works without auth if the e-shop allows it.
530
534
 
@@ -534,6 +538,55 @@ const { data, isLoading, error } = useShopInfo();
534
538
  // data: ShopInfo
535
539
  ```
536
540
 
541
+ ### useShopSeo
542
+
543
+ Returns per-locale SEO metadata (title, description, keywords, OG tags). Falls back to the shop's default locale when `locale` is omitted, and to `metaTitle / metaDescription` on the shop itself if there's no per-locale override.
544
+
545
+ ```tsx
546
+ const { data: seo } = useShopSeo({ locale: 'cs' });
547
+ // data: { locale, title, description, keywords, ogTitle, ogDescription, ogImage }
548
+ ```
549
+
550
+ **Server-side / SSR** — use the core client directly to fetch at request time and pass as `initialData`:
551
+
552
+ ```tsx
553
+ // app/[locale]/page.tsx (Next.js RSC)
554
+ import { BehioStorefront } from '@behio/storefront-sdk';
555
+ import type { Metadata } from 'next';
556
+
557
+ const shop = new BehioStorefront({ apiKey: process.env.BEHIO_API_KEY! });
558
+
559
+ export async function generateMetadata({ params }: { params: { locale: string } }): Promise<Metadata> {
560
+ const seo = await shop.getShopSeo(params.locale);
561
+ return {
562
+ title: seo.title ?? undefined,
563
+ description: seo.description ?? undefined,
564
+ openGraph: {
565
+ title: seo.ogTitle ?? seo.title ?? undefined,
566
+ description: seo.ogDescription ?? seo.description ?? undefined,
567
+ images: seo.ogImage ? [seo.ogImage] : undefined,
568
+ },
569
+ };
570
+ }
571
+
572
+ export default async function Home({ params }: { params: { locale: string } }) {
573
+ const seo = await shop.getShopSeo(params.locale);
574
+ // Pass to client component for React Query hydration:
575
+ // <ClientHome initialSeo={seo} />
576
+ }
577
+ ```
578
+
579
+ Client hydration:
580
+ ```tsx
581
+ 'use client';
582
+ import { useShopSeo } from '@behio/storefront-sdk/react';
583
+
584
+ export function ClientHome({ initialSeo }: { initialSeo: ShopSeo }) {
585
+ const { data } = useShopSeo({ locale: 'cs', initialData: initialSeo });
586
+ return <h1>{data.title}</h1>;
587
+ }
588
+ ```
589
+
537
590
  ### useProducts
538
591
 
539
592
  Supports **both** traditional pagination and infinite scroll from one hook.
@@ -735,6 +788,49 @@ const { data: pages } = usePages('cs');
735
788
  const { data: page } = usePage('about-us', 'cs');
736
789
  ```
737
790
 
791
+ ### useBundles
792
+ ```typescript
793
+ import { useBundles, useBundle } from '@behio/storefront-sdk/react';
794
+
795
+ // List
796
+ const { data } = useBundles();
797
+ data?.items.forEach((b) => console.log(b.name, b.savingsPercent, '%'));
798
+
799
+ // Detail
800
+ const { data: bundle } = useBundle('startovaci-balicek');
801
+ // bundle: { name, bundlePrice, itemsSum, savings, items: [{ productId, quantity, ... }] }
802
+
803
+ // Add to cart — uses existing useCart hook
804
+ const { cart, refresh } = useCart();
805
+ await shop.cart.addBundle(bundle.id, 1);
806
+ await refresh();
807
+ ```
808
+
809
+ ### useCrossSell
810
+ ```typescript
811
+ import { useCrossSell } from '@behio/storefront-sdk/react';
812
+
813
+ const { data } = useCrossSell(product.slug);
814
+ // data: { related: CrossSellItem[], upsell: CrossSellItem[], crossSell: CrossSellItem[] }
815
+
816
+ // Render sections on product detail page
817
+ <CrossSellSection title="Často kupováno s" items={data?.crossSell} />
818
+ <CrossSellSection title="Podobné produkty" items={data?.related} />
819
+ ```
820
+
821
+ ### useProductPromotions
822
+ ```typescript
823
+ import { useProductPromotions } from '@behio/storefront-sdk/react';
824
+
825
+ // Auto-refetch every 5 seconds so the countdown stays accurate on long-lived pages
826
+ const { data } = useProductPromotions(product.slug, { refetchIntervalMs: 5000 });
827
+
828
+ data?.items.forEach((promo) => {
829
+ // promo: { name, discountType, discountValue, endsAt, badgeText, badgeColor, ... }
830
+ // Use endsAt to render a live countdown: new Date(promo.endsAt) - Date.now()
831
+ });
832
+ ```
833
+
738
834
  ## All API methods
739
835
 
740
836
  ### Catalog
@@ -748,6 +844,17 @@ shop.catalog.getLabels(locale?) → { labels: ProductLabel[] }
748
844
  shop.catalog.getFeatured() → PaginatedResponse<ProductListItem>
749
845
  shop.catalog.getFilters() → { filters: FilterField[] }
750
846
  shop.catalog.search(query, opts?) → PaginatedResponse<ProductListItem>
847
+ shop.catalog.getBundles() → { items: Bundle[] }
848
+ shop.catalog.getBundle(slug) → Bundle
849
+ shop.catalog.getCrossSell(productSlug) → { related, upsell, crossSell: CrossSellItem[] }
850
+ shop.catalog.getProductPromotions(slug) → { items: ActivePromotion[] }
851
+ ```
852
+
853
+ ### Cart — bundles
854
+ ```typescript
855
+ shop.cart.addBundle(bundleId, quantity?) → Cart
856
+ shop.cart.updateBundleQuantity(id, qty) → Cart
857
+ shop.cart.removeBundle(bundleId) → Cart
751
858
  ```
752
859
 
753
860
  ### Auth
@@ -807,6 +914,7 @@ shop.pages.get(slug, locale?) → PageDetail
807
914
  ### Instance utilities
808
915
  ```typescript
809
916
  shop.getShopInfo() → ShopInfo
917
+ shop.getShopSeo(locale?) → ShopSeo (per-locale SEO for SSR/metadata)
810
918
  shop.setTokens({ accessToken, refreshToken })
811
919
  shop.clearTokens()
812
920
  shop.getAccessToken() → string | undefined
@@ -108,6 +108,12 @@ var BehioStorefront = class {
108
108
  async getShopInfo() {
109
109
  return this.request("GET", "/shop");
110
110
  }
111
+ /** Get SEO metadata for the shop homepage in the given locale (defaults to shop default). */
112
+ async getShopSeo(locale) {
113
+ return this.request("GET", "/shop/seo", {
114
+ query: locale ? { locale } : void 0
115
+ });
116
+ }
111
117
  /** Set auth tokens (e.g. from localStorage) */
112
118
  setTokens(tokens) {
113
119
  this.accessToken = tokens.accessToken;
@@ -396,6 +402,22 @@ var CatalogModule = class {
396
402
  async search(query, options) {
397
403
  return this.getProducts({ search: query, ...options });
398
404
  }
405
+ /** List all active bundles */
406
+ async getBundles() {
407
+ return this.client.request("GET", "/catalog/bundles");
408
+ }
409
+ /** Get a single bundle by slug */
410
+ async getBundle(slug) {
411
+ return this.client.request("GET", `/catalog/bundles/${slug}`);
412
+ }
413
+ /** Cross-sell / related / upsell products for a product */
414
+ async getCrossSell(productSlug) {
415
+ return this.client.request("GET", `/catalog/products/${productSlug}/cross-sell`);
416
+ }
417
+ /** Active promotions applicable to a product (with countdown end time) */
418
+ async getProductPromotions(productSlug) {
419
+ return this.client.request("GET", `/catalog/products/${productSlug}/promotions`);
420
+ }
399
421
  };
400
422
  var AuthModule = class {
401
423
  constructor(client) {
@@ -507,6 +529,28 @@ var CartModule = class {
507
529
  this.client.emit("cart:cleared");
508
530
  return result;
509
531
  }
532
+ /** Add a bundle to the cart (price is locked at the bundle's current price) */
533
+ async addBundle(bundleId, quantity = 1) {
534
+ const result = await this.client.request("POST", "/cart/bundles", {
535
+ body: { bundleId, quantity }
536
+ });
537
+ this.client.emit("cart:updated", result);
538
+ return result;
539
+ }
540
+ /** Update quantity of a bundle already in the cart */
541
+ async updateBundleQuantity(bundleId, quantity) {
542
+ const result = await this.client.request("PATCH", `/cart/bundles/${bundleId}`, {
543
+ body: { quantity }
544
+ });
545
+ this.client.emit("cart:updated", result);
546
+ return result;
547
+ }
548
+ /** Remove a bundle from the cart */
549
+ async removeBundle(bundleId) {
550
+ const result = await this.client.request("DELETE", `/cart/bundles/${bundleId}`);
551
+ this.client.emit("cart:updated", result);
552
+ return result;
553
+ }
510
554
  /** Merge anonymous cart into authenticated customer cart */
511
555
  async merge() {
512
556
  const result = await this.client.request("POST", "/cart/merge");
@@ -561,7 +605,7 @@ var OrdersModule = class {
561
605
  async cancel(orderNumber) {
562
606
  return this.client.request("POST", `/orders/${orderNumber}/cancel`);
563
607
  }
564
- /** Track order by tracking token (no auth required) */
608
+ /** Track order by tracking token (no customer login required, only API key) */
565
609
  async track(trackingToken) {
566
610
  return this.client.request("GET", `/orders/track/${trackingToken}`, { auth: false });
567
611
  }
@@ -108,6 +108,12 @@ var BehioStorefront = class {
108
108
  async getShopInfo() {
109
109
  return this.request("GET", "/shop");
110
110
  }
111
+ /** Get SEO metadata for the shop homepage in the given locale (defaults to shop default). */
112
+ async getShopSeo(locale) {
113
+ return this.request("GET", "/shop/seo", {
114
+ query: locale ? { locale } : void 0
115
+ });
116
+ }
111
117
  /** Set auth tokens (e.g. from localStorage) */
112
118
  setTokens(tokens) {
113
119
  this.accessToken = tokens.accessToken;
@@ -396,6 +402,22 @@ var CatalogModule = class {
396
402
  async search(query, options) {
397
403
  return this.getProducts({ search: query, ...options });
398
404
  }
405
+ /** List all active bundles */
406
+ async getBundles() {
407
+ return this.client.request("GET", "/catalog/bundles");
408
+ }
409
+ /** Get a single bundle by slug */
410
+ async getBundle(slug) {
411
+ return this.client.request("GET", `/catalog/bundles/${slug}`);
412
+ }
413
+ /** Cross-sell / related / upsell products for a product */
414
+ async getCrossSell(productSlug) {
415
+ return this.client.request("GET", `/catalog/products/${productSlug}/cross-sell`);
416
+ }
417
+ /** Active promotions applicable to a product (with countdown end time) */
418
+ async getProductPromotions(productSlug) {
419
+ return this.client.request("GET", `/catalog/products/${productSlug}/promotions`);
420
+ }
399
421
  };
400
422
  var AuthModule = class {
401
423
  constructor(client) {
@@ -507,6 +529,28 @@ var CartModule = class {
507
529
  this.client.emit("cart:cleared");
508
530
  return result;
509
531
  }
532
+ /** Add a bundle to the cart (price is locked at the bundle's current price) */
533
+ async addBundle(bundleId, quantity = 1) {
534
+ const result = await this.client.request("POST", "/cart/bundles", {
535
+ body: { bundleId, quantity }
536
+ });
537
+ this.client.emit("cart:updated", result);
538
+ return result;
539
+ }
540
+ /** Update quantity of a bundle already in the cart */
541
+ async updateBundleQuantity(bundleId, quantity) {
542
+ const result = await this.client.request("PATCH", `/cart/bundles/${bundleId}`, {
543
+ body: { quantity }
544
+ });
545
+ this.client.emit("cart:updated", result);
546
+ return result;
547
+ }
548
+ /** Remove a bundle from the cart */
549
+ async removeBundle(bundleId) {
550
+ const result = await this.client.request("DELETE", `/cart/bundles/${bundleId}`);
551
+ this.client.emit("cart:updated", result);
552
+ return result;
553
+ }
510
554
  /** Merge anonymous cart into authenticated customer cart */
511
555
  async merge() {
512
556
  const result = await this.client.request("POST", "/cart/merge");
@@ -561,7 +605,7 @@ var OrdersModule = class {
561
605
  async cancel(orderNumber) {
562
606
  return this.client.request("POST", `/orders/${orderNumber}/cancel`);
563
607
  }
564
- /** Track order by tracking token (no auth required) */
608
+ /** Track order by tracking token (no customer login required, only API key) */
565
609
  async track(trackingToken) {
566
610
  return this.client.request("GET", `/orders/track/${trackingToken}`, { auth: false });
567
611
  }
package/dist/index.d.mts CHANGED
@@ -41,6 +41,15 @@ interface ShopInfo {
41
41
  metaDescription?: string;
42
42
  allowGuestCheckout: boolean;
43
43
  }
44
+ interface ShopSeo {
45
+ locale: string;
46
+ title: string | null;
47
+ description: string | null;
48
+ keywords: string | null;
49
+ ogTitle: string | null;
50
+ ogDescription: string | null;
51
+ ogImage: string | null;
52
+ }
44
53
  interface ProductPrice {
45
54
  amount: number;
46
55
  currency: string;
@@ -381,6 +390,52 @@ interface ResponseInterceptorData {
381
390
  interface ResponseInterceptor {
382
391
  (response: ResponseInterceptorData): void | Promise<void>;
383
392
  }
393
+ interface BundleItem {
394
+ productId: string;
395
+ slug: string | null;
396
+ name: string;
397
+ sku: string;
398
+ quantity: number;
399
+ imageUrl: string | null;
400
+ defaultPrice: number | null;
401
+ }
402
+ interface Bundle {
403
+ id: string;
404
+ slug: string;
405
+ name: string;
406
+ description: string | null;
407
+ bundlePrice: number;
408
+ currency: string;
409
+ coverImage: string | null;
410
+ endsAt: number | null;
411
+ itemsSum: number;
412
+ savings: number;
413
+ savingsPercent: number;
414
+ items: BundleItem[];
415
+ }
416
+ interface CrossSellItem {
417
+ productId: string;
418
+ slug: string | null;
419
+ name: string;
420
+ sku: string;
421
+ price: number | null;
422
+ imageUrl: string | null;
423
+ stockCached: number;
424
+ }
425
+ interface ActivePromotion {
426
+ id: string;
427
+ name: string;
428
+ slug: string;
429
+ type: string;
430
+ discountType: string;
431
+ discountValue: number;
432
+ startsAt: number;
433
+ endsAt: number | null;
434
+ badgeText: string | null;
435
+ badgeColor: string | null;
436
+ showCountdown: boolean;
437
+ couponRequired: boolean;
438
+ }
384
439
 
385
440
  declare class BehioStorefront {
386
441
  private baseUrl;
@@ -411,6 +466,8 @@ declare class BehioStorefront {
411
466
  readonly pages: PagesModule;
412
467
  /** Get basic shop info */
413
468
  getShopInfo(): Promise<ShopInfo>;
469
+ /** Get SEO metadata for the shop homepage in the given locale (defaults to shop default). */
470
+ getShopSeo(locale?: string): Promise<ShopSeo>;
414
471
  /** Set auth tokens (e.g. from localStorage) */
415
472
  setTokens(tokens: {
416
473
  accessToken: string;
@@ -488,6 +545,22 @@ declare class CatalogModule {
488
545
  page?: number;
489
546
  limit?: number;
490
547
  }): Promise<PaginatedResponse<ProductListItem>>;
548
+ /** List all active bundles */
549
+ getBundles(): Promise<{
550
+ items: Bundle[];
551
+ }>;
552
+ /** Get a single bundle by slug */
553
+ getBundle(slug: string): Promise<Bundle>;
554
+ /** Cross-sell / related / upsell products for a product */
555
+ getCrossSell(productSlug: string): Promise<{
556
+ related: CrossSellItem[];
557
+ upsell: CrossSellItem[];
558
+ crossSell: CrossSellItem[];
559
+ }>;
560
+ /** Active promotions applicable to a product (with countdown end time) */
561
+ getProductPromotions(productSlug: string): Promise<{
562
+ items: ActivePromotion[];
563
+ }>;
491
564
  }
492
565
  declare class AuthModule {
493
566
  private client;
@@ -524,6 +597,12 @@ declare class CartModule {
524
597
  removeItem(itemId: string): Promise<Cart>;
525
598
  /** Clear entire cart */
526
599
  clear(): Promise<void>;
600
+ /** Add a bundle to the cart (price is locked at the bundle's current price) */
601
+ addBundle(bundleId: string, quantity?: number): Promise<Cart>;
602
+ /** Update quantity of a bundle already in the cart */
603
+ updateBundleQuantity(bundleId: string, quantity: number): Promise<Cart>;
604
+ /** Remove a bundle from the cart */
605
+ removeBundle(bundleId: string): Promise<Cart>;
527
606
  /** Merge anonymous cart into authenticated customer cart */
528
607
  merge(): Promise<Cart>;
529
608
  /** Apply discount code */
@@ -549,7 +628,7 @@ declare class OrdersModule {
549
628
  get(orderNumber: string): Promise<OrderDetail>;
550
629
  /** Cancel a PENDING order (requires auth) */
551
630
  cancel(orderNumber: string): Promise<OrderDetail>;
552
- /** Track order by tracking token (no auth required) */
631
+ /** Track order by tracking token (no customer login required, only API key) */
553
632
  track(trackingToken: string): Promise<OrderDetail>;
554
633
  }
555
634
  declare class CustomerModule {
@@ -583,4 +662,4 @@ declare class PagesModule {
583
662
  get(slug: string, locale?: string): Promise<PageDetail>;
584
663
  }
585
664
 
586
- export { type AddToCartInput, type AddressType, AddressTypes, type AuthTokens, BehioApiError, type BehioErrorCode, type BehioEventHandler, type BehioEventType, BehioNetworkError, BehioStorefront, type BehioStorefrontConfig, type Cart, type CartDiscount, type CartItem, type CartItemProduct, type Category, type CategoryDetail, type CheckoutAddress, type CheckoutInput, type CustomerAddress, type CustomerProfile, type DataGroupFieldType, type FilterField, type FulfillmentStatus, FulfillmentStatuses, type LoginInput, type MessageResponse, type OrderDetail, type OrderItem, type OrderListItem, type OrderStatus, type OrderStatusHistory, OrderStatuses, type Page, type PageDetail, type PaginatedResponse, type PaymentStatus, PaymentStatuses, type ProductDetail, type ProductLabel, type ProductListItem, type ProductPrice, ProductSort, type ProductSortValue, type ProductVariant, type ProductVolumePrice, type ProductsQuery, type RegisterInput, type RequestInterceptor, type RequestInterceptorConfig, type ResponseInterceptor, type ResponseInterceptorData, type ShopInfo };
665
+ export { type ActivePromotion, type AddToCartInput, type AddressType, AddressTypes, type AuthTokens, BehioApiError, type BehioErrorCode, type BehioEventHandler, type BehioEventType, BehioNetworkError, BehioStorefront, type BehioStorefrontConfig, type Bundle, type BundleItem, type Cart, type CartDiscount, type CartItem, type CartItemProduct, type Category, type CategoryDetail, type CheckoutAddress, type CheckoutInput, type CrossSellItem, type CustomerAddress, type CustomerProfile, type DataGroupFieldType, type FilterField, type FulfillmentStatus, FulfillmentStatuses, type LoginInput, type MessageResponse, type OrderDetail, type OrderItem, type OrderListItem, type OrderStatus, type OrderStatusHistory, OrderStatuses, type Page, type PageDetail, type PaginatedResponse, type PaymentStatus, PaymentStatuses, type ProductDetail, type ProductLabel, type ProductListItem, type ProductPrice, ProductSort, type ProductSortValue, type ProductVariant, type ProductVolumePrice, type ProductsQuery, type RegisterInput, type RequestInterceptor, type RequestInterceptorConfig, type ResponseInterceptor, type ResponseInterceptorData, type ShopInfo, type ShopSeo };
package/dist/index.d.ts CHANGED
@@ -41,6 +41,15 @@ interface ShopInfo {
41
41
  metaDescription?: string;
42
42
  allowGuestCheckout: boolean;
43
43
  }
44
+ interface ShopSeo {
45
+ locale: string;
46
+ title: string | null;
47
+ description: string | null;
48
+ keywords: string | null;
49
+ ogTitle: string | null;
50
+ ogDescription: string | null;
51
+ ogImage: string | null;
52
+ }
44
53
  interface ProductPrice {
45
54
  amount: number;
46
55
  currency: string;
@@ -381,6 +390,52 @@ interface ResponseInterceptorData {
381
390
  interface ResponseInterceptor {
382
391
  (response: ResponseInterceptorData): void | Promise<void>;
383
392
  }
393
+ interface BundleItem {
394
+ productId: string;
395
+ slug: string | null;
396
+ name: string;
397
+ sku: string;
398
+ quantity: number;
399
+ imageUrl: string | null;
400
+ defaultPrice: number | null;
401
+ }
402
+ interface Bundle {
403
+ id: string;
404
+ slug: string;
405
+ name: string;
406
+ description: string | null;
407
+ bundlePrice: number;
408
+ currency: string;
409
+ coverImage: string | null;
410
+ endsAt: number | null;
411
+ itemsSum: number;
412
+ savings: number;
413
+ savingsPercent: number;
414
+ items: BundleItem[];
415
+ }
416
+ interface CrossSellItem {
417
+ productId: string;
418
+ slug: string | null;
419
+ name: string;
420
+ sku: string;
421
+ price: number | null;
422
+ imageUrl: string | null;
423
+ stockCached: number;
424
+ }
425
+ interface ActivePromotion {
426
+ id: string;
427
+ name: string;
428
+ slug: string;
429
+ type: string;
430
+ discountType: string;
431
+ discountValue: number;
432
+ startsAt: number;
433
+ endsAt: number | null;
434
+ badgeText: string | null;
435
+ badgeColor: string | null;
436
+ showCountdown: boolean;
437
+ couponRequired: boolean;
438
+ }
384
439
 
385
440
  declare class BehioStorefront {
386
441
  private baseUrl;
@@ -411,6 +466,8 @@ declare class BehioStorefront {
411
466
  readonly pages: PagesModule;
412
467
  /** Get basic shop info */
413
468
  getShopInfo(): Promise<ShopInfo>;
469
+ /** Get SEO metadata for the shop homepage in the given locale (defaults to shop default). */
470
+ getShopSeo(locale?: string): Promise<ShopSeo>;
414
471
  /** Set auth tokens (e.g. from localStorage) */
415
472
  setTokens(tokens: {
416
473
  accessToken: string;
@@ -488,6 +545,22 @@ declare class CatalogModule {
488
545
  page?: number;
489
546
  limit?: number;
490
547
  }): Promise<PaginatedResponse<ProductListItem>>;
548
+ /** List all active bundles */
549
+ getBundles(): Promise<{
550
+ items: Bundle[];
551
+ }>;
552
+ /** Get a single bundle by slug */
553
+ getBundle(slug: string): Promise<Bundle>;
554
+ /** Cross-sell / related / upsell products for a product */
555
+ getCrossSell(productSlug: string): Promise<{
556
+ related: CrossSellItem[];
557
+ upsell: CrossSellItem[];
558
+ crossSell: CrossSellItem[];
559
+ }>;
560
+ /** Active promotions applicable to a product (with countdown end time) */
561
+ getProductPromotions(productSlug: string): Promise<{
562
+ items: ActivePromotion[];
563
+ }>;
491
564
  }
492
565
  declare class AuthModule {
493
566
  private client;
@@ -524,6 +597,12 @@ declare class CartModule {
524
597
  removeItem(itemId: string): Promise<Cart>;
525
598
  /** Clear entire cart */
526
599
  clear(): Promise<void>;
600
+ /** Add a bundle to the cart (price is locked at the bundle's current price) */
601
+ addBundle(bundleId: string, quantity?: number): Promise<Cart>;
602
+ /** Update quantity of a bundle already in the cart */
603
+ updateBundleQuantity(bundleId: string, quantity: number): Promise<Cart>;
604
+ /** Remove a bundle from the cart */
605
+ removeBundle(bundleId: string): Promise<Cart>;
527
606
  /** Merge anonymous cart into authenticated customer cart */
528
607
  merge(): Promise<Cart>;
529
608
  /** Apply discount code */
@@ -549,7 +628,7 @@ declare class OrdersModule {
549
628
  get(orderNumber: string): Promise<OrderDetail>;
550
629
  /** Cancel a PENDING order (requires auth) */
551
630
  cancel(orderNumber: string): Promise<OrderDetail>;
552
- /** Track order by tracking token (no auth required) */
631
+ /** Track order by tracking token (no customer login required, only API key) */
553
632
  track(trackingToken: string): Promise<OrderDetail>;
554
633
  }
555
634
  declare class CustomerModule {
@@ -583,4 +662,4 @@ declare class PagesModule {
583
662
  get(slug: string, locale?: string): Promise<PageDetail>;
584
663
  }
585
664
 
586
- export { type AddToCartInput, type AddressType, AddressTypes, type AuthTokens, BehioApiError, type BehioErrorCode, type BehioEventHandler, type BehioEventType, BehioNetworkError, BehioStorefront, type BehioStorefrontConfig, type Cart, type CartDiscount, type CartItem, type CartItemProduct, type Category, type CategoryDetail, type CheckoutAddress, type CheckoutInput, type CustomerAddress, type CustomerProfile, type DataGroupFieldType, type FilterField, type FulfillmentStatus, FulfillmentStatuses, type LoginInput, type MessageResponse, type OrderDetail, type OrderItem, type OrderListItem, type OrderStatus, type OrderStatusHistory, OrderStatuses, type Page, type PageDetail, type PaginatedResponse, type PaymentStatus, PaymentStatuses, type ProductDetail, type ProductLabel, type ProductListItem, type ProductPrice, ProductSort, type ProductSortValue, type ProductVariant, type ProductVolumePrice, type ProductsQuery, type RegisterInput, type RequestInterceptor, type RequestInterceptorConfig, type ResponseInterceptor, type ResponseInterceptorData, type ShopInfo };
665
+ export { type ActivePromotion, type AddToCartInput, type AddressType, AddressTypes, type AuthTokens, BehioApiError, type BehioErrorCode, type BehioEventHandler, type BehioEventType, BehioNetworkError, BehioStorefront, type BehioStorefrontConfig, type Bundle, type BundleItem, type Cart, type CartDiscount, type CartItem, type CartItemProduct, type Category, type CategoryDetail, type CheckoutAddress, type CheckoutInput, type CrossSellItem, type CustomerAddress, type CustomerProfile, type DataGroupFieldType, type FilterField, type FulfillmentStatus, FulfillmentStatuses, type LoginInput, type MessageResponse, type OrderDetail, type OrderItem, type OrderListItem, type OrderStatus, type OrderStatusHistory, OrderStatuses, type Page, type PageDetail, type PaginatedResponse, type PaymentStatus, PaymentStatuses, type ProductDetail, type ProductLabel, type ProductListItem, type ProductPrice, ProductSort, type ProductSortValue, type ProductVariant, type ProductVolumePrice, type ProductsQuery, type RegisterInput, type RequestInterceptor, type RequestInterceptorConfig, type ResponseInterceptor, type ResponseInterceptorData, type ShopInfo, type ShopSeo };
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
 
10
- var _chunkGGAO5T5Pjs = require('./chunk-GGAO5T5P.js');
10
+ var _chunkQOEYSUF2js = require('./chunk-QOEYSUF2.js');
11
11
 
12
12
 
13
13
 
@@ -17,4 +17,4 @@ var _chunkGGAO5T5Pjs = require('./chunk-GGAO5T5P.js');
17
17
 
18
18
 
19
19
 
20
- exports.AddressTypes = _chunkGGAO5T5Pjs.AddressTypes; exports.BehioApiError = _chunkGGAO5T5Pjs.BehioApiError; exports.BehioNetworkError = _chunkGGAO5T5Pjs.BehioNetworkError; exports.BehioStorefront = _chunkGGAO5T5Pjs.BehioStorefront; exports.FulfillmentStatuses = _chunkGGAO5T5Pjs.FulfillmentStatuses; exports.OrderStatuses = _chunkGGAO5T5Pjs.OrderStatuses; exports.PaymentStatuses = _chunkGGAO5T5Pjs.PaymentStatuses; exports.ProductSort = _chunkGGAO5T5Pjs.ProductSort;
20
+ exports.AddressTypes = _chunkQOEYSUF2js.AddressTypes; exports.BehioApiError = _chunkQOEYSUF2js.BehioApiError; exports.BehioNetworkError = _chunkQOEYSUF2js.BehioNetworkError; exports.BehioStorefront = _chunkQOEYSUF2js.BehioStorefront; exports.FulfillmentStatuses = _chunkQOEYSUF2js.FulfillmentStatuses; exports.OrderStatuses = _chunkQOEYSUF2js.OrderStatuses; exports.PaymentStatuses = _chunkQOEYSUF2js.PaymentStatuses; exports.ProductSort = _chunkQOEYSUF2js.ProductSort;
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  OrderStatuses,
8
8
  PaymentStatuses,
9
9
  ProductSort
10
- } from "./chunk-S4DOL3OV.mjs";
10
+ } from "./chunk-HYKJO2IB.mjs";
11
11
  export {
12
12
  AddressTypes,
13
13
  BehioApiError,
package/dist/react.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _tanstack_react_query from '@tanstack/react-query';
3
3
  import { QueryClient } from '@tanstack/react-query';
4
- import { BehioStorefront, ProductsQuery, PaginatedResponse, ProductListItem, ProductDetail, Category, CategoryDetail, ProductLabel, FilterField, Cart, CustomerProfile, RegisterInput, CustomerAddress, OrderListItem, OrderDetail, CheckoutInput, PageDetail, Page, ShopInfo } from './index.mjs';
5
- export { AddToCartInput, AuthTokens, BehioApiError, CartDiscount, CartItem, CheckoutAddress, FulfillmentStatus, LoginInput, MessageResponse, OrderItem, OrderStatus, PaymentStatus, ProductPrice, ProductVariant } from './index.mjs';
4
+ import { BehioStorefront, ProductsQuery, PaginatedResponse, ProductListItem, ProductDetail, Category, CategoryDetail, ProductLabel, FilterField, Cart, CustomerProfile, RegisterInput, CustomerAddress, OrderListItem, OrderDetail, CheckoutInput, PageDetail, Page, ShopInfo, ShopSeo, Bundle, CrossSellItem, ActivePromotion } from './index.mjs';
5
+ export { AddToCartInput, AuthTokens, BehioApiError, BundleItem, CartDiscount, CartItem, CheckoutAddress, FulfillmentStatus, LoginInput, MessageResponse, OrderItem, OrderStatus, PaymentStatus, ProductPrice, ProductVariant } from './index.mjs';
6
6
  import * as _tanstack_query_core from '@tanstack/query-core';
7
7
 
8
8
  interface StorageAdapter {
@@ -265,6 +265,62 @@ interface UseShopInfoOptions {
265
265
  }
266
266
  declare function useShopInfo(options?: UseShopInfoOptions): _tanstack_react_query.UseQueryResult<ShopInfo, Error>;
267
267
 
268
+ interface UseShopSeoOptions {
269
+ /** Override locale (ISO-639-1). Defaults to the shop's default locale. */
270
+ locale?: string;
271
+ /** Hydrate from SSR-fetched data (use `client.getShopSeo(locale)` on the server). */
272
+ initialData?: ShopSeo;
273
+ /** Disable the query. */
274
+ enabled?: boolean;
275
+ }
276
+ /**
277
+ * React Query hook for per-locale shop SEO metadata. Safe to render on the
278
+ * server via `initialData` from `client.getShopSeo(locale)`.
279
+ */
280
+ declare function useShopSeo(options?: UseShopSeoOptions): _tanstack_react_query.UseQueryResult<ShopSeo, Error>;
281
+
282
+ /** List all active bundles. */
283
+ declare function useBundles(options?: {
284
+ enabled?: boolean;
285
+ initialData?: {
286
+ items: Bundle[];
287
+ };
288
+ }): _tanstack_react_query.UseQueryResult<{
289
+ items: Bundle[];
290
+ }, Error>;
291
+ /** Get a single bundle by slug. */
292
+ declare function useBundle(slug: string | undefined, options?: {
293
+ enabled?: boolean;
294
+ initialData?: Bundle;
295
+ }): _tanstack_react_query.UseQueryResult<Bundle, Error>;
296
+
297
+ type CrossSellResponse = {
298
+ related: CrossSellItem[];
299
+ upsell: CrossSellItem[];
300
+ crossSell: CrossSellItem[];
301
+ };
302
+ /**
303
+ * Fetch related / upsell / cross-sell products for a given product.
304
+ * Returns all three lists separately so the UI can group them into
305
+ * different sections on the product detail page.
306
+ */
307
+ declare function useCrossSell(productSlug: string | undefined, options?: {
308
+ enabled?: boolean;
309
+ initialData?: CrossSellResponse;
310
+ }): _tanstack_react_query.UseQueryResult<CrossSellResponse, Error>;
311
+
312
+ /**
313
+ * Fetch currently active promotions applicable to a specific product.
314
+ * Use this on product detail pages to render countdown timers and
315
+ * "AKCE -20%" badges.
316
+ */
317
+ declare function useProductPromotions(productSlug: string | undefined, options?: {
318
+ enabled?: boolean;
319
+ refetchIntervalMs?: number;
320
+ }): _tanstack_react_query.UseQueryResult<{
321
+ items: ActivePromotion[];
322
+ }, Error>;
323
+
268
324
  /**
269
325
  * Returns the raw BehioStorefront client instance.
270
326
  *
@@ -283,4 +339,4 @@ declare function useBehioClient(): BehioStorefront;
283
339
  */
284
340
  declare function formatPrice(amount: number, currency: string, locale?: string): string;
285
341
 
286
- export { BehioProvider, type BehioProviderProps, Cart, Category, CategoryDetail, CheckoutInput, CustomerAddress, CustomerProfile, FilterField, OrderDetail, OrderListItem, Page, PageDetail, PaginatedResponse, ProductDetail, ProductLabel, ProductListItem, ProductsQuery, RegisterInput, ShopInfo, type StorageAdapter, type UseAddressesOptions, type UseCartCountOptions, type UseCartOptions, type UseCategoriesOptions, type UseCategoryOptions, type UseCustomerOptions, type UseFeaturedOptions, type UseFiltersOptions, type UseLabelsOptions, type UseOrderOptions, type UseOrdersOptions, type UsePageOptions, type UsePagesOptions, type UseProductOptions, type UseProductsOptions, type UseSearchOptions, type UseShopInfoOptions, cookieStorage, createMemoryStorage, detectStorage, formatPrice, localStorageAdapter, memoryStorage, useAddresses, useAuth, useBehio, useBehioClient, useCart, useCartCount, useCategories, useCategory, useCheckout, useCustomer, useFeatured, useFilters, useLabels, useOrder, useOrders, usePage, usePages, useProduct, useProducts, useSearch, useShopInfo };
342
+ export { ActivePromotion, BehioProvider, type BehioProviderProps, Bundle, Cart, Category, CategoryDetail, CheckoutInput, CrossSellItem, CustomerAddress, CustomerProfile, FilterField, OrderDetail, OrderListItem, Page, PageDetail, PaginatedResponse, ProductDetail, ProductLabel, ProductListItem, ProductsQuery, RegisterInput, ShopInfo, ShopSeo, type StorageAdapter, type UseAddressesOptions, type UseCartCountOptions, type UseCartOptions, type UseCategoriesOptions, type UseCategoryOptions, type UseCustomerOptions, type UseFeaturedOptions, type UseFiltersOptions, type UseLabelsOptions, type UseOrderOptions, type UseOrdersOptions, type UsePageOptions, type UsePagesOptions, type UseProductOptions, type UseProductsOptions, type UseSearchOptions, type UseShopInfoOptions, type UseShopSeoOptions, cookieStorage, createMemoryStorage, detectStorage, formatPrice, localStorageAdapter, memoryStorage, useAddresses, useAuth, useBehio, useBehioClient, useBundle, useBundles, useCart, useCartCount, useCategories, useCategory, useCheckout, useCrossSell, useCustomer, useFeatured, useFilters, useLabels, useOrder, useOrders, usePage, usePages, useProduct, useProductPromotions, useProducts, useSearch, useShopInfo, useShopSeo };
package/dist/react.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _tanstack_react_query from '@tanstack/react-query';
3
3
  import { QueryClient } from '@tanstack/react-query';
4
- import { BehioStorefront, ProductsQuery, PaginatedResponse, ProductListItem, ProductDetail, Category, CategoryDetail, ProductLabel, FilterField, Cart, CustomerProfile, RegisterInput, CustomerAddress, OrderListItem, OrderDetail, CheckoutInput, PageDetail, Page, ShopInfo } from './index.js';
5
- export { AddToCartInput, AuthTokens, BehioApiError, CartDiscount, CartItem, CheckoutAddress, FulfillmentStatus, LoginInput, MessageResponse, OrderItem, OrderStatus, PaymentStatus, ProductPrice, ProductVariant } from './index.js';
4
+ import { BehioStorefront, ProductsQuery, PaginatedResponse, ProductListItem, ProductDetail, Category, CategoryDetail, ProductLabel, FilterField, Cart, CustomerProfile, RegisterInput, CustomerAddress, OrderListItem, OrderDetail, CheckoutInput, PageDetail, Page, ShopInfo, ShopSeo, Bundle, CrossSellItem, ActivePromotion } from './index.js';
5
+ export { AddToCartInput, AuthTokens, BehioApiError, BundleItem, CartDiscount, CartItem, CheckoutAddress, FulfillmentStatus, LoginInput, MessageResponse, OrderItem, OrderStatus, PaymentStatus, ProductPrice, ProductVariant } from './index.js';
6
6
  import * as _tanstack_query_core from '@tanstack/query-core';
7
7
 
8
8
  interface StorageAdapter {
@@ -265,6 +265,62 @@ interface UseShopInfoOptions {
265
265
  }
266
266
  declare function useShopInfo(options?: UseShopInfoOptions): _tanstack_react_query.UseQueryResult<ShopInfo, Error>;
267
267
 
268
+ interface UseShopSeoOptions {
269
+ /** Override locale (ISO-639-1). Defaults to the shop's default locale. */
270
+ locale?: string;
271
+ /** Hydrate from SSR-fetched data (use `client.getShopSeo(locale)` on the server). */
272
+ initialData?: ShopSeo;
273
+ /** Disable the query. */
274
+ enabled?: boolean;
275
+ }
276
+ /**
277
+ * React Query hook for per-locale shop SEO metadata. Safe to render on the
278
+ * server via `initialData` from `client.getShopSeo(locale)`.
279
+ */
280
+ declare function useShopSeo(options?: UseShopSeoOptions): _tanstack_react_query.UseQueryResult<ShopSeo, Error>;
281
+
282
+ /** List all active bundles. */
283
+ declare function useBundles(options?: {
284
+ enabled?: boolean;
285
+ initialData?: {
286
+ items: Bundle[];
287
+ };
288
+ }): _tanstack_react_query.UseQueryResult<{
289
+ items: Bundle[];
290
+ }, Error>;
291
+ /** Get a single bundle by slug. */
292
+ declare function useBundle(slug: string | undefined, options?: {
293
+ enabled?: boolean;
294
+ initialData?: Bundle;
295
+ }): _tanstack_react_query.UseQueryResult<Bundle, Error>;
296
+
297
+ type CrossSellResponse = {
298
+ related: CrossSellItem[];
299
+ upsell: CrossSellItem[];
300
+ crossSell: CrossSellItem[];
301
+ };
302
+ /**
303
+ * Fetch related / upsell / cross-sell products for a given product.
304
+ * Returns all three lists separately so the UI can group them into
305
+ * different sections on the product detail page.
306
+ */
307
+ declare function useCrossSell(productSlug: string | undefined, options?: {
308
+ enabled?: boolean;
309
+ initialData?: CrossSellResponse;
310
+ }): _tanstack_react_query.UseQueryResult<CrossSellResponse, Error>;
311
+
312
+ /**
313
+ * Fetch currently active promotions applicable to a specific product.
314
+ * Use this on product detail pages to render countdown timers and
315
+ * "AKCE -20%" badges.
316
+ */
317
+ declare function useProductPromotions(productSlug: string | undefined, options?: {
318
+ enabled?: boolean;
319
+ refetchIntervalMs?: number;
320
+ }): _tanstack_react_query.UseQueryResult<{
321
+ items: ActivePromotion[];
322
+ }, Error>;
323
+
268
324
  /**
269
325
  * Returns the raw BehioStorefront client instance.
270
326
  *
@@ -283,4 +339,4 @@ declare function useBehioClient(): BehioStorefront;
283
339
  */
284
340
  declare function formatPrice(amount: number, currency: string, locale?: string): string;
285
341
 
286
- export { BehioProvider, type BehioProviderProps, Cart, Category, CategoryDetail, CheckoutInput, CustomerAddress, CustomerProfile, FilterField, OrderDetail, OrderListItem, Page, PageDetail, PaginatedResponse, ProductDetail, ProductLabel, ProductListItem, ProductsQuery, RegisterInput, ShopInfo, type StorageAdapter, type UseAddressesOptions, type UseCartCountOptions, type UseCartOptions, type UseCategoriesOptions, type UseCategoryOptions, type UseCustomerOptions, type UseFeaturedOptions, type UseFiltersOptions, type UseLabelsOptions, type UseOrderOptions, type UseOrdersOptions, type UsePageOptions, type UsePagesOptions, type UseProductOptions, type UseProductsOptions, type UseSearchOptions, type UseShopInfoOptions, cookieStorage, createMemoryStorage, detectStorage, formatPrice, localStorageAdapter, memoryStorage, useAddresses, useAuth, useBehio, useBehioClient, useCart, useCartCount, useCategories, useCategory, useCheckout, useCustomer, useFeatured, useFilters, useLabels, useOrder, useOrders, usePage, usePages, useProduct, useProducts, useSearch, useShopInfo };
342
+ export { ActivePromotion, BehioProvider, type BehioProviderProps, Bundle, Cart, Category, CategoryDetail, CheckoutInput, CrossSellItem, CustomerAddress, CustomerProfile, FilterField, OrderDetail, OrderListItem, Page, PageDetail, PaginatedResponse, ProductDetail, ProductLabel, ProductListItem, ProductsQuery, RegisterInput, ShopInfo, ShopSeo, type StorageAdapter, type UseAddressesOptions, type UseCartCountOptions, type UseCartOptions, type UseCategoriesOptions, type UseCategoryOptions, type UseCustomerOptions, type UseFeaturedOptions, type UseFiltersOptions, type UseLabelsOptions, type UseOrderOptions, type UseOrdersOptions, type UsePageOptions, type UsePagesOptions, type UseProductOptions, type UseProductsOptions, type UseSearchOptions, type UseShopInfoOptions, type UseShopSeoOptions, cookieStorage, createMemoryStorage, detectStorage, formatPrice, localStorageAdapter, memoryStorage, useAddresses, useAuth, useBehio, useBehioClient, useBundle, useBundles, useCart, useCartCount, useCategories, useCategory, useCheckout, useCrossSell, useCustomer, useFeatured, useFilters, useLabels, useOrder, useOrders, usePage, usePages, useProduct, useProductPromotions, useProducts, useSearch, useShopInfo, useShopSeo };
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkGGAO5T5Pjs = require('./chunk-GGAO5T5P.js');
3
+ var _chunkQOEYSUF2js = require('./chunk-QOEYSUF2.js');
4
4
 
5
5
  // src/react/provider.tsx
6
6
  var _react = require('react');
@@ -114,7 +114,7 @@ function BehioProvider({
114
114
  const storageAdapter = _react.useMemo.call(void 0, () => resolveStorage(storageOption), [storageOption]);
115
115
  const clientRef = _react.useRef.call(void 0, null);
116
116
  if (!clientRef.current) {
117
- clientRef.current = new (0, _chunkGGAO5T5Pjs.BehioStorefront)({
117
+ clientRef.current = new (0, _chunkQOEYSUF2js.BehioStorefront)({
118
118
  apiKey,
119
119
  baseUrl,
120
120
  locale,
@@ -872,6 +872,64 @@ function useShopInfo(options) {
872
872
  });
873
873
  }
874
874
 
875
+ // src/react/hooks/use-shop-seo.ts
876
+
877
+ function useShopSeo(options) {
878
+ const { client } = useBehio();
879
+ const { locale, initialData, enabled = true } = _nullishCoalesce(options, () => ( {}));
880
+ return _reactquery.useQuery.call(void 0, {
881
+ queryKey: ["behio", "shop-seo", _nullishCoalesce(locale, () => ( "_default"))],
882
+ queryFn: () => client.getShopSeo(locale),
883
+ initialData,
884
+ enabled
885
+ });
886
+ }
887
+
888
+ // src/react/hooks/use-bundles.ts
889
+
890
+ function useBundles(options) {
891
+ const { client } = useBehio();
892
+ return _reactquery.useQuery.call(void 0, {
893
+ queryKey: ["behio", "bundles"],
894
+ queryFn: () => client.catalog.getBundles(),
895
+ enabled: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _60 => _60.enabled]), () => ( true)),
896
+ initialData: _optionalChain([options, 'optionalAccess', _61 => _61.initialData])
897
+ });
898
+ }
899
+ function useBundle(slug, options) {
900
+ const { client } = useBehio();
901
+ return _reactquery.useQuery.call(void 0, {
902
+ queryKey: ["behio", "bundle", slug],
903
+ queryFn: () => client.catalog.getBundle(slug),
904
+ enabled: Boolean(slug) && (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _62 => _62.enabled]), () => ( true))),
905
+ initialData: _optionalChain([options, 'optionalAccess', _63 => _63.initialData])
906
+ });
907
+ }
908
+
909
+ // src/react/hooks/use-cross-sell.ts
910
+
911
+ function useCrossSell(productSlug, options) {
912
+ const { client } = useBehio();
913
+ return _reactquery.useQuery.call(void 0, {
914
+ queryKey: ["behio", "cross-sell", productSlug],
915
+ queryFn: () => client.catalog.getCrossSell(productSlug),
916
+ enabled: Boolean(productSlug) && (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _64 => _64.enabled]), () => ( true))),
917
+ initialData: _optionalChain([options, 'optionalAccess', _65 => _65.initialData])
918
+ });
919
+ }
920
+
921
+ // src/react/hooks/use-product-promotions.ts
922
+
923
+ function useProductPromotions(productSlug, options) {
924
+ const { client } = useBehio();
925
+ return _reactquery.useQuery.call(void 0, {
926
+ queryKey: ["behio", "product-promotions", productSlug],
927
+ queryFn: () => client.catalog.getProductPromotions(productSlug),
928
+ enabled: Boolean(productSlug) && (_nullishCoalesce(_optionalChain([options, 'optionalAccess', _66 => _66.enabled]), () => ( true))),
929
+ refetchInterval: _optionalChain([options, 'optionalAccess', _67 => _67.refetchIntervalMs])
930
+ });
931
+ }
932
+
875
933
  // src/react/hooks/use-behio-client.ts
876
934
  function useBehioClient() {
877
935
  return useBehio().client;
@@ -920,4 +978,9 @@ function formatPrice(amount, currency, locale) {
920
978
 
921
979
 
922
980
 
923
- exports.BehioProvider = BehioProvider; exports.cookieStorage = cookieStorage; exports.createMemoryStorage = createMemoryStorage; exports.detectStorage = detectStorage; exports.formatPrice = formatPrice; exports.localStorageAdapter = localStorageAdapter; exports.memoryStorage = memoryStorage; exports.useAddresses = useAddresses; exports.useAuth = useAuth; exports.useBehio = useBehio; exports.useBehioClient = useBehioClient; exports.useCart = useCart; exports.useCartCount = useCartCount; exports.useCategories = useCategories; exports.useCategory = useCategory; exports.useCheckout = useCheckout; exports.useCustomer = useCustomer; exports.useFeatured = useFeatured; exports.useFilters = useFilters; exports.useLabels = useLabels; exports.useOrder = useOrder; exports.useOrders = useOrders; exports.usePage = usePage; exports.usePages = usePages; exports.useProduct = useProduct; exports.useProducts = useProducts; exports.useSearch = useSearch; exports.useShopInfo = useShopInfo;
981
+
982
+
983
+
984
+
985
+
986
+ exports.BehioProvider = BehioProvider; exports.cookieStorage = cookieStorage; exports.createMemoryStorage = createMemoryStorage; exports.detectStorage = detectStorage; exports.formatPrice = formatPrice; exports.localStorageAdapter = localStorageAdapter; exports.memoryStorage = memoryStorage; exports.useAddresses = useAddresses; exports.useAuth = useAuth; exports.useBehio = useBehio; exports.useBehioClient = useBehioClient; exports.useBundle = useBundle; exports.useBundles = useBundles; exports.useCart = useCart; exports.useCartCount = useCartCount; exports.useCategories = useCategories; exports.useCategory = useCategory; exports.useCheckout = useCheckout; exports.useCrossSell = useCrossSell; exports.useCustomer = useCustomer; exports.useFeatured = useFeatured; exports.useFilters = useFilters; exports.useLabels = useLabels; exports.useOrder = useOrder; exports.useOrders = useOrders; exports.usePage = usePage; exports.usePages = usePages; exports.useProduct = useProduct; exports.useProductPromotions = useProductPromotions; exports.useProducts = useProducts; exports.useSearch = useSearch; exports.useShopInfo = useShopInfo; exports.useShopSeo = useShopSeo;
package/dist/react.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BehioStorefront
3
- } from "./chunk-S4DOL3OV.mjs";
3
+ } from "./chunk-HYKJO2IB.mjs";
4
4
 
5
5
  // src/react/provider.tsx
6
6
  import { useRef, useEffect, useMemo } from "react";
@@ -872,6 +872,64 @@ function useShopInfo(options) {
872
872
  });
873
873
  }
874
874
 
875
+ // src/react/hooks/use-shop-seo.ts
876
+ import { useQuery as useQuery15 } from "@tanstack/react-query";
877
+ function useShopSeo(options) {
878
+ const { client } = useBehio();
879
+ const { locale, initialData, enabled = true } = options ?? {};
880
+ return useQuery15({
881
+ queryKey: ["behio", "shop-seo", locale ?? "_default"],
882
+ queryFn: () => client.getShopSeo(locale),
883
+ initialData,
884
+ enabled
885
+ });
886
+ }
887
+
888
+ // src/react/hooks/use-bundles.ts
889
+ import { useQuery as useQuery16 } from "@tanstack/react-query";
890
+ function useBundles(options) {
891
+ const { client } = useBehio();
892
+ return useQuery16({
893
+ queryKey: ["behio", "bundles"],
894
+ queryFn: () => client.catalog.getBundles(),
895
+ enabled: options?.enabled ?? true,
896
+ initialData: options?.initialData
897
+ });
898
+ }
899
+ function useBundle(slug, options) {
900
+ const { client } = useBehio();
901
+ return useQuery16({
902
+ queryKey: ["behio", "bundle", slug],
903
+ queryFn: () => client.catalog.getBundle(slug),
904
+ enabled: Boolean(slug) && (options?.enabled ?? true),
905
+ initialData: options?.initialData
906
+ });
907
+ }
908
+
909
+ // src/react/hooks/use-cross-sell.ts
910
+ import { useQuery as useQuery17 } from "@tanstack/react-query";
911
+ function useCrossSell(productSlug, options) {
912
+ const { client } = useBehio();
913
+ return useQuery17({
914
+ queryKey: ["behio", "cross-sell", productSlug],
915
+ queryFn: () => client.catalog.getCrossSell(productSlug),
916
+ enabled: Boolean(productSlug) && (options?.enabled ?? true),
917
+ initialData: options?.initialData
918
+ });
919
+ }
920
+
921
+ // src/react/hooks/use-product-promotions.ts
922
+ import { useQuery as useQuery18 } from "@tanstack/react-query";
923
+ function useProductPromotions(productSlug, options) {
924
+ const { client } = useBehio();
925
+ return useQuery18({
926
+ queryKey: ["behio", "product-promotions", productSlug],
927
+ queryFn: () => client.catalog.getProductPromotions(productSlug),
928
+ enabled: Boolean(productSlug) && (options?.enabled ?? true),
929
+ refetchInterval: options?.refetchIntervalMs
930
+ });
931
+ }
932
+
875
933
  // src/react/hooks/use-behio-client.ts
876
934
  function useBehioClient() {
877
935
  return useBehio().client;
@@ -903,11 +961,14 @@ export {
903
961
  useAuth,
904
962
  useBehio,
905
963
  useBehioClient,
964
+ useBundle,
965
+ useBundles,
906
966
  useCart,
907
967
  useCartCount,
908
968
  useCategories,
909
969
  useCategory,
910
970
  useCheckout,
971
+ useCrossSell,
911
972
  useCustomer,
912
973
  useFeatured,
913
974
  useFilters,
@@ -917,7 +978,9 @@ export {
917
978
  usePage,
918
979
  usePages,
919
980
  useProduct,
981
+ useProductPromotions,
920
982
  useProducts,
921
983
  useSearch,
922
- useShopInfo
984
+ useShopInfo,
985
+ useShopSeo
923
986
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@behio/storefront-sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "TypeScript SDK for Behio Headless E-Shop — core client + React hooks",
5
5
  "author": "Behio",
6
6
  "license": "MIT",