@lime-bundles/react 7.3.0 → 7.4.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/README.md +7 -3
- package/dist/index.cjs +122 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -4
- package/dist/index.d.ts +36 -4
- package/dist/index.js +124 -23
- package/dist/index.js.map +1 -1
- package/dist/styles.css +137 -19
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -59,6 +59,14 @@ interface BundleComponentProps {
|
|
|
59
59
|
* more than one product should pass it.
|
|
60
60
|
*/
|
|
61
61
|
productId?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Store→presentment currency rate. Merchant-configured amounts
|
|
64
|
+
* (fixed_amount / flat_price values, volume tier amounts) are stored in
|
|
65
|
+
* the shop's store currency; pass the rate for the buyer's currency so
|
|
66
|
+
* quoted sale prices match what the checkout's discount function
|
|
67
|
+
* charges. Omit (or pass 1) on store-currency storefronts.
|
|
68
|
+
*/
|
|
69
|
+
currencyRate?: number;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
declare function FixedBundle(props: BundleComponentProps): react_jsx_runtime.JSX.Element | null;
|
|
@@ -187,12 +195,24 @@ interface FetchBundleDataOptions {
|
|
|
187
195
|
*/
|
|
188
196
|
buyer?: BuyerResolver;
|
|
189
197
|
/**
|
|
190
|
-
* Shopify Market GID for the current visitor.
|
|
191
|
-
* `marketVisibility === "specific"`,
|
|
192
|
-
*
|
|
193
|
-
* `
|
|
198
|
+
* Shopify Market GID for the current visitor. Legacy market-gate signal:
|
|
199
|
+
* when set and the bundle's `marketVisibility === "specific"`, a direct
|
|
200
|
+
* market-id match shows the bundle. Prefer letting the gate work from
|
|
201
|
+
* `country` (retail) and `buyer.companyLocationId` (B2B) — Shopify has
|
|
202
|
+
* deprecated market IDs as buyer-targeting signals, and a B2B buyer's
|
|
203
|
+
* company-location market has no storefront market context at all.
|
|
204
|
+
* Misses are returned via `BundleVisibilityWarning[]` for surfacing.
|
|
194
205
|
*/
|
|
195
206
|
marketId?: string;
|
|
207
|
+
/**
|
|
208
|
+
* Store→presentment currency rate. Merchant-configured amounts
|
|
209
|
+
* (fixed_amount / flat_price values, volume tier amounts) are stored in
|
|
210
|
+
* the shop's store currency; pass the rate for the buyer's currency so
|
|
211
|
+
* quoted sale prices match what the checkout's discount function
|
|
212
|
+
* charges. Omit (or pass 1) on store-currency storefronts. See
|
|
213
|
+
* `convertBundleToPresentment` in `@lime-bundles/core`.
|
|
214
|
+
*/
|
|
215
|
+
currencyRate?: number;
|
|
196
216
|
}
|
|
197
217
|
declare function fetchBundleData(options: FetchBundleDataOptions): Promise<ParsedBundle>;
|
|
198
218
|
|
|
@@ -229,6 +249,12 @@ interface UseBundleDataOptions {
|
|
|
229
249
|
buyer?: BuyerResolver;
|
|
230
250
|
/** Current visitor's Market GID — filters market-restricted bundles client-side. */
|
|
231
251
|
marketId?: string;
|
|
252
|
+
/**
|
|
253
|
+
* Store→presentment currency rate for merchant-configured amounts
|
|
254
|
+
* (fixed_amount / flat_price values, volume tier amounts). See
|
|
255
|
+
* `FetchBundleDataOptions.currencyRate`.
|
|
256
|
+
*/
|
|
257
|
+
currencyRate?: number;
|
|
232
258
|
}
|
|
233
259
|
type UseBundleDataResult = {
|
|
234
260
|
status: "loading";
|
|
@@ -251,6 +277,12 @@ interface UseBundlesForProductOptions {
|
|
|
251
277
|
productHandle: string;
|
|
252
278
|
/** Forwarded as `Shopify-Storefront-Buyer-IP` — required for SSR paths. */
|
|
253
279
|
buyerIp?: string;
|
|
280
|
+
/**
|
|
281
|
+
* Store→presentment currency rate for merchant-configured amounts
|
|
282
|
+
* (fixed_amount / flat_price values, volume tier amounts). See
|
|
283
|
+
* `FetchBundlesForProductOptions.currencyRate`.
|
|
284
|
+
*/
|
|
285
|
+
currencyRate?: number;
|
|
254
286
|
}
|
|
255
287
|
type UseBundlesForProductResult = {
|
|
256
288
|
status: "loading";
|
package/dist/index.d.ts
CHANGED
|
@@ -59,6 +59,14 @@ interface BundleComponentProps {
|
|
|
59
59
|
* more than one product should pass it.
|
|
60
60
|
*/
|
|
61
61
|
productId?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Store→presentment currency rate. Merchant-configured amounts
|
|
64
|
+
* (fixed_amount / flat_price values, volume tier amounts) are stored in
|
|
65
|
+
* the shop's store currency; pass the rate for the buyer's currency so
|
|
66
|
+
* quoted sale prices match what the checkout's discount function
|
|
67
|
+
* charges. Omit (or pass 1) on store-currency storefronts.
|
|
68
|
+
*/
|
|
69
|
+
currencyRate?: number;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
declare function FixedBundle(props: BundleComponentProps): react_jsx_runtime.JSX.Element | null;
|
|
@@ -187,12 +195,24 @@ interface FetchBundleDataOptions {
|
|
|
187
195
|
*/
|
|
188
196
|
buyer?: BuyerResolver;
|
|
189
197
|
/**
|
|
190
|
-
* Shopify Market GID for the current visitor.
|
|
191
|
-
* `marketVisibility === "specific"`,
|
|
192
|
-
*
|
|
193
|
-
* `
|
|
198
|
+
* Shopify Market GID for the current visitor. Legacy market-gate signal:
|
|
199
|
+
* when set and the bundle's `marketVisibility === "specific"`, a direct
|
|
200
|
+
* market-id match shows the bundle. Prefer letting the gate work from
|
|
201
|
+
* `country` (retail) and `buyer.companyLocationId` (B2B) — Shopify has
|
|
202
|
+
* deprecated market IDs as buyer-targeting signals, and a B2B buyer's
|
|
203
|
+
* company-location market has no storefront market context at all.
|
|
204
|
+
* Misses are returned via `BundleVisibilityWarning[]` for surfacing.
|
|
194
205
|
*/
|
|
195
206
|
marketId?: string;
|
|
207
|
+
/**
|
|
208
|
+
* Store→presentment currency rate. Merchant-configured amounts
|
|
209
|
+
* (fixed_amount / flat_price values, volume tier amounts) are stored in
|
|
210
|
+
* the shop's store currency; pass the rate for the buyer's currency so
|
|
211
|
+
* quoted sale prices match what the checkout's discount function
|
|
212
|
+
* charges. Omit (or pass 1) on store-currency storefronts. See
|
|
213
|
+
* `convertBundleToPresentment` in `@lime-bundles/core`.
|
|
214
|
+
*/
|
|
215
|
+
currencyRate?: number;
|
|
196
216
|
}
|
|
197
217
|
declare function fetchBundleData(options: FetchBundleDataOptions): Promise<ParsedBundle>;
|
|
198
218
|
|
|
@@ -229,6 +249,12 @@ interface UseBundleDataOptions {
|
|
|
229
249
|
buyer?: BuyerResolver;
|
|
230
250
|
/** Current visitor's Market GID — filters market-restricted bundles client-side. */
|
|
231
251
|
marketId?: string;
|
|
252
|
+
/**
|
|
253
|
+
* Store→presentment currency rate for merchant-configured amounts
|
|
254
|
+
* (fixed_amount / flat_price values, volume tier amounts). See
|
|
255
|
+
* `FetchBundleDataOptions.currencyRate`.
|
|
256
|
+
*/
|
|
257
|
+
currencyRate?: number;
|
|
232
258
|
}
|
|
233
259
|
type UseBundleDataResult = {
|
|
234
260
|
status: "loading";
|
|
@@ -251,6 +277,12 @@ interface UseBundlesForProductOptions {
|
|
|
251
277
|
productHandle: string;
|
|
252
278
|
/** Forwarded as `Shopify-Storefront-Buyer-IP` — required for SSR paths. */
|
|
253
279
|
buyerIp?: string;
|
|
280
|
+
/**
|
|
281
|
+
* Store→presentment currency rate for merchant-configured amounts
|
|
282
|
+
* (fixed_amount / flat_price values, volume tier amounts). See
|
|
283
|
+
* `FetchBundlesForProductOptions.currencyRate`.
|
|
284
|
+
*/
|
|
285
|
+
currencyRate?: number;
|
|
254
286
|
}
|
|
255
287
|
type UseBundlesForProductResult = {
|
|
256
288
|
status: "loading";
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,8 @@ import {
|
|
|
22
22
|
BUNDLE_METAOBJECT_QUERY,
|
|
23
23
|
withInContext,
|
|
24
24
|
parseMetaobjectBundleStrict,
|
|
25
|
-
|
|
25
|
+
convertBundleToPresentment,
|
|
26
|
+
isVisibleToBuyer,
|
|
26
27
|
BundleParseError
|
|
27
28
|
} from "@lime-bundles/core";
|
|
28
29
|
async function fetchBundleData(options) {
|
|
@@ -36,6 +37,7 @@ async function fetchBundleData(options) {
|
|
|
36
37
|
return result.bundle;
|
|
37
38
|
}
|
|
38
39
|
async function fetchBundleDataWithWarnings(options) {
|
|
40
|
+
const buyer = typeof options.buyer === "function" ? await options.buyer() : options.buyer;
|
|
39
41
|
const config = {
|
|
40
42
|
shopDomain: options.shopDomain,
|
|
41
43
|
accessToken: options.storefrontAccessToken,
|
|
@@ -43,7 +45,7 @@ async function fetchBundleDataWithWarnings(options) {
|
|
|
43
45
|
apiVersion: options.apiVersion,
|
|
44
46
|
country: options.country,
|
|
45
47
|
language: options.language,
|
|
46
|
-
buyer
|
|
48
|
+
buyer
|
|
47
49
|
};
|
|
48
50
|
const client = createStorefrontClient(config);
|
|
49
51
|
const query = hasInContext(config) ? withInContext(BUNDLE_METAOBJECT_QUERY) : BUNDLE_METAOBJECT_QUERY;
|
|
@@ -58,11 +60,16 @@ async function fetchBundleDataWithWarnings(options) {
|
|
|
58
60
|
"not_found"
|
|
59
61
|
);
|
|
60
62
|
}
|
|
61
|
-
const bundle =
|
|
62
|
-
data.metaobject.id,
|
|
63
|
-
|
|
63
|
+
const bundle = convertBundleToPresentment(
|
|
64
|
+
parseMetaobjectBundleStrict(data.metaobject.id, data.metaobject.fields),
|
|
65
|
+
options.currencyRate
|
|
64
66
|
);
|
|
65
|
-
|
|
67
|
+
const buyerContext = {
|
|
68
|
+
marketId: options.marketId,
|
|
69
|
+
countryCode: options.country,
|
|
70
|
+
companyLocationId: buyer?.companyLocationId
|
|
71
|
+
};
|
|
72
|
+
if (!isVisibleToBuyer(bundle, buyerContext)) {
|
|
66
73
|
return {
|
|
67
74
|
bundle: null,
|
|
68
75
|
warnings: [
|
|
@@ -70,7 +77,11 @@ async function fetchBundleDataWithWarnings(options) {
|
|
|
70
77
|
bundleGid: options.bundleGid,
|
|
71
78
|
reason: "market_mismatch",
|
|
72
79
|
currentMarketId: options.marketId ?? null,
|
|
73
|
-
|
|
80
|
+
currentCountryCode: options.country ?? null,
|
|
81
|
+
currentCompanyLocationId: buyer?.companyLocationId ?? null,
|
|
82
|
+
allowedMarketIds: bundle.marketIds,
|
|
83
|
+
allowedCountryCodes: bundle.countryCodes,
|
|
84
|
+
allowedCompanyLocationIds: bundle.companyLocationIds
|
|
74
85
|
}
|
|
75
86
|
]
|
|
76
87
|
};
|
|
@@ -140,7 +151,8 @@ function useBundleData(options) {
|
|
|
140
151
|
country: options.country,
|
|
141
152
|
language: options.language,
|
|
142
153
|
buyer: options.buyer,
|
|
143
|
-
marketId: options.marketId
|
|
154
|
+
marketId: options.marketId,
|
|
155
|
+
currencyRate: options.currencyRate
|
|
144
156
|
}).then((bundle) => {
|
|
145
157
|
if (controller.signal.aborted) return;
|
|
146
158
|
setState({ status: "success", bundle, error: null });
|
|
@@ -171,7 +183,8 @@ function useBundleData(options) {
|
|
|
171
183
|
options.country,
|
|
172
184
|
options.language,
|
|
173
185
|
options.buyer,
|
|
174
|
-
options.marketId
|
|
186
|
+
options.marketId,
|
|
187
|
+
options.currencyRate
|
|
175
188
|
]);
|
|
176
189
|
return state;
|
|
177
190
|
}
|
|
@@ -706,12 +719,22 @@ function FixedBundle(props) {
|
|
|
706
719
|
analyticsEnabled,
|
|
707
720
|
onAddToCart,
|
|
708
721
|
onError,
|
|
709
|
-
className
|
|
722
|
+
className,
|
|
723
|
+
country,
|
|
724
|
+
language,
|
|
725
|
+
buyer,
|
|
726
|
+
marketId,
|
|
727
|
+
currencyRate
|
|
710
728
|
} = props;
|
|
711
729
|
const result = useBundleData({
|
|
712
730
|
shopDomain,
|
|
713
731
|
storefrontAccessToken,
|
|
714
|
-
bundleGid
|
|
732
|
+
bundleGid,
|
|
733
|
+
country,
|
|
734
|
+
language,
|
|
735
|
+
buyer,
|
|
736
|
+
marketId,
|
|
737
|
+
currencyRate
|
|
715
738
|
});
|
|
716
739
|
const { elementRef, trackAddToCart } = useAnalytics({
|
|
717
740
|
shopDomain,
|
|
@@ -1784,12 +1807,22 @@ function MixMatchBundle(props) {
|
|
|
1784
1807
|
onAddToCart,
|
|
1785
1808
|
onError,
|
|
1786
1809
|
className,
|
|
1787
|
-
productHandle
|
|
1810
|
+
productHandle,
|
|
1811
|
+
country,
|
|
1812
|
+
language,
|
|
1813
|
+
buyer,
|
|
1814
|
+
marketId,
|
|
1815
|
+
currencyRate
|
|
1788
1816
|
} = props;
|
|
1789
1817
|
const result = useBundleData({
|
|
1790
1818
|
shopDomain,
|
|
1791
1819
|
storefrontAccessToken,
|
|
1792
|
-
bundleGid
|
|
1820
|
+
bundleGid,
|
|
1821
|
+
country,
|
|
1822
|
+
language,
|
|
1823
|
+
buyer,
|
|
1824
|
+
marketId,
|
|
1825
|
+
currencyRate
|
|
1793
1826
|
});
|
|
1794
1827
|
const { elementRef, trackAddToCart } = useAnalytics({
|
|
1795
1828
|
shopDomain,
|
|
@@ -2327,12 +2360,22 @@ function VolumeBundle(props) {
|
|
|
2327
2360
|
onAddToCart,
|
|
2328
2361
|
onError,
|
|
2329
2362
|
className,
|
|
2330
|
-
productId
|
|
2363
|
+
productId,
|
|
2364
|
+
country,
|
|
2365
|
+
language,
|
|
2366
|
+
buyer,
|
|
2367
|
+
marketId,
|
|
2368
|
+
currencyRate
|
|
2331
2369
|
} = props;
|
|
2332
2370
|
const result = useBundleData({
|
|
2333
2371
|
shopDomain,
|
|
2334
2372
|
storefrontAccessToken,
|
|
2335
|
-
bundleGid
|
|
2373
|
+
bundleGid,
|
|
2374
|
+
country,
|
|
2375
|
+
language,
|
|
2376
|
+
buyer,
|
|
2377
|
+
marketId,
|
|
2378
|
+
currencyRate
|
|
2336
2379
|
});
|
|
2337
2380
|
const { elementRef, trackAddToCart } = useAnalytics({
|
|
2338
2381
|
shopDomain,
|
|
@@ -2712,12 +2755,22 @@ function BogoBundle(props) {
|
|
|
2712
2755
|
analyticsEnabled,
|
|
2713
2756
|
onAddToCart,
|
|
2714
2757
|
onError,
|
|
2715
|
-
className
|
|
2758
|
+
className,
|
|
2759
|
+
country,
|
|
2760
|
+
language,
|
|
2761
|
+
buyer,
|
|
2762
|
+
marketId,
|
|
2763
|
+
currencyRate
|
|
2716
2764
|
} = props;
|
|
2717
2765
|
const result = useBundleData({
|
|
2718
2766
|
shopDomain,
|
|
2719
2767
|
storefrontAccessToken,
|
|
2720
|
-
bundleGid
|
|
2768
|
+
bundleGid,
|
|
2769
|
+
country,
|
|
2770
|
+
language,
|
|
2771
|
+
buyer,
|
|
2772
|
+
marketId,
|
|
2773
|
+
currencyRate
|
|
2721
2774
|
});
|
|
2722
2775
|
const { elementRef, trackAddToCart } = useAnalytics({
|
|
2723
2776
|
shopDomain,
|
|
@@ -3076,6 +3129,8 @@ function normalizeText2(str) {
|
|
|
3076
3129
|
return str.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
|
|
3077
3130
|
}
|
|
3078
3131
|
var FILTERS_ALL2 = "__all__";
|
|
3132
|
+
var STEP_CASCADE_MS = 500;
|
|
3133
|
+
var AUTO_ADVANCE_HOLD_MS = 160;
|
|
3079
3134
|
function MultiStepPicker({
|
|
3080
3135
|
bundle,
|
|
3081
3136
|
currency,
|
|
@@ -3099,6 +3154,8 @@ function MultiStepPicker({
|
|
|
3099
3154
|
const closeBtnRef = useRef7(null);
|
|
3100
3155
|
const listRef = useRef7(null);
|
|
3101
3156
|
const mouseDownTarget = useRef7(null);
|
|
3157
|
+
const cascadeTimer = useRef7(null);
|
|
3158
|
+
const autoAdvanceTimer = useRef7(null);
|
|
3102
3159
|
const [open, setOpen] = useState11(false);
|
|
3103
3160
|
const [stepIndex, setStepIndex] = useState11(
|
|
3104
3161
|
() => Math.max(0, Math.min(steps.length - 1, initialStep))
|
|
@@ -3134,6 +3191,14 @@ function MultiStepPicker({
|
|
|
3134
3191
|
const id = requestAnimationFrame(() => setOpen(true));
|
|
3135
3192
|
return () => cancelAnimationFrame(id);
|
|
3136
3193
|
}, []);
|
|
3194
|
+
useEffect14(() => {
|
|
3195
|
+
return () => {
|
|
3196
|
+
if (cascadeTimer.current !== null) clearTimeout(cascadeTimer.current);
|
|
3197
|
+
if (autoAdvanceTimer.current !== null) {
|
|
3198
|
+
clearTimeout(autoAdvanceTimer.current);
|
|
3199
|
+
}
|
|
3200
|
+
};
|
|
3201
|
+
}, []);
|
|
3137
3202
|
useScrollLock(true);
|
|
3138
3203
|
useFocusTrap({
|
|
3139
3204
|
active: true,
|
|
@@ -3162,12 +3227,36 @@ function MultiStepPicker({
|
|
|
3162
3227
|
lastSeen.current = { step: stepIndex, units: unitsInStep };
|
|
3163
3228
|
if (!autoAdvance || isLastStep || prev.step !== stepIndex) return;
|
|
3164
3229
|
if (unitsInStep <= prev.units) return;
|
|
3165
|
-
if (stepHeadroom(step?.maxQuantity ?? null, unitsInStep)
|
|
3166
|
-
|
|
3230
|
+
if (stepHeadroom(step?.maxQuantity ?? null, unitsInStep) !== 0) return;
|
|
3231
|
+
const from = stepIndex;
|
|
3232
|
+
if (autoAdvanceTimer.current !== null) {
|
|
3233
|
+
clearTimeout(autoAdvanceTimer.current);
|
|
3167
3234
|
}
|
|
3235
|
+
autoAdvanceTimer.current = setTimeout(() => {
|
|
3236
|
+
autoAdvanceTimer.current = null;
|
|
3237
|
+
goToStep(from + 1);
|
|
3238
|
+
}, AUTO_ADVANCE_HOLD_MS);
|
|
3168
3239
|
});
|
|
3169
3240
|
function goToStep(i) {
|
|
3170
3241
|
const clamped = Math.max(0, Math.min(steps.length - 1, i));
|
|
3242
|
+
if (autoAdvanceTimer.current !== null) {
|
|
3243
|
+
clearTimeout(autoAdvanceTimer.current);
|
|
3244
|
+
autoAdvanceTimer.current = null;
|
|
3245
|
+
}
|
|
3246
|
+
const dialog = dialogRef.current;
|
|
3247
|
+
if (dialog && clamped !== stepIndex) {
|
|
3248
|
+
if (cascadeTimer.current !== null) clearTimeout(cascadeTimer.current);
|
|
3249
|
+
dialog.removeAttribute("data-step-transition");
|
|
3250
|
+
void dialog.offsetHeight;
|
|
3251
|
+
dialog.setAttribute(
|
|
3252
|
+
"data-step-transition",
|
|
3253
|
+
clamped > stepIndex ? "forward" : "back"
|
|
3254
|
+
);
|
|
3255
|
+
cascadeTimer.current = setTimeout(() => {
|
|
3256
|
+
cascadeTimer.current = null;
|
|
3257
|
+
dialog.removeAttribute("data-step-transition");
|
|
3258
|
+
}, STEP_CASCADE_MS);
|
|
3259
|
+
}
|
|
3171
3260
|
setStepIndex(clamped);
|
|
3172
3261
|
setQuery("");
|
|
3173
3262
|
setActiveType(FILTERS_ALL2);
|
|
@@ -3752,12 +3841,22 @@ function MultiStepBundle(props) {
|
|
|
3752
3841
|
analyticsEnabled,
|
|
3753
3842
|
onAddToCart,
|
|
3754
3843
|
onError,
|
|
3755
|
-
className
|
|
3844
|
+
className,
|
|
3845
|
+
country,
|
|
3846
|
+
language,
|
|
3847
|
+
buyer,
|
|
3848
|
+
marketId,
|
|
3849
|
+
currencyRate
|
|
3756
3850
|
} = props;
|
|
3757
3851
|
const result = useBundleData({
|
|
3758
3852
|
shopDomain,
|
|
3759
3853
|
storefrontAccessToken,
|
|
3760
|
-
bundleGid
|
|
3854
|
+
bundleGid,
|
|
3855
|
+
country,
|
|
3856
|
+
language,
|
|
3857
|
+
buyer,
|
|
3858
|
+
marketId,
|
|
3859
|
+
currencyRate
|
|
3761
3860
|
});
|
|
3762
3861
|
const { elementRef, trackAddToCart } = useAnalytics({
|
|
3763
3862
|
shopDomain,
|
|
@@ -4366,7 +4465,8 @@ function useBundlesForProduct(options) {
|
|
|
4366
4465
|
storefrontAccessToken: options.storefrontAccessToken,
|
|
4367
4466
|
productHandle: options.productHandle,
|
|
4368
4467
|
buyerIp: options.buyerIp,
|
|
4369
|
-
signal: controller.signal
|
|
4468
|
+
signal: controller.signal,
|
|
4469
|
+
currencyRate: options.currencyRate
|
|
4370
4470
|
}).then((bundles) => {
|
|
4371
4471
|
if (controller.signal.aborted) return;
|
|
4372
4472
|
setState({ status: "success", bundles, error: null });
|
|
@@ -4394,7 +4494,8 @@ function useBundlesForProduct(options) {
|
|
|
4394
4494
|
options.shopDomain,
|
|
4395
4495
|
options.storefrontAccessToken,
|
|
4396
4496
|
options.productHandle,
|
|
4397
|
-
options.buyerIp
|
|
4497
|
+
options.buyerIp,
|
|
4498
|
+
options.currencyRate
|
|
4398
4499
|
]);
|
|
4399
4500
|
return state;
|
|
4400
4501
|
}
|