@lime-bundles/react 3.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { CartLineInput, ProductVariant, ParsedBundle, WidgetConfig } from '@lime-bundles/core';
2
+ import { CartLineInput, BuyerResolver, ProductVariant, ParsedBundle, WidgetConfig } from '@lime-bundles/core';
3
3
  export { ABVariantOverrides, BUNDLES_FOR_PRODUCT_QUERY, BUNDLE_METAOBJECT_QUERY, BundleParseError, BundleType, CartLineInput, CountdownConfig, CtaConfig, DiscountConfig, FixedBundleData, FixedBundlePricing, HeaderConfig, ImageTransform, LayoutConfig, MixMatchBundleData, ParsedBundle, PopularBadgeConfig, PricingConfig, PricingRow, Product, ProductListConfig, ProductVariant, SHOP_CUSTOM_CSS_QUERY, SavingsBarConfig, StorefrontApiError, ThumbnailRatio, VolumeBundleData, VolumeTier, WIDGET_CONFIG_DEFAULTS, WidgetConfig, applyABVariantB, applyWidgetConfigVars, calculateDiscount, calculateTierSavings, computeBundleSaleCents, computeFixedPricing, createStorefrontClient, fetchBundlesForProduct, formatCents, formatCountdown, formatMoney, formatUnitPrice, getABTestAssignment, getActiveTier, hasConsent, injectCustomCss, mergeWidgetConfig, observeImpression, parseCents, parseMetaobjectBundle, parseMetaobjectBundleStrict, percentageDiscountUnit, reportAddToCart, reportImpression, sanitizeCustomCss, setConsent, thumbnailRatioVars, transformImageUrl, validateQuantity } from '@lime-bundles/core';
4
4
 
5
5
  /**
@@ -32,6 +32,25 @@ interface BundleComponentProps {
32
32
  analyticsEnabled?: boolean;
33
33
  /** Called with the thrown `Error` from fetchBundleData or onAddToCart. */
34
34
  onError?: (error: Error) => void;
35
+ /**
36
+ * ISO-3166 alpha-2 country code, passed as Storefront `@inContext(country:)`.
37
+ * Drives Markets pricing and currency. Omit for shop default.
38
+ */
39
+ country?: string;
40
+ /** ISO-639-1 language code, passed as `@inContext(language:)`. */
41
+ language?: string;
42
+ /**
43
+ * B2B buyer identity. Prefer the callback form (`() => Promise<BuyerInput>`)
44
+ * so the customer access token doesn't live in static prop trees. See
45
+ * the package README ("Markets & B2B") for the security threat model.
46
+ */
47
+ buyer?: BuyerResolver;
48
+ /**
49
+ * Current visitor's Shopify Market GID. When set and the bundle's
50
+ * `marketVisibility === "specific"`, the bundle is hidden if its
51
+ * `marketIds` doesn't include this market.
52
+ */
53
+ marketId?: string;
35
54
  }
36
55
 
37
56
  declare function FixedBundle(props: BundleComponentProps): react_jsx_runtime.JSX.Element | null;
@@ -116,6 +135,26 @@ interface FetchBundleDataOptions {
116
135
  signal?: AbortSignal;
117
136
  /** Override the Storefront API version pinned in `createStorefrontClient`. */
118
137
  apiVersion?: string;
138
+ /**
139
+ * ISO-3166 alpha-2 country code passed as `@inContext(country: ...)`.
140
+ * Drives Shopify Markets pricing, currency, and availability.
141
+ */
142
+ country?: string;
143
+ /** ISO-639-1 language code passed as `@inContext(language: ...)`. */
144
+ language?: string;
145
+ /**
146
+ * B2B buyer identity. Prefer the callback form for security — it lets
147
+ * you fetch the customer access token just-in-time so it doesn't sit
148
+ * in static prop trees. See packages/*\/README.md → "Markets & B2B".
149
+ */
150
+ buyer?: BuyerResolver;
151
+ /**
152
+ * Shopify Market GID for the current visitor. When set and the bundle's
153
+ * `marketVisibility === "specific"`, the bundle is filtered out if its
154
+ * `marketIds` doesn't include this market. Returned to the caller via
155
+ * `BundleVisibilityWarning[]` for surfacing.
156
+ */
157
+ marketId?: string;
119
158
  }
120
159
  declare function fetchBundleData(options: FetchBundleDataOptions): Promise<ParsedBundle>;
121
160
 
@@ -131,6 +170,14 @@ interface UseBundleDataOptions {
131
170
  shopDomain: string;
132
171
  storefrontAccessToken: string;
133
172
  bundleGid: string;
173
+ /** ISO-3166 alpha-2 country, passed as Storefront `@inContext(country:)`. */
174
+ country?: string;
175
+ /** ISO-639-1 language, passed as `@inContext(language:)`. */
176
+ language?: string;
177
+ /** B2B buyer identity. Prefer the callback form to keep tokens off prop trees. */
178
+ buyer?: BuyerResolver;
179
+ /** Current visitor's Market GID — filters market-restricted bundles client-side. */
180
+ marketId?: string;
134
181
  }
135
182
  type UseBundleDataResult = {
136
183
  status: "loading";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { CartLineInput, ProductVariant, ParsedBundle, WidgetConfig } from '@lime-bundles/core';
2
+ import { CartLineInput, BuyerResolver, ProductVariant, ParsedBundle, WidgetConfig } from '@lime-bundles/core';
3
3
  export { ABVariantOverrides, BUNDLES_FOR_PRODUCT_QUERY, BUNDLE_METAOBJECT_QUERY, BundleParseError, BundleType, CartLineInput, CountdownConfig, CtaConfig, DiscountConfig, FixedBundleData, FixedBundlePricing, HeaderConfig, ImageTransform, LayoutConfig, MixMatchBundleData, ParsedBundle, PopularBadgeConfig, PricingConfig, PricingRow, Product, ProductListConfig, ProductVariant, SHOP_CUSTOM_CSS_QUERY, SavingsBarConfig, StorefrontApiError, ThumbnailRatio, VolumeBundleData, VolumeTier, WIDGET_CONFIG_DEFAULTS, WidgetConfig, applyABVariantB, applyWidgetConfigVars, calculateDiscount, calculateTierSavings, computeBundleSaleCents, computeFixedPricing, createStorefrontClient, fetchBundlesForProduct, formatCents, formatCountdown, formatMoney, formatUnitPrice, getABTestAssignment, getActiveTier, hasConsent, injectCustomCss, mergeWidgetConfig, observeImpression, parseCents, parseMetaobjectBundle, parseMetaobjectBundleStrict, percentageDiscountUnit, reportAddToCart, reportImpression, sanitizeCustomCss, setConsent, thumbnailRatioVars, transformImageUrl, validateQuantity } from '@lime-bundles/core';
4
4
 
5
5
  /**
@@ -32,6 +32,25 @@ interface BundleComponentProps {
32
32
  analyticsEnabled?: boolean;
33
33
  /** Called with the thrown `Error` from fetchBundleData or onAddToCart. */
34
34
  onError?: (error: Error) => void;
35
+ /**
36
+ * ISO-3166 alpha-2 country code, passed as Storefront `@inContext(country:)`.
37
+ * Drives Markets pricing and currency. Omit for shop default.
38
+ */
39
+ country?: string;
40
+ /** ISO-639-1 language code, passed as `@inContext(language:)`. */
41
+ language?: string;
42
+ /**
43
+ * B2B buyer identity. Prefer the callback form (`() => Promise<BuyerInput>`)
44
+ * so the customer access token doesn't live in static prop trees. See
45
+ * the package README ("Markets & B2B") for the security threat model.
46
+ */
47
+ buyer?: BuyerResolver;
48
+ /**
49
+ * Current visitor's Shopify Market GID. When set and the bundle's
50
+ * `marketVisibility === "specific"`, the bundle is hidden if its
51
+ * `marketIds` doesn't include this market.
52
+ */
53
+ marketId?: string;
35
54
  }
36
55
 
37
56
  declare function FixedBundle(props: BundleComponentProps): react_jsx_runtime.JSX.Element | null;
@@ -116,6 +135,26 @@ interface FetchBundleDataOptions {
116
135
  signal?: AbortSignal;
117
136
  /** Override the Storefront API version pinned in `createStorefrontClient`. */
118
137
  apiVersion?: string;
138
+ /**
139
+ * ISO-3166 alpha-2 country code passed as `@inContext(country: ...)`.
140
+ * Drives Shopify Markets pricing, currency, and availability.
141
+ */
142
+ country?: string;
143
+ /** ISO-639-1 language code passed as `@inContext(language: ...)`. */
144
+ language?: string;
145
+ /**
146
+ * B2B buyer identity. Prefer the callback form for security — it lets
147
+ * you fetch the customer access token just-in-time so it doesn't sit
148
+ * in static prop trees. See packages/*\/README.md → "Markets & B2B".
149
+ */
150
+ buyer?: BuyerResolver;
151
+ /**
152
+ * Shopify Market GID for the current visitor. When set and the bundle's
153
+ * `marketVisibility === "specific"`, the bundle is filtered out if its
154
+ * `marketIds` doesn't include this market. Returned to the caller via
155
+ * `BundleVisibilityWarning[]` for surfacing.
156
+ */
157
+ marketId?: string;
119
158
  }
120
159
  declare function fetchBundleData(options: FetchBundleDataOptions): Promise<ParsedBundle>;
121
160
 
@@ -131,6 +170,14 @@ interface UseBundleDataOptions {
131
170
  shopDomain: string;
132
171
  storefrontAccessToken: string;
133
172
  bundleGid: string;
173
+ /** ISO-3166 alpha-2 country, passed as Storefront `@inContext(country:)`. */
174
+ country?: string;
175
+ /** ISO-639-1 language, passed as `@inContext(language:)`. */
176
+ language?: string;
177
+ /** B2B buyer identity. Prefer the callback form to keep tokens off prop trees. */
178
+ buyer?: BuyerResolver;
179
+ /** Current visitor's Market GID — filters market-restricted bundles client-side. */
180
+ marketId?: string;
134
181
  }
135
182
  type UseBundleDataResult = {
136
183
  status: "loading";
package/dist/index.js CHANGED
@@ -11,24 +11,43 @@ import {
11
11
 
12
12
  // src/hooks/useBundleData.ts
13
13
  import { useState, useEffect } from "react";
14
- import { injectCustomCss } from "@lime-bundles/core";
14
+ import {
15
+ injectCustomCss
16
+ } from "@lime-bundles/core";
15
17
 
16
18
  // src/fetchBundleData.ts
17
19
  import {
18
20
  createStorefrontClient,
21
+ hasInContext,
19
22
  BUNDLE_METAOBJECT_QUERY,
23
+ withInContext,
20
24
  parseMetaobjectBundleStrict,
21
25
  BundleParseError
22
26
  } from "@lime-bundles/core";
23
27
  async function fetchBundleData(options) {
24
- const client = createStorefrontClient({
28
+ const result = await fetchBundleDataWithWarnings(options);
29
+ if (!result.bundle) {
30
+ throw new BundleParseError(
31
+ `Bundle hidden by market gate: ${options.bundleGid}`,
32
+ "not_found"
33
+ );
34
+ }
35
+ return result.bundle;
36
+ }
37
+ async function fetchBundleDataWithWarnings(options) {
38
+ const config = {
25
39
  shopDomain: options.shopDomain,
26
40
  accessToken: options.storefrontAccessToken,
27
41
  buyerIp: options.buyerIp,
28
- apiVersion: options.apiVersion
29
- });
42
+ apiVersion: options.apiVersion,
43
+ country: options.country,
44
+ language: options.language,
45
+ buyer: options.buyer
46
+ };
47
+ const client = createStorefrontClient(config);
48
+ const query = hasInContext(config) ? withInContext(BUNDLE_METAOBJECT_QUERY) : BUNDLE_METAOBJECT_QUERY;
30
49
  const data = await client.query(
31
- BUNDLE_METAOBJECT_QUERY,
50
+ query,
32
51
  { id: options.bundleGid },
33
52
  { signal: options.signal }
34
53
  );
@@ -38,10 +57,24 @@ async function fetchBundleData(options) {
38
57
  "not_found"
39
58
  );
40
59
  }
41
- return parseMetaobjectBundleStrict(
60
+ const bundle = parseMetaobjectBundleStrict(
42
61
  data.metaobject.id,
43
62
  data.metaobject.fields
44
63
  );
64
+ if (bundle.marketVisibility === "specific" && (!options.marketId || !bundle.marketIds.includes(options.marketId))) {
65
+ return {
66
+ bundle: null,
67
+ warnings: [
68
+ {
69
+ bundleGid: options.bundleGid,
70
+ reason: "market_mismatch",
71
+ currentMarketId: options.marketId ?? null,
72
+ allowedMarketIds: bundle.marketIds
73
+ }
74
+ ]
75
+ };
76
+ }
77
+ return { bundle, warnings: [] };
45
78
  }
46
79
 
47
80
  // src/fetchShopCustomCss.ts
@@ -90,7 +123,11 @@ function useBundleData(options) {
90
123
  shopDomain: options.shopDomain,
91
124
  storefrontAccessToken: options.storefrontAccessToken,
92
125
  bundleGid: options.bundleGid,
93
- signal: controller.signal
126
+ signal: controller.signal,
127
+ country: options.country,
128
+ language: options.language,
129
+ buyer: options.buyer,
130
+ marketId: options.marketId
94
131
  }).then((bundle) => {
95
132
  if (controller.signal.aborted) return;
96
133
  setState({ status: "success", bundle, error: null });
@@ -117,7 +154,11 @@ function useBundleData(options) {
117
154
  }, [
118
155
  options.shopDomain,
119
156
  options.storefrontAccessToken,
120
- options.bundleGid
157
+ options.bundleGid,
158
+ options.country,
159
+ options.language,
160
+ options.buyer,
161
+ options.marketId
121
162
  ]);
122
163
  return state;
123
164
  }