@behio/storefront-sdk 0.21.0 → 0.22.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.
@@ -0,0 +1,36 @@
1
+ // src/react/utils/format-price.ts
2
+ function formatPrice(amount, currency, locale) {
3
+ const resolvedLocale = locale ?? "cs";
4
+ try {
5
+ return new Intl.NumberFormat(resolvedLocale, {
6
+ style: "currency",
7
+ currency,
8
+ minimumFractionDigits: Number.isInteger(amount) ? 0 : 2,
9
+ maximumFractionDigits: 2
10
+ }).format(amount);
11
+ } catch {
12
+ return `${amount} ${currency}`;
13
+ }
14
+ }
15
+
16
+ // src/analytics.ts
17
+ function trackEcommerceEvent(event, payload) {
18
+ if (typeof window === "undefined") return;
19
+ const w = window;
20
+ try {
21
+ if (typeof w.gtag === "function") {
22
+ w.gtag("event", event, payload);
23
+ return;
24
+ }
25
+ if (Array.isArray(w.dataLayer)) {
26
+ w.dataLayer.push({ ecommerce: null });
27
+ w.dataLayer.push({ event, ecommerce: payload });
28
+ }
29
+ } catch {
30
+ }
31
+ }
32
+
33
+ export {
34
+ formatPrice,
35
+ trackEcommerceEvent
36
+ };
@@ -13,6 +13,24 @@ function formatPrice(amount, currency, locale) {
13
13
  }
14
14
  }
15
15
 
16
+ // src/analytics.ts
17
+ function trackEcommerceEvent(event, payload) {
18
+ if (typeof window === "undefined") return;
19
+ const w = window;
20
+ try {
21
+ if (typeof w.gtag === "function") {
22
+ w.gtag("event", event, payload);
23
+ return;
24
+ }
25
+ if (Array.isArray(w.dataLayer)) {
26
+ w.dataLayer.push({ ecommerce: null });
27
+ w.dataLayer.push({ event, ecommerce: payload });
28
+ }
29
+ } catch (e2) {
30
+ }
31
+ }
32
+
33
+
16
34
 
17
35
 
18
- exports.formatPrice = formatPrice;
36
+ exports.formatPrice = formatPrice; exports.trackEcommerceEvent = trackEcommerceEvent;
package/dist/index.d.mts CHANGED
@@ -10,4 +10,40 @@ export { u as ActivePromotion, K as AddToCartInput, j as AddressDetail, A as Add
10
10
  */
11
11
  declare function formatPrice(amount: number, currency: string, locale?: string): string;
12
12
 
13
- export { formatPrice };
13
+ /**
14
+ * GA4 e-commerce event helper.
15
+ *
16
+ * Fires standard GA4 ecommerce events (view_item, add_to_cart, begin_checkout,
17
+ * purchase, ...) into whatever analytics runtime the shop has injected via
18
+ * `<StorefrontScripts/>`:
19
+ *
20
+ * - direct GA4 (`gtag` present) -> `gtag("event", name, payload)`
21
+ * - GTM (`dataLayer` array present) -> `dataLayer.push({event, ecommerce})`
22
+ * (with the recommended `ecommerce: null` reset push first)
23
+ * - neither present (no analytics configured, or consent not granted yet so
24
+ * the consent-gated script never loaded) -> silent no-op
25
+ *
26
+ * Consent stays the script layer's job: this helper never loads anything, it
27
+ * only talks to runtimes that already exist on the page.
28
+ */
29
+ type EcommerceEventName = "view_item" | "add_to_cart" | "remove_from_cart" | "view_cart" | "begin_checkout" | "add_payment_info" | "add_shipping_info" | "purchase";
30
+ type EcommerceItem = {
31
+ item_id: string;
32
+ item_name: string;
33
+ price?: number;
34
+ quantity?: number;
35
+ item_variant?: string;
36
+ item_category?: string;
37
+ };
38
+ type EcommercePayload = {
39
+ currency?: string;
40
+ /** Order / cart total in `currency`. */
41
+ value?: number;
42
+ /** Required for `purchase` — the order number. */
43
+ transaction_id?: string;
44
+ shipping?: number;
45
+ items: EcommerceItem[];
46
+ };
47
+ declare function trackEcommerceEvent(event: EcommerceEventName, payload: EcommercePayload): void;
48
+
49
+ export { type EcommerceEventName, type EcommerceItem, type EcommercePayload, formatPrice, trackEcommerceEvent };
package/dist/index.d.ts CHANGED
@@ -10,4 +10,40 @@ export { u as ActivePromotion, K as AddToCartInput, j as AddressDetail, A as Add
10
10
  */
11
11
  declare function formatPrice(amount: number, currency: string, locale?: string): string;
12
12
 
13
- export { formatPrice };
13
+ /**
14
+ * GA4 e-commerce event helper.
15
+ *
16
+ * Fires standard GA4 ecommerce events (view_item, add_to_cart, begin_checkout,
17
+ * purchase, ...) into whatever analytics runtime the shop has injected via
18
+ * `<StorefrontScripts/>`:
19
+ *
20
+ * - direct GA4 (`gtag` present) -> `gtag("event", name, payload)`
21
+ * - GTM (`dataLayer` array present) -> `dataLayer.push({event, ecommerce})`
22
+ * (with the recommended `ecommerce: null` reset push first)
23
+ * - neither present (no analytics configured, or consent not granted yet so
24
+ * the consent-gated script never loaded) -> silent no-op
25
+ *
26
+ * Consent stays the script layer's job: this helper never loads anything, it
27
+ * only talks to runtimes that already exist on the page.
28
+ */
29
+ type EcommerceEventName = "view_item" | "add_to_cart" | "remove_from_cart" | "view_cart" | "begin_checkout" | "add_payment_info" | "add_shipping_info" | "purchase";
30
+ type EcommerceItem = {
31
+ item_id: string;
32
+ item_name: string;
33
+ price?: number;
34
+ quantity?: number;
35
+ item_variant?: string;
36
+ item_category?: string;
37
+ };
38
+ type EcommercePayload = {
39
+ currency?: string;
40
+ /** Order / cart total in `currency`. */
41
+ value?: number;
42
+ /** Required for `purchase` — the order number. */
43
+ transaction_id?: string;
44
+ shipping?: number;
45
+ items: EcommerceItem[];
46
+ };
47
+ declare function trackEcommerceEvent(event: EcommerceEventName, payload: EcommercePayload): void;
48
+
49
+ export { type EcommerceEventName, type EcommerceItem, type EcommercePayload, formatPrice, trackEcommerceEvent };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkXWYDXBLGjs = require('./chunk-XWYDXBLG.js');
3
+
4
+ var _chunkBFF5BKR2js = require('./chunk-BFF5BKR2.js');
4
5
 
5
6
 
6
7
 
@@ -27,4 +28,5 @@ var _chunkBF4YVFHXjs = require('./chunk-BF4YVFHX.js');
27
28
 
28
29
 
29
30
 
30
- exports.AddressTypes = _chunkBF4YVFHXjs.AddressTypes; exports.BehioApiError = _chunkBF4YVFHXjs.BehioApiError; exports.BehioNetworkError = _chunkBF4YVFHXjs.BehioNetworkError; exports.BehioStorefront = _chunkBF4YVFHXjs.BehioStorefront; exports.FulfillmentStatuses = _chunkBF4YVFHXjs.FulfillmentStatuses; exports.OrderStatuses = _chunkBF4YVFHXjs.OrderStatuses; exports.PaymentStatuses = _chunkBF4YVFHXjs.PaymentStatuses; exports.ProductSort = _chunkBF4YVFHXjs.ProductSort; exports.err = _chunkBF4YVFHXjs.err; exports.formatPrice = _chunkXWYDXBLGjs.formatPrice; exports.ok = _chunkBF4YVFHXjs.ok; exports.toSdkError = _chunkBF4YVFHXjs.toSdkError;
31
+
32
+ exports.AddressTypes = _chunkBF4YVFHXjs.AddressTypes; exports.BehioApiError = _chunkBF4YVFHXjs.BehioApiError; exports.BehioNetworkError = _chunkBF4YVFHXjs.BehioNetworkError; exports.BehioStorefront = _chunkBF4YVFHXjs.BehioStorefront; exports.FulfillmentStatuses = _chunkBF4YVFHXjs.FulfillmentStatuses; exports.OrderStatuses = _chunkBF4YVFHXjs.OrderStatuses; exports.PaymentStatuses = _chunkBF4YVFHXjs.PaymentStatuses; exports.ProductSort = _chunkBF4YVFHXjs.ProductSort; exports.err = _chunkBF4YVFHXjs.err; exports.formatPrice = _chunkBFF5BKR2js.formatPrice; exports.ok = _chunkBF4YVFHXjs.ok; exports.toSdkError = _chunkBF4YVFHXjs.toSdkError; exports.trackEcommerceEvent = _chunkBFF5BKR2js.trackEcommerceEvent;
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
- formatPrice
3
- } from "./chunk-YJ45WIQZ.mjs";
2
+ formatPrice,
3
+ trackEcommerceEvent
4
+ } from "./chunk-AN3QTDNM.mjs";
4
5
  import {
5
6
  AddressTypes,
6
7
  BehioApiError,
@@ -26,5 +27,6 @@ export {
26
27
  err,
27
28
  formatPrice,
28
29
  ok,
29
- toSdkError
30
+ toSdkError,
31
+ trackEcommerceEvent
30
32
  };
package/dist/react.d.mts CHANGED
@@ -4,7 +4,7 @@ import { QueryClient } from '@tanstack/react-query';
4
4
  import { a as BehioStorefront, P as ProductsQuery, b as PaginatedResponse, c as ProductListItem, d as ProductDetail, C as Category, e as CategoryDetail, f as ProductLabel, F as FilterField, g as Cart, h as CustomerProfile, R as RegisterInput, i as CustomerAddress, A as AddressSuggestion, j as AddressDetail, O as OrderListItem, k as OrderDetail, l as OrderAccessRequestResponse, m as OrderAccessVerifyResponse, n as CheckoutInput, o as PageDetail, p as Page, S as ShopInfo, q as ShopScripts, r as ShopSeo, s as Bundle, t as CrossSellItem, u as ActivePromotion, G as GiftCardBalance, W as WishlistItem, v as ProductReviewsResponse, w as SubmitReviewInput, x as ReturnableOrder, y as ReturnStatus, z as ReturnRequest, D as SubmitReturnInput, E as CookieConsent, H as CookieConsentInput, Q as QuoteRequest, I as SubmitQuoteInput, J as BackInStockSubscription } from './client-hCuGQERQ.mjs';
5
5
  export { K as AddToCartInput, L as AuthTokens, M as BehioApiError, N as BundleItem, T as CartDiscount, U as CartItem, V as CheckoutAddress, X as FulfillmentStatus, Y as LoginInput, Z as MessageResponse, _ as OrderItem, $ as OrderStatus, a0 as PaymentStatus, a1 as ProductPrice, a2 as ProductReview, a3 as ProductVariant } from './client-hCuGQERQ.mjs';
6
6
  import * as _tanstack_query_core from '@tanstack/query-core';
7
- export { formatPrice } from './index.mjs';
7
+ export { EcommerceEventName, EcommerceItem, EcommercePayload, formatPrice, trackEcommerceEvent } from './index.mjs';
8
8
 
9
9
  interface StorageAdapter {
10
10
  get(key: string): string | null;
package/dist/react.d.ts CHANGED
@@ -4,7 +4,7 @@ import { QueryClient } from '@tanstack/react-query';
4
4
  import { a as BehioStorefront, P as ProductsQuery, b as PaginatedResponse, c as ProductListItem, d as ProductDetail, C as Category, e as CategoryDetail, f as ProductLabel, F as FilterField, g as Cart, h as CustomerProfile, R as RegisterInput, i as CustomerAddress, A as AddressSuggestion, j as AddressDetail, O as OrderListItem, k as OrderDetail, l as OrderAccessRequestResponse, m as OrderAccessVerifyResponse, n as CheckoutInput, o as PageDetail, p as Page, S as ShopInfo, q as ShopScripts, r as ShopSeo, s as Bundle, t as CrossSellItem, u as ActivePromotion, G as GiftCardBalance, W as WishlistItem, v as ProductReviewsResponse, w as SubmitReviewInput, x as ReturnableOrder, y as ReturnStatus, z as ReturnRequest, D as SubmitReturnInput, E as CookieConsent, H as CookieConsentInput, Q as QuoteRequest, I as SubmitQuoteInput, J as BackInStockSubscription } from './client-hCuGQERQ.js';
5
5
  export { K as AddToCartInput, L as AuthTokens, M as BehioApiError, N as BundleItem, T as CartDiscount, U as CartItem, V as CheckoutAddress, X as FulfillmentStatus, Y as LoginInput, Z as MessageResponse, _ as OrderItem, $ as OrderStatus, a0 as PaymentStatus, a1 as ProductPrice, a2 as ProductReview, a3 as ProductVariant } from './client-hCuGQERQ.js';
6
6
  import * as _tanstack_query_core from '@tanstack/query-core';
7
- export { formatPrice } from './index.js';
7
+ export { EcommerceEventName, EcommerceItem, EcommercePayload, formatPrice, trackEcommerceEvent } from './index.js';
8
8
 
9
9
  interface StorageAdapter {
10
10
  get(key: string): string | null;
package/dist/react.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkXWYDXBLGjs = require('./chunk-XWYDXBLG.js');
3
+
4
+ var _chunkBFF5BKR2js = require('./chunk-BFF5BKR2.js');
4
5
 
5
6
 
6
7
  var _chunkBF4YVFHXjs = require('./chunk-BF4YVFHX.js');
@@ -1489,4 +1490,5 @@ function useBehioClient() {
1489
1490
 
1490
1491
 
1491
1492
 
1492
- exports.BehioProvider = BehioProvider; exports.CurrencySwitcher = CurrencySwitcher; exports.StorefrontScripts = StorefrontScripts; exports.cookieStorage = cookieStorage; exports.createMemoryStorage = createMemoryStorage; exports.detectStorage = detectStorage; exports.formatPrice = _chunkXWYDXBLGjs.formatPrice; exports.localStorageAdapter = localStorageAdapter; exports.memoryStorage = memoryStorage; exports.useAddressAutocomplete = useAddressAutocomplete; 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.useCookieConsent = useCookieConsent; exports.useCrossSell = useCrossSell; exports.useCurrency = useCurrency; exports.useCustomer = useCustomer; exports.useFeatured = useFeatured; exports.useFilters = useFilters; exports.useGiftCardBalance = useGiftCardBalance; exports.useIsInWishlist = useIsInWishlist; exports.useLabels = useLabels; exports.useLookupReturnableOrder = useLookupReturnableOrder; exports.useNotifyWhenAvailable = useNotifyWhenAvailable; exports.useOrder = useOrder; exports.useOrderAccess = useOrderAccess; exports.useOrders = useOrders; exports.usePage = usePage; exports.usePages = usePages; exports.useProduct = useProduct; exports.useProductPromotions = useProductPromotions; exports.useProductReviews = useProductReviews; exports.useProducts = useProducts; exports.useQuoteStatus = useQuoteStatus; exports.useReturnStatus = useReturnStatus; exports.useSearch = useSearch; exports.useShopInfo = useShopInfo; exports.useShopScripts = useShopScripts; exports.useShopSeo = useShopSeo; exports.useSubmitQuote = useSubmitQuote; exports.useSubmitReturn = useSubmitReturn; exports.useSubmitReview = useSubmitReview; exports.useWishlist = useWishlist;
1493
+
1494
+ exports.BehioProvider = BehioProvider; exports.CurrencySwitcher = CurrencySwitcher; exports.StorefrontScripts = StorefrontScripts; exports.cookieStorage = cookieStorage; exports.createMemoryStorage = createMemoryStorage; exports.detectStorage = detectStorage; exports.formatPrice = _chunkBFF5BKR2js.formatPrice; exports.localStorageAdapter = localStorageAdapter; exports.memoryStorage = memoryStorage; exports.trackEcommerceEvent = _chunkBFF5BKR2js.trackEcommerceEvent; exports.useAddressAutocomplete = useAddressAutocomplete; 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.useCookieConsent = useCookieConsent; exports.useCrossSell = useCrossSell; exports.useCurrency = useCurrency; exports.useCustomer = useCustomer; exports.useFeatured = useFeatured; exports.useFilters = useFilters; exports.useGiftCardBalance = useGiftCardBalance; exports.useIsInWishlist = useIsInWishlist; exports.useLabels = useLabels; exports.useLookupReturnableOrder = useLookupReturnableOrder; exports.useNotifyWhenAvailable = useNotifyWhenAvailable; exports.useOrder = useOrder; exports.useOrderAccess = useOrderAccess; exports.useOrders = useOrders; exports.usePage = usePage; exports.usePages = usePages; exports.useProduct = useProduct; exports.useProductPromotions = useProductPromotions; exports.useProductReviews = useProductReviews; exports.useProducts = useProducts; exports.useQuoteStatus = useQuoteStatus; exports.useReturnStatus = useReturnStatus; exports.useSearch = useSearch; exports.useShopInfo = useShopInfo; exports.useShopScripts = useShopScripts; exports.useShopSeo = useShopSeo; exports.useSubmitQuote = useSubmitQuote; exports.useSubmitReturn = useSubmitReturn; exports.useSubmitReview = useSubmitReview; exports.useWishlist = useWishlist;
package/dist/react.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
- formatPrice
3
- } from "./chunk-YJ45WIQZ.mjs";
2
+ formatPrice,
3
+ trackEcommerceEvent
4
+ } from "./chunk-AN3QTDNM.mjs";
4
5
  import {
5
6
  BehioStorefront
6
7
  } from "./chunk-PZED7VMQ.mjs";
@@ -1447,6 +1448,7 @@ export {
1447
1448
  formatPrice,
1448
1449
  localStorageAdapter,
1449
1450
  memoryStorage,
1451
+ trackEcommerceEvent,
1450
1452
  useAddressAutocomplete,
1451
1453
  useAddresses,
1452
1454
  useAuth,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@behio/storefront-sdk",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "TypeScript SDK for Behio Headless E-Shop — core client + React hooks",
5
5
  "author": "Behio",
6
6
  "license": "MIT",
@@ -1,18 +0,0 @@
1
- // src/react/utils/format-price.ts
2
- function formatPrice(amount, currency, locale) {
3
- const resolvedLocale = locale ?? "cs";
4
- try {
5
- return new Intl.NumberFormat(resolvedLocale, {
6
- style: "currency",
7
- currency,
8
- minimumFractionDigits: Number.isInteger(amount) ? 0 : 2,
9
- maximumFractionDigits: 2
10
- }).format(amount);
11
- } catch {
12
- return `${amount} ${currency}`;
13
- }
14
- }
15
-
16
- export {
17
- formatPrice
18
- };