@anker-in/shopify-react 0.1.1-beta.5 → 0.1.1-beta.51

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.js CHANGED
@@ -5,6 +5,7 @@ var shopifySdk = require('@anker-in/shopify-sdk');
5
5
  var Cookies5 = require('js-cookie');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
  var Decimal2 = require('decimal.js');
8
+ var shopifyCore = require('@anker-in/shopify-core');
8
9
  var useSWR = require('swr');
9
10
  var useSWRMutation = require('swr/mutation');
10
11
  var ahooks = require('ahooks');
@@ -53,6 +54,20 @@ var browserCartCookieAdapter = {
53
54
  Cookies5__default.default.remove(getCartCookieName(locale));
54
55
  }
55
56
  };
57
+
58
+ // src/adapters/browser-performance.ts
59
+ var BrowserPerformanceAdapter = class {
60
+ /**
61
+ * Start tracking a performance event
62
+ */
63
+ addToCartStart() {
64
+ }
65
+ /**
66
+ * End tracking a performance event
67
+ */
68
+ addToCartEnd() {
69
+ }
70
+ };
56
71
  function ShopifyProvider({
57
72
  config,
58
73
  locale,
@@ -61,7 +76,8 @@ function ShopifyProvider({
61
76
  cartCookieAdapter = browserCartCookieAdapter,
62
77
  routerAdapter,
63
78
  userAdapter,
64
- children
79
+ children,
80
+ performanceAdapter
65
81
  }) {
66
82
  const client = react.useMemo(() => {
67
83
  return shopifySdk.createShopifyClient(config, locale);
@@ -75,7 +91,8 @@ function ShopifyProvider({
75
91
  cookieAdapter,
76
92
  cartCookieAdapter,
77
93
  routerAdapter,
78
- userAdapter
94
+ userAdapter,
95
+ performanceAdapter
79
96
  };
80
97
  }, [
81
98
  client,
@@ -85,6 +102,7 @@ function ShopifyProvider({
85
102
  cookieAdapter,
86
103
  cartCookieAdapter,
87
104
  routerAdapter,
105
+ performanceAdapter,
88
106
  userAdapter
89
107
  ]);
90
108
  return /* @__PURE__ */ jsxRuntime.jsx(ShopifyContext.Provider, { value, children });
@@ -140,6 +158,7 @@ var CUSTOMER_ATTRIBUTE_KEY = "_discounts_function_env";
140
158
  var CUSTOMER_SCRIPT_GIFT_KEY = "_giveaway_gradient_gifts";
141
159
  var CODE_AMOUNT_KEY = "_sku_code_money";
142
160
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
161
+ var MEMBER_PRICE_ATTRIBUTE_KEY = "_member_price";
143
162
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
144
163
 
145
164
  // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
@@ -148,9 +167,10 @@ function normalizeAddToCartLines(lines) {
148
167
  const variant = line.variant;
149
168
  const product = variant.product;
150
169
  const quantity = line.quantity || 1;
151
- const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
152
- const subtotalAmount = price * quantity;
153
- const totalAmount = subtotalAmount;
170
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
171
+ const finalPrice = variant.finalPrice?.amount === void 0 ? originalPrice : Number(variant.finalPrice?.amount);
172
+ const subtotalAmount = originalPrice * quantity;
173
+ const totalAmount = finalPrice * quantity;
154
174
  return {
155
175
  id: `temp-line-${index}-${variant.id}`,
156
176
  // Temporary ID for pre-cart lines
@@ -164,7 +184,7 @@ function normalizeAddToCartLines(lines) {
164
184
  customAttributes: line.attributes || [],
165
185
  variant: {
166
186
  id: variant.id,
167
- price,
187
+ price: finalPrice,
168
188
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
169
189
  sku: variant.sku || "",
170
190
  name: variant.title || "",
@@ -195,15 +215,16 @@ function createMockCartFromLines(lines, existingCart) {
195
215
  const normalizedLines = normalizeAddToCartLines(lines);
196
216
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
197
217
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
218
+ const currency = lines[0]?.variant?.price?.currencyCode;
198
219
  return {
199
220
  id: existingCart?.id || "temp-cart-id",
200
221
  customerId: existingCart?.customerId,
201
222
  email: existingCart?.email,
202
223
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
203
- currency: existingCart?.currency || { code: "USD" },
224
+ currency: existingCart?.currency || { code: currency },
204
225
  taxesIncluded: existingCart?.taxesIncluded,
205
226
  lineItems: normalizedLines,
206
- totallineItemsDiscount: 0,
227
+ totalLineItemsDiscount: 0,
207
228
  orderDiscounts: 0,
208
229
  lineItemsSubtotalPrice: subtotalPrice,
209
230
  subtotalPrice,
@@ -234,22 +255,12 @@ var getQuery = () => {
234
255
  }
235
256
  return theRequest;
236
257
  };
237
- function atobID(id) {
238
- if (id && typeof id === "string" && id.includes("/")) {
239
- return id.split("/").pop()?.split("?")?.shift();
240
- } else {
241
- return id;
242
- }
243
- }
244
- function btoaID(id, type = "ProductVariant") {
245
- return `gid://shopify/${type}/${id}`;
246
- }
247
258
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
248
259
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
249
260
  const matchedList = cartData?.lineItems?.filter((line) => {
250
261
  const { is_gift } = getDiscountEnvAttributeValue(line.customAttributes);
251
262
  return isAllStoreVariant ? !is_gift : variant_list?.find((item) => {
252
- return !is_gift && atobID(line.variantId) === item;
263
+ return !is_gift && shopifyCore.atobID(line.variantId) === item;
253
264
  });
254
265
  });
255
266
  return matchedList?.reduce((acc, line) => {
@@ -267,14 +278,6 @@ var getDiscountEnvAttributeValue = (attributes = []) => {
267
278
  const attr = attributes.find((attr2) => attr2.key === CUSTOMER_ATTRIBUTE_KEY);
268
279
  return safeParse(attr?.value ?? "") ?? {};
269
280
  };
270
- var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
271
- return oldAttributes.some((attr) => {
272
- const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
273
- return newAttr ? newAttr.value !== attr.value : true;
274
- }) || newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || customAttributesNeedRemove.some(
275
- (removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
276
- );
277
- };
278
281
  var containsAll = (source, requiredItems = []) => {
279
282
  if (!requiredItems?.length) return true;
280
283
  const sourceSet = new Set(source);
@@ -475,43 +478,29 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
475
478
  }
476
479
  return { activeCampaign: null, subtotal: 0 };
477
480
  }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
478
- const { qualifyingGift, nextTierGoal } = react.useMemo(() => {
481
+ const { qualifyingTier, nextTierGoal, actualThreshold, currentCurrency } = react.useMemo(() => {
479
482
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
480
- return { qualifyingGift: null, nextTierGoal: null };
483
+ return { qualifyingTier: null, nextTierGoal: null, actualThreshold: 0, currentCurrency: "" };
481
484
  }
482
485
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
483
- const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
484
- const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
485
- if (!qualifyingTier) {
486
- return { qualifyingGift: null, nextTierGoal: nextGoal || null };
487
- }
488
- const formattedGift = {
489
- tier: qualifyingTier,
490
- itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
491
- const giftProduct = reward?.variant_list?.[0];
492
- if (!giftProduct) return null;
493
- return {
494
- variant: {
495
- id: btoaID(giftProduct.variant_id),
496
- handle: giftProduct.handle,
497
- sku: giftProduct.sku
498
- },
499
- quantity: reward?.get_unit || 1,
500
- attributes: [
501
- {
502
- key: CUSTOMER_ATTRIBUTE_KEY,
503
- value: JSON.stringify({
504
- is_gift: true,
505
- rule_id: activeCampaign.rule_id,
506
- spend_sum_money: qualifyingTier.spend_sum_money
507
- })
508
- }
509
- ]
510
- };
511
- }).filter((item) => item !== null)
486
+ const currentCurrency2 = effectiveCart?.currency?.code || "";
487
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency2);
488
+ const getThresholdAmount = (tier) => {
489
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency2]?.value) {
490
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency2].value);
491
+ }
492
+ return Number(tier.spend_sum_money || 0);
512
493
  };
513
- return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
514
- }, [activeCampaign, subtotal]);
494
+ const qualifyingTier2 = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
495
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
496
+ const actualThreshold2 = qualifyingTier2 ? getThresholdAmount(qualifyingTier2) : 0;
497
+ return {
498
+ qualifyingTier: qualifyingTier2,
499
+ nextTierGoal: nextGoal || null,
500
+ actualThreshold: actualThreshold2,
501
+ currentCurrency: currentCurrency2
502
+ };
503
+ }, [activeCampaign, subtotal, effectiveCart]);
515
504
  const giftHandles = react.useMemo(() => {
516
505
  const giftVariant = autoFreeGiftConfig.map(
517
506
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -527,24 +516,82 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
527
516
  }
528
517
  return true;
529
518
  }, [giftHandles]);
530
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
531
- const res = await shopifySdk.getProductsByHandles(client, {
532
- handles: giftHandles,
533
- locale
534
- });
535
- const result = Array.isArray(res) ? res : [];
536
- giftProductsCache.current = {
537
- data: result,
538
- giftHandles: [...giftHandles]
539
- };
540
- return result;
541
- });
519
+ const { data: giftProductsResult } = useSWR__default.default(
520
+ shouldFetch ? giftHandles : null,
521
+ async () => {
522
+ const res = await shopifySdk.getProductsByHandles(client, {
523
+ handles: giftHandles,
524
+ locale
525
+ });
526
+ const result = Array.isArray(res) ? res : [];
527
+ giftProductsCache.current = {
528
+ data: result,
529
+ giftHandles: [...giftHandles]
530
+ };
531
+ return result;
532
+ },
533
+ {
534
+ revalidateOnFocus: false
535
+ }
536
+ );
542
537
  const finalGiftProductsResult = react.useMemo(() => {
543
538
  if (giftProductsCache.current && !shouldFetch) {
544
539
  return giftProductsCache.current.data || void 0;
545
540
  }
546
541
  return giftProductsResult;
547
542
  }, [giftProductsResult, shouldFetch]);
543
+ const qualifyingGift = react.useMemo(() => {
544
+ if (!qualifyingTier || !activeCampaign) {
545
+ return null;
546
+ }
547
+ const itemsToAdd = qualifyingTier.reward_list?.map((reward) => {
548
+ if (!reward.variant_list || reward.variant_list.length === 0) {
549
+ return null;
550
+ }
551
+ let selectedGiftProduct = null;
552
+ for (const giftVariant of reward.variant_list) {
553
+ const productInfo = finalGiftProductsResult?.find(
554
+ (p) => p.handle === giftVariant.handle
555
+ );
556
+ if (productInfo) {
557
+ const variantInfo = productInfo.variants?.find((v) => v.sku === giftVariant.sku);
558
+ if (variantInfo?.availableForSale) {
559
+ selectedGiftProduct = giftVariant;
560
+ break;
561
+ }
562
+ }
563
+ }
564
+ if (!selectedGiftProduct) {
565
+ selectedGiftProduct = reward.variant_list[0];
566
+ }
567
+ return {
568
+ variant: {
569
+ id: shopifyCore.btoaID(selectedGiftProduct.variant_id),
570
+ handle: selectedGiftProduct.handle,
571
+ sku: selectedGiftProduct.sku
572
+ },
573
+ quantity: reward?.get_unit || 1,
574
+ attributes: [
575
+ {
576
+ key: CUSTOMER_ATTRIBUTE_KEY,
577
+ value: JSON.stringify({
578
+ is_gift: true,
579
+ rule_id: activeCampaign.rule_id,
580
+ spend_sum_money: actualThreshold,
581
+ // 使用实际的门槛金额(多币种支持)
582
+ currency_code: currentCurrency
583
+ // 记录当前币种
584
+ })
585
+ }
586
+ ]
587
+ };
588
+ }).filter((item) => item !== null);
589
+ const formattedGift = {
590
+ tier: qualifyingTier,
591
+ itemsToAdd
592
+ };
593
+ return formattedGift;
594
+ }, [qualifyingTier, activeCampaign, finalGiftProductsResult, actualThreshold, currentCurrency]);
548
595
  return {
549
596
  qualifyingGift,
550
597
  nextTierGoal,
@@ -558,7 +605,8 @@ var useScriptAutoFreeGift = ({
558
605
  _giveaway,
559
606
  cart,
560
607
  locale: providedLocale,
561
- lines
608
+ lines,
609
+ profile
562
610
  }) => {
563
611
  const { client, locale: contextLocale } = useShopify();
564
612
  const locale = providedLocale || contextLocale;
@@ -582,8 +630,9 @@ var useScriptAutoFreeGift = ({
582
630
  const utmCampaign = Cookies5__default.default.get("utm_campaign") || query?.utm_campaign;
583
631
  if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
584
632
  return false;
633
+ if (campaign.requireLogin && !profile?.email) return false;
585
634
  return true;
586
- }, [campaign]);
635
+ }, [campaign, profile]);
587
636
  const [upgrade_multiple, upgrade_value] = react.useMemo(() => {
588
637
  let upgrade_multiple2 = 1;
589
638
  let upgrade_value2 = 0;
@@ -591,12 +640,14 @@ var useScriptAutoFreeGift = ({
591
640
  upgrade_multiple2 = 1.2;
592
641
  upgrade_value2 = 40;
593
642
  }
594
- effectiveCart?.lineItems?.forEach(({ customAttributes }) => {
595
- customAttributes?.forEach(({ key, value }) => {
596
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
597
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
598
- });
599
- });
643
+ effectiveCart?.lineItems?.forEach(
644
+ ({ customAttributes }) => {
645
+ customAttributes?.forEach(({ key, value }) => {
646
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
647
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
648
+ });
649
+ }
650
+ );
600
651
  return [upgrade_multiple2, upgrade_value2];
601
652
  }, [effectiveCart?.lineItems, points_subscribe]);
602
653
  const breakpoints = react.useMemo(() => {
@@ -661,18 +712,24 @@ var useScriptAutoFreeGift = ({
661
712
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
662
713
  return [currentLevel, nextLevel];
663
714
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
664
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
665
- const res = await shopifySdk.getProductsByHandles(client, {
666
- handles: giftHandles,
667
- locale
668
- });
669
- const result = Array.isArray(res) ? res : [];
670
- giftProductsCache.current = {
671
- data: result,
672
- giftHandles: [...giftHandles]
673
- };
674
- return result;
675
- });
715
+ const { data: giftProductsResult } = useSWR__default.default(
716
+ shouldFetch ? giftHandles : null,
717
+ async () => {
718
+ const res = await shopifySdk.getProductsByHandles(client, {
719
+ handles: giftHandles,
720
+ locale
721
+ });
722
+ const result = Array.isArray(res) ? res : [];
723
+ giftProductsCache.current = {
724
+ data: result,
725
+ giftHandles: [...giftHandles]
726
+ };
727
+ return result;
728
+ },
729
+ {
730
+ revalidateOnFocus: false
731
+ }
732
+ );
676
733
  const finalGiftProductsResult = react.useMemo(() => {
677
734
  if (giftProductsCache.current && !shouldFetch) {
678
735
  return giftProductsCache.current.data || void 0;
@@ -704,7 +761,20 @@ var useScriptAutoFreeGift = ({
704
761
  giftProductsResult: finalGiftProductsResult
705
762
  };
706
763
  };
707
- function useCreateCart(options) {
764
+
765
+ // src/hooks/cart/utils/cart-attributes.ts
766
+ var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
767
+ return newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || oldAttributes.some((attr) => {
768
+ const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
769
+ return newAttr ? newAttr.value !== attr.value : true;
770
+ }) || customAttributesNeedRemove.some(
771
+ (removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
772
+ );
773
+ };
774
+ function useCreateCart({
775
+ updateCookie = false,
776
+ options
777
+ }) {
708
778
  const { client, locale, cartCookieAdapter } = useShopify();
709
779
  const { mutateCart, metafieldIdentifiers } = useCartContext();
710
780
  const createNewCart = react.useCallback(
@@ -712,7 +782,8 @@ function useCreateCart(options) {
712
782
  let newCart = await shopifySdk.createCart(client, {
713
783
  ...arg,
714
784
  metafieldIdentifiers,
715
- cookieAdapter: cartCookieAdapter
785
+ cookieAdapter: cartCookieAdapter,
786
+ updateCookie
716
787
  });
717
788
  if (newCart) {
718
789
  const unApplicableCodes = newCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
@@ -739,11 +810,23 @@ function useAddCartLines(options) {
739
810
  const { mutateCart, metafieldIdentifiers } = useCartContext();
740
811
  const addLines = react.useCallback(
741
812
  async (_key, { arg }) => {
742
- let updatedCart = await shopifySdk.addCartLines(client, {
743
- ...arg,
744
- metafieldIdentifiers,
745
- cookieAdapter: cartCookieAdapter
746
- });
813
+ const { cartId, lines } = arg;
814
+ const id = cartId || cartCookieAdapter?.getCartId(locale);
815
+ let updatedCart;
816
+ if (!id) {
817
+ updatedCart = await shopifySdk.createCart(client, {
818
+ lines,
819
+ metafieldIdentifiers,
820
+ cookieAdapter: cartCookieAdapter
821
+ });
822
+ } else {
823
+ updatedCart = await shopifySdk.addCartLines(client, {
824
+ cartId: id,
825
+ lines,
826
+ metafieldIdentifiers,
827
+ cookieAdapter: cartCookieAdapter
828
+ });
829
+ }
747
830
  if (updatedCart) {
748
831
  const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
749
832
  if (unApplicableCodes.length > 0) {
@@ -790,7 +873,7 @@ var trackAddToCartGA = ({
790
873
  const currencyCode = variant.product?.price?.currencyCode;
791
874
  const totalPrice = lineItems?.reduce(
792
875
  (prev, { variant: variant2 }) => prev.plus(
793
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
876
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
794
877
  ),
795
878
  new Decimal2__default.default(0)
796
879
  ).toNumber();
@@ -825,7 +908,7 @@ var trackBeginCheckoutGA = ({
825
908
  }
826
909
  const totalPrice = lineItems?.reduce(
827
910
  (prev, { variant }) => prev.plus(
828
- variant?.finalPrice?.amount ?? variant?.compareAtPrice?.amount ?? variant?.price?.amount ?? 0
911
+ variant?.finalPrice?.amount === void 0 ? Number(variant?.price?.amount) || 0 : Number(variant?.finalPrice?.amount) || 0
829
912
  ),
830
913
  new Decimal2__default.default(0)
831
914
  ).toNumber();
@@ -858,10 +941,10 @@ var trackBuyNowGA = ({
858
941
  return;
859
942
  }
860
943
  const { variant } = lineItems[0];
861
- const currencyCode = variant.price?.currencyCode;
944
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
862
945
  const totalPrice = lineItems?.reduce(
863
946
  (prev, { variant: variant2 }) => prev.plus(
864
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
947
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
865
948
  ),
866
949
  new Decimal2__default.default(0)
867
950
  ).toNumber();
@@ -935,7 +1018,7 @@ function useApplyCartCodes(options) {
935
1018
  if (!discountCodes?.length) {
936
1019
  throw new Error("Invalid input used for this operation: Miss discountCode");
937
1020
  }
938
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1021
+ const cartId = providedCartId || cart?.id;
939
1022
  if (!cartId) {
940
1023
  return void 0;
941
1024
  }
@@ -948,12 +1031,18 @@ function useApplyCartCodes(options) {
948
1031
  cookieAdapter: cartCookieAdapter,
949
1032
  metafieldIdentifiers
950
1033
  });
1034
+ const unApplicableCodes = discountCodes.filter(
1035
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
1036
+ );
1037
+ if (unApplicableCodes.length) {
1038
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
1039
+ }
951
1040
  if (updatedCart) {
952
1041
  mutateCart(updatedCart);
953
1042
  }
954
1043
  return updatedCart;
955
1044
  },
956
- [client, locale, cartCookieAdapter, mutateCart, cart]
1045
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
957
1046
  );
958
1047
  return useSWRMutation__default.default("apply-codes", applyCodes, options);
959
1048
  }
@@ -963,7 +1052,7 @@ function useRemoveCartCodes(options) {
963
1052
  const removeCodes = react.useCallback(
964
1053
  async (_key, { arg }) => {
965
1054
  const { cartId: providedCartId, discountCodes } = arg;
966
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1055
+ const cartId = providedCartId || cart?.id;
967
1056
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
968
1057
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
969
1058
  const updatedCart = await shopifySdk.updateCartCodes(client, {
@@ -977,225 +1066,96 @@ function useRemoveCartCodes(options) {
977
1066
  }
978
1067
  return updatedCart;
979
1068
  },
980
- [client, locale, cartCookieAdapter, mutateCart, cart]
1069
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
981
1070
  );
982
1071
  return useSWRMutation__default.default("remove-codes", removeCodes, options);
983
1072
  }
984
-
985
- // src/hooks/cart/use-add-to-cart.ts
986
- function useAddToCart({ withTrack = true } = {}, swrOptions) {
987
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
988
- const { cart } = useCartContext();
989
- const { trigger: applyCartCodes } = useApplyCartCodes();
990
- const { trigger: removeInvalidCodes } = useRemoveCartCodes();
991
- const { trigger: addCartLines2 } = useAddCartLines();
992
- const addToCart = react.useCallback(
993
- async (_key, { arg }) => {
994
- const {
995
- lineItems,
996
- cartId: providedCartId,
997
- discountCodes,
998
- gtmParams = {},
999
- buyerIdentity,
1000
- needCreateCart = false,
1001
- onCodesInvalid,
1002
- replaceExistingCodes
1003
- } = arg;
1004
- if (!lineItems || lineItems.length === 0) {
1005
- return;
1006
- }
1007
- const lines = lineItems.map((item) => ({
1008
- merchandiseId: item.variant?.id || "",
1009
- quantity: item.quantity || 1,
1010
- attributes: item.attributes,
1011
- sellingPlanId: item.sellingPlanId
1012
- })).filter((item) => item.merchandiseId && item.quantity);
1013
- if (lines.length === 0) {
1014
- return;
1015
- }
1016
- const cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
1017
- let resultCart = await addCartLines2({
1018
- cartId,
1019
- lines,
1020
- buyerIdentity
1021
- });
1022
- if (!resultCart) {
1023
- return void 0;
1024
- }
1025
- console.log("npm addCartLines resultCart", resultCart);
1026
- if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
1027
- const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1028
- if (unapplicableCodes.length > 0) {
1029
- if (onCodesInvalid) {
1030
- const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
1031
- if (handledCart) {
1032
- resultCart = handledCart;
1033
- }
1034
- } else {
1035
- await removeInvalidCodes({
1036
- discountCodes: unapplicableCodes
1037
- });
1038
- }
1039
- }
1040
- }
1041
- if (discountCodes && discountCodes.length > 0) {
1042
- applyCartCodes({
1043
- replaceExistingCodes,
1044
- discountCodes
1045
- });
1046
- }
1047
- if (withTrack) {
1048
- trackAddToCartGA({
1049
- lineItems,
1050
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1051
- });
1052
- trackAddToCartFBQ({ lineItems });
1053
- }
1054
- return resultCart;
1055
- },
1056
- [client, locale, cartCookieAdapter, userAdapter, cart, withTrack]
1073
+ var initSameLinesAttributes = ({
1074
+ cart,
1075
+ line
1076
+ }) => {
1077
+ const sameLineInCart = cart?.lineItems.find(
1078
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
1057
1079
  );
1058
- return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
1059
- }
1060
- function useUpdateCartLines(options) {
1061
- const { client, locale, cartCookieAdapter } = useShopify();
1062
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1063
- const updateLines = react.useCallback(
1064
- async (_key, { arg }) => {
1065
- const updatedCart = await shopifySdk.updateCartLines(client, {
1066
- ...arg,
1067
- metafieldIdentifiers,
1068
- cookieAdapter: cartCookieAdapter
1069
- });
1070
- if (updatedCart) {
1071
- mutateCart(updatedCart);
1072
- }
1073
- return updatedCart;
1074
- },
1075
- [client, locale, cartCookieAdapter, mutateCart]
1080
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
1081
+ (attr) => attr.key === CODE_AMOUNT_KEY
1076
1082
  );
1077
- return useSWRMutation__default.default("update-cart-lines", updateLines, options);
1078
- }
1079
- function useRemoveCartLines(options) {
1080
- const { client, locale, cartCookieAdapter } = useShopify();
1081
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1082
- const removeLines = react.useCallback(
1083
- async (_key, { arg }) => {
1084
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1085
- let updatedCart = await shopifySdk.removeCartLines(client, {
1086
- cartId,
1087
- lineIds,
1088
- metafieldIdentifiers,
1089
- cookieAdapter: cartCookieAdapter
1090
- });
1091
- if (updatedCart && autoRemoveInvalidCodes) {
1092
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1093
- if (unApplicableCodes.length > 0) {
1094
- if (onCodesRemoved) {
1095
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1096
- if (handledCart) {
1097
- updatedCart = handledCart;
1098
- }
1099
- } else {
1100
- updatedCart = await shopifySdk.updateCartCodes(client, {
1101
- cartId: updatedCart.id,
1102
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1103
- metafieldIdentifiers,
1104
- cookieAdapter: cartCookieAdapter
1105
- }) || updatedCart;
1106
- }
1107
- }
1108
- }
1109
- if (updatedCart) {
1110
- mutateCart(updatedCart);
1083
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
1084
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
1085
+ );
1086
+ let functionAttribute = null;
1087
+ try {
1088
+ functionAttribute = sameLineInCart?.customAttributes?.find(
1089
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
1090
+ );
1091
+ } catch (error) {
1092
+ }
1093
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
1094
+ return {
1095
+ ...line,
1096
+ attributes: [
1097
+ ...line.attributes || [],
1098
+ codeAmountAttribute,
1099
+ functionAttribute,
1100
+ scriptCodeAmountAttribute
1101
+ ].filter(Boolean)
1102
+ };
1103
+ }
1104
+ return line;
1105
+ };
1106
+ var initDiscountAttributes = ({ line }) => {
1107
+ let itemAttributes = line.attributes || [];
1108
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
1109
+ if (!functionEnvAttribute) {
1110
+ itemAttributes = itemAttributes.concat([
1111
+ {
1112
+ key: CUSTOMER_ATTRIBUTE_KEY,
1113
+ value: JSON.stringify({
1114
+ is_gift: false,
1115
+ discounted_amount: line.variant?.finalPrice?.amount === void 0 ? Number(line.variant?.price?.amount) * (line.quantity || 1) : Number(line.variant?.finalPrice?.amount) * (line.quantity || 1)
1116
+ })
1111
1117
  }
1112
- return updatedCart;
1113
- },
1114
- [client, locale, cartCookieAdapter, mutateCart]
1118
+ ]);
1119
+ }
1120
+ const memberPriceAttribute = itemAttributes.find(
1121
+ (attr) => attr.key === MEMBER_PRICE_ATTRIBUTE_KEY
1115
1122
  );
1116
- return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1117
- }
1118
- function useUpdateCartAttributes(mutate, metafieldIdentifiers, options) {
1119
- const { client, locale, cartCookieAdapter } = useShopify();
1120
- const updateAttributes = react.useCallback(
1121
- async (_key, { arg }) => {
1122
- const updatedCart = await shopifySdk.updateCartAttributes(client, {
1123
- ...arg,
1124
- metafieldIdentifiers,
1125
- cookieAdapter: cartCookieAdapter
1126
- });
1127
- console.log("useUpdateCartAttributes updatedCart", updatedCart);
1128
- if (updatedCart) {
1129
- mutate(updatedCart);
1123
+ const coupon = line.coupon;
1124
+ if (!memberPriceAttribute && coupon) {
1125
+ itemAttributes = itemAttributes.concat([
1126
+ {
1127
+ key: MEMBER_PRICE_ATTRIBUTE_KEY,
1128
+ value: JSON.stringify({ code: coupon.code })
1130
1129
  }
1131
- return updatedCart;
1132
- },
1133
- [client, locale, cartCookieAdapter, mutate]
1130
+ ]);
1131
+ }
1132
+ const couponDiscountAttribute = itemAttributes.find(
1133
+ (attr) => attr.key === CODE_AMOUNT_KEY || attr.key === SCRIPT_CODE_AMOUNT_KEY
1134
1134
  );
1135
- return useSWRMutation__default.default("update-cart-attributes", updateAttributes, options);
1136
- }
1137
- function useBuyNow({ withTrack = true } = {}, swrOptions) {
1138
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
1139
- const isLoggedIn = userAdapter?.isLoggedIn || false;
1140
- const buyNow = react.useCallback(
1141
- async (_key, { arg }) => {
1142
- const {
1143
- lineItems,
1144
- discountCodes,
1145
- gtmParams = {},
1146
- buyerIdentity,
1147
- fbqTrackConfig,
1148
- customAttributes,
1149
- metafieldIdentifiers,
1150
- redirectToCheckout
1151
- } = arg;
1152
- if (!lineItems || lineItems.length === 0) {
1153
- return;
1154
- }
1155
- const lines = lineItems.map((item) => ({
1156
- merchandiseId: item.variant?.id || "",
1157
- quantity: item.quantity || 1,
1158
- attributes: item.attributes,
1159
- sellingPlanId: item.sellingPlanId
1160
- })).filter((item) => item.merchandiseId && item.quantity);
1161
- if (lines.length === 0) {
1162
- return;
1163
- }
1164
- const resultCart = await shopifySdk.createCart(client, {
1165
- lines,
1166
- metafieldIdentifiers,
1167
- cookieAdapter: cartCookieAdapter,
1168
- buyerIdentity,
1169
- discountCodes,
1170
- customAttributes
1171
- });
1172
- if (!resultCart) {
1173
- throw new Error("Failed to create cart for buy now");
1174
- }
1175
- if (withTrack && resultCart.lineItems) {
1176
- trackBuyNowGA({
1177
- lineItems,
1178
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1179
- });
1180
- if (fbqTrackConfig) {
1181
- trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
1182
- }
1183
- }
1184
- if (redirectToCheckout) {
1185
- if (resultCart.url) {
1186
- if (typeof window !== "undefined") {
1187
- window.location.href = resultCart.url;
1188
- }
1189
- } else {
1190
- throw new Error("Failed to get checkout URL");
1191
- }
1135
+ if (!couponDiscountAttribute && coupon && Number(coupon?.amount) > 0) {
1136
+ itemAttributes = itemAttributes.concat([
1137
+ {
1138
+ key: CODE_AMOUNT_KEY,
1139
+ value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
1140
+ },
1141
+ {
1142
+ key: SCRIPT_CODE_AMOUNT_KEY,
1143
+ value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
1192
1144
  }
1193
- return resultCart;
1194
- },
1195
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
1196
- );
1197
- return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
1198
- }
1145
+ ]);
1146
+ }
1147
+ return { ...line, attributes: itemAttributes };
1148
+ };
1149
+ var getLinesWithAttributes = ({
1150
+ cart,
1151
+ lineItems
1152
+ }) => {
1153
+ return lineItems.map((line) => {
1154
+ const sameLine = initSameLinesAttributes({ cart, line });
1155
+ const functionLine = initDiscountAttributes({ line: sameLine });
1156
+ return functionLine;
1157
+ });
1158
+ };
1199
1159
  function useCalcGiftsFromLines({
1200
1160
  lines,
1201
1161
  customer,
@@ -1212,17 +1172,41 @@ function useCalcGiftsFromLines({
1212
1172
  lines
1213
1173
  });
1214
1174
  const allGiftLines = react.useMemo(() => {
1215
- const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || [];
1216
- const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((product) => {
1217
- const giftProduct = scriptGift.giftProductsResult?.find(
1218
- (p) => p.handle === product.handle
1175
+ const functionGiftLines = (functionGift.qualifyingGift?.itemsToAdd || []).map((item) => {
1176
+ const product = functionGift.giftProductsResult?.find(
1177
+ (product2) => product2.handle === item.variant.handle
1178
+ );
1179
+ const variants = product?.variants;
1180
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.variant.sku) : void 0;
1181
+ if (!variant) {
1182
+ console.warn(
1183
+ `Function gift: Variant not found for handle=${item.variant.handle}, sku=${item.variant.sku}`
1184
+ );
1185
+ return null;
1186
+ }
1187
+ return {
1188
+ variant: {
1189
+ ...variant,
1190
+ product
1191
+ },
1192
+ quantity: item.quantity ?? 1,
1193
+ attributes: item.attributes
1194
+ };
1195
+ }).filter((item) => item !== null);
1196
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((item) => {
1197
+ const product = scriptGift.giftProductsResult?.find(
1198
+ (product2) => product2.handle === item.handle
1219
1199
  );
1220
- const variant = giftProduct?.variants?.[0];
1200
+ const variants = product?.variants;
1201
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1202
+ if (!variant) {
1203
+ console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1204
+ return null;
1205
+ }
1221
1206
  return {
1222
1207
  variant: {
1223
- id: variant?.id || "",
1224
- handle: product.handle,
1225
- sku: product.sku
1208
+ ...variant,
1209
+ product
1226
1210
  },
1227
1211
  quantity: 1,
1228
1212
  attributes: [
@@ -1232,10 +1216,11 @@ function useCalcGiftsFromLines({
1232
1216
  }
1233
1217
  ]
1234
1218
  };
1235
- }).filter((item) => item.variant.id) : [];
1219
+ }).filter((item) => item !== null) : [];
1236
1220
  return [...functionGiftLines, ...scriptGiftLines];
1237
1221
  }, [
1238
1222
  functionGift.qualifyingGift,
1223
+ functionGift.giftProductsResult,
1239
1224
  scriptGift.freeGiftLevel,
1240
1225
  scriptGift.giftProductsResult,
1241
1226
  scriptGiveawayKey
@@ -1270,7 +1255,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1270
1255
  const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
1271
1256
  const dealsType = "";
1272
1257
  const { activeCampaign, subtotal } = react.useMemo(() => {
1273
- for (const campaign of orderDiscountConfig) {
1258
+ for (const campaign of orderDiscountConfig || []) {
1274
1259
  const { rule_conditions = [], result_detail } = campaign;
1275
1260
  const { main_product, order_discount_conf } = result_detail || {};
1276
1261
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
@@ -1300,9 +1285,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1300
1285
  discountAmount: 0
1301
1286
  };
1302
1287
  }
1303
- const tieredDiscounts = activeCampaign.result_detail.order_discount_conf.tiered_discounts;
1304
- const qualifyingTier = [...tieredDiscounts].reverse().find((tier) => subtotal >= Number(tier.amount));
1305
- const nextGoal = tieredDiscounts.find((tier) => subtotal < Number(tier.amount));
1288
+ const currentCurrency = cart?.currency?.code || "";
1289
+ console.log("currentCurrency", cart, currentCurrency);
1290
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1291
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1292
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1293
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1306
1294
  if (!qualifyingTier) {
1307
1295
  return {
1308
1296
  qualifyingDiscount: null,
@@ -1339,43 +1327,10 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1339
1327
  isLoading: isCustomerLoading
1340
1328
  };
1341
1329
  };
1342
- function useHasPlusMemberInCart({
1343
- memberSetting,
1344
- cart
1345
- }) {
1346
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1347
- return react.useMemo(() => {
1348
- if (!cart?.lineItems) {
1349
- return {
1350
- hasPlusMember: false,
1351
- hasMonthlyPlus: false,
1352
- hasAnnualPlus: false
1353
- };
1354
- }
1355
- const monthlyPlusItem = cart.lineItems.find(
1356
- (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1357
- );
1358
- const annualPlusItem = cart.lineItems.find(
1359
- (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1360
- );
1361
- const hasMonthlyPlus = !!monthlyPlusItem;
1362
- const hasAnnualPlus = !!annualPlusItem;
1363
- const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1364
- return {
1365
- hasPlusMember,
1366
- hasMonthlyPlus,
1367
- hasAnnualPlus,
1368
- monthlyPlusItem,
1369
- annualPlusItem
1370
- };
1371
- }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1372
- }
1373
-
1374
- // src/hooks/cart/feature/use-cart-attributes.ts
1375
1330
  var getReferralAttributes = () => {
1376
- const inviteCode = Cookies5__default.default.get("invite_code");
1377
- const playModeId = Cookies5__default.default.get("playModeId");
1378
- const popup = Cookies5__default.default.get("_popup");
1331
+ const inviteCode = shopifySdk.getLocalStorage("inviteCode") || Cookies5__default.default.get("inviteCode");
1332
+ const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
1333
+ const popup = shopifySdk.getLocalStorage("_popup") || Cookies5__default.default.get("_popup");
1379
1334
  if (inviteCode && playModeId) {
1380
1335
  return popup ? [
1381
1336
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1388,117 +1343,130 @@ var getReferralAttributes = () => {
1388
1343
  }
1389
1344
  return [];
1390
1345
  };
1346
+ var getUserType = (customer) => {
1347
+ let userInfo = Cookies5__default.default.get("userInfo");
1348
+ if (userInfo) {
1349
+ userInfo = JSON.parse(userInfo);
1350
+ let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1351
+ userInfo.setId = arr[arr.length - 1];
1352
+ }
1353
+ const customerInfo = userInfo || customer;
1354
+ if (!customerInfo) {
1355
+ return "new_user_unlogin";
1356
+ }
1357
+ if (customer) {
1358
+ const { orders = {} } = customer;
1359
+ if (orders?.edges?.length === 1) {
1360
+ return "old_user_orders_once";
1361
+ } else if (orders?.edges?.length > 1) {
1362
+ return "old_user_orders_twice";
1363
+ }
1364
+ }
1365
+ return "new_user_login";
1366
+ };
1367
+ function getCartAttributes({
1368
+ profile,
1369
+ customer,
1370
+ cart,
1371
+ memberType,
1372
+ currentUrl = ""
1373
+ }) {
1374
+ const userType = getUserType(customer);
1375
+ const memberAttributes = [
1376
+ {
1377
+ key: "_token",
1378
+ value: profile?.token
1379
+ },
1380
+ {
1381
+ key: "_member_type",
1382
+ value: memberType ?? String(profile?.memberType)
1383
+ },
1384
+ {
1385
+ key: "_user_type",
1386
+ value: userType
1387
+ },
1388
+ {
1389
+ key: "_is_login",
1390
+ value: profile?.token ? "true" : "false"
1391
+ }
1392
+ ];
1393
+ if (profile?.token) {
1394
+ memberAttributes.push({
1395
+ key: "_login_user",
1396
+ value: "1"
1397
+ });
1398
+ }
1399
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1400
+ const functionAttributes = [
1401
+ {
1402
+ key: CUSTOMER_ATTRIBUTE_KEY,
1403
+ value: JSON.stringify({
1404
+ discount_code: discountCodes,
1405
+ user_tags: customer?.tags || []
1406
+ })
1407
+ }
1408
+ ];
1409
+ const presellAttributes = [
1410
+ {
1411
+ key: "_presale",
1412
+ value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1413
+ }
1414
+ ];
1415
+ const weightAttributes = [
1416
+ {
1417
+ key: "_weight",
1418
+ value: cart?.lineItems.reduce((acc, item) => {
1419
+ return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1420
+ }, 0).toString()
1421
+ },
1422
+ {
1423
+ key: "_app_source_name",
1424
+ value: "dtc"
1425
+ }
1426
+ ];
1427
+ const trackingAttributes = [
1428
+ {
1429
+ key: "utm_params",
1430
+ value: currentUrl
1431
+ }
1432
+ ];
1433
+ const commonAttributes = [
1434
+ ...memberAttributes,
1435
+ ...functionAttributes,
1436
+ ...presellAttributes,
1437
+ ...weightAttributes,
1438
+ ...trackingAttributes,
1439
+ ...getReferralAttributes()
1440
+ ].filter((item) => item?.value);
1441
+ const extraAttributesInCart = cart?.customAttributes?.filter(
1442
+ (item) => !commonAttributes.some((attr) => attr.key === item.key)
1443
+ ) || [];
1444
+ return [...commonAttributes, ...extraAttributesInCart].filter((item) => item?.value);
1445
+ }
1391
1446
  var useCartAttributes = ({
1392
1447
  profile,
1393
1448
  customer,
1394
1449
  cart,
1395
- memberSetting
1450
+ memberType
1396
1451
  }) => {
1397
1452
  const [currentUrl, setCurrentUrl] = react.useState("");
1398
- const { hasPlusMember } = useHasPlusMemberInCart({
1399
- memberSetting,
1400
- cart
1401
- });
1402
1453
  react.useEffect(() => {
1403
1454
  setCurrentUrl(window.location.href);
1404
1455
  }, []);
1405
- const userType = react.useMemo(() => {
1406
- let userInfo = Cookies5__default.default.get("userInfo");
1407
- if (userInfo) {
1408
- userInfo = JSON.parse(userInfo);
1409
- let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1410
- userInfo.setId = arr[arr.length - 1];
1411
- }
1412
- const customerInfo = userInfo || customer;
1413
- if (!customerInfo) {
1414
- return "new_user_unlogin";
1415
- }
1416
- if (customer) {
1417
- const { orders = {} } = customer;
1418
- if (orders?.edges?.length === 1) {
1419
- return "old_user_orders_once";
1420
- } else if (orders?.edges?.length > 1) {
1421
- return "old_user_orders_twice";
1422
- }
1423
- }
1424
- return "new_user_login";
1425
- }, [customer]);
1426
- const memberAttributes = react.useMemo(() => {
1427
- return [
1428
- {
1429
- key: "_token",
1430
- value: profile?.token
1431
- //是否登录
1432
- },
1433
- {
1434
- key: "_member_type",
1435
- value: hasPlusMember ? "2" : profile?.memberType
1436
- //:0(游客),1(普通会员),2(付费会员)
1437
- },
1438
- {
1439
- key: "_user_type",
1440
- value: userType
1441
- // n
1442
- },
1443
- {
1444
- key: "_is_login",
1445
- value: profile?.token ? "true" : "false"
1446
- }
1447
- ];
1448
- }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1449
- const functionAttributes = react.useMemo(() => {
1450
- return [
1451
- cart?.discountCodes && {
1452
- key: "_discounts_function_env",
1453
- value: JSON.stringify({
1454
- discount_code: cart?.discountCodes.map((item) => item.code),
1455
- user_tags: customer?.tags || []
1456
- })
1457
- }
1458
- ];
1459
- }, [cart]);
1460
- const presellAttributes = react.useMemo(() => {
1461
- return [
1462
- {
1463
- key: "_presale",
1464
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1465
- }
1466
- ];
1467
- }, [cart]);
1468
- const weightAttributes = react.useMemo(() => {
1469
- return [
1470
- {
1471
- key: "_weight",
1472
- value: cart?.lineItems.reduce((acc, item) => {
1473
- return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1474
- }, 0).toString()
1475
- },
1476
- {
1477
- key: "_app_source_name",
1478
- value: "dtc"
1479
- }
1480
- ];
1481
- }, [cart]);
1482
- const trackingAttributes = react.useMemo(() => {
1483
- return [
1484
- {
1485
- key: "utm_params",
1486
- value: currentUrl
1487
- }
1488
- ];
1489
- }, [currentUrl]);
1456
+ const attributes = react.useMemo(() => {
1457
+ return getCartAttributes({
1458
+ profile,
1459
+ customer,
1460
+ cart,
1461
+ memberType,
1462
+ currentUrl
1463
+ });
1464
+ }, [profile, customer, cart, memberType, currentUrl]);
1490
1465
  return react.useMemo(
1491
1466
  () => ({
1492
- attributes: [
1493
- ...memberAttributes,
1494
- ...functionAttributes,
1495
- ...presellAttributes,
1496
- ...weightAttributes,
1497
- ...trackingAttributes,
1498
- ...getReferralAttributes()
1499
- ].filter((item) => item?.value)
1467
+ attributes
1500
1468
  }),
1501
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1469
+ [attributes]
1502
1470
  );
1503
1471
  };
1504
1472
  var DEFAULT_MIN = 1;
@@ -1561,7 +1529,7 @@ var useUpdateLineCodeAmountAttributes = ({
1561
1529
  );
1562
1530
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1563
1531
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1564
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1532
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1565
1533
  attrNeedUpdate.push({
1566
1534
  key: CUSTOMER_ATTRIBUTE_KEY,
1567
1535
  value: JSON.stringify({
@@ -1600,29 +1568,22 @@ var useUpdateLineCodeAmountAttributes = ({
1600
1568
  }).filter(
1601
1569
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1602
1570
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1571
+ let lineId = line.id;
1572
+ let attributes = line.customAttributes || [];
1573
+ if (attrNeedDelete.length) {
1574
+ attributes = attributes.filter(
1575
+ (attr) => !attrNeedDelete.includes(attr.key)
1576
+ );
1577
+ }
1603
1578
  if (attrNeedUpdate.length) {
1604
- return {
1605
- id: line.id,
1606
- attributes: [
1607
- ...line.customAttributes?.filter(
1608
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1609
- ) || [],
1610
- ...attrNeedUpdate
1611
- ]
1612
- };
1613
- } else if (attrNeedDelete.length) {
1614
- return {
1615
- id: line.id,
1616
- attributes: line.customAttributes?.filter(
1617
- (attr) => !attrNeedDelete.includes(attr.key)
1618
- ) || []
1619
- };
1620
- } else {
1621
- return {
1622
- id: line.id,
1623
- attributes: line.customAttributes || []
1624
- };
1579
+ attributes = attributes.filter(
1580
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1581
+ ).concat(attrNeedUpdate);
1625
1582
  }
1583
+ return {
1584
+ id: lineId,
1585
+ attributes
1586
+ };
1626
1587
  }),
1627
1588
  [cart?.lineItems, mainProductDiscountCodes]
1628
1589
  );
@@ -1657,45 +1618,61 @@ var useUpdateLineCodeAmountAttributes = ({
1657
1618
  }, [loading, setLoadingState]);
1658
1619
  };
1659
1620
 
1660
- // src/hooks/cart/types/price-discount.ts
1661
- var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
1662
- PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1663
- PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1664
- return PriceDiscountType2;
1665
- })(PriceDiscountType || {});
1666
- var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
1667
- PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
1668
- PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
1669
- return PriceBasePriceType2;
1670
- })(PriceBasePriceType || {});
1671
- function useProduct(options = {}) {
1672
- const { client, locale } = useShopify();
1673
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
1674
- return useSWR__default.default(
1675
- handle ? ["product", locale, handle, metafieldIdentifiers] : null,
1676
- () => shopifySdk.getProduct(client, {
1677
- handle,
1678
- locale,
1679
- metafieldIdentifiers
1680
- }),
1681
- swrOptions
1682
- );
1683
- }
1684
- function useAllProducts(options = {}) {
1685
- const { client, locale } = useShopify();
1686
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
1687
- return useSWR__default.default(
1688
- ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
1689
- () => shopifySdk.getAllProducts(client, {
1690
- locale,
1691
- first,
1692
- query,
1693
- sortKey,
1694
- reverse,
1695
- metafieldIdentifiers
1696
- }),
1697
- swrOptions
1698
- );
1621
+ // src/hooks/member/plus/types.ts
1622
+ var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
1623
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
1624
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
1625
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
1626
+ return PLUS_MEMBER_TYPE2;
1627
+ })(PLUS_MEMBER_TYPE || {});
1628
+ var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
1629
+ PlusMemberMode2["MONTHLY"] = "monthly";
1630
+ PlusMemberMode2["ANNUAL"] = "annual";
1631
+ return PlusMemberMode2;
1632
+ })(PlusMemberMode || {});
1633
+ var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
1634
+ DeliveryPlusType2["FREE"] = "free";
1635
+ DeliveryPlusType2["MONTHLY"] = "monthly";
1636
+ DeliveryPlusType2["ANNUAL"] = "annual";
1637
+ return DeliveryPlusType2;
1638
+ })(DeliveryPlusType || {});
1639
+ var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
1640
+ ShippingMethodMode2["FREE"] = "free";
1641
+ ShippingMethodMode2["TDD"] = "tdd";
1642
+ ShippingMethodMode2["NDD"] = "ndd";
1643
+ return ShippingMethodMode2;
1644
+ })(ShippingMethodMode || {});
1645
+ var createInitialValue = () => ({
1646
+ plusMemberMetafields: {},
1647
+ selectedPlusMemberMode: "free",
1648
+ setSelectedPlusMemberMode: () => {
1649
+ },
1650
+ selectedShippingMethod: void 0,
1651
+ setSelectedShippingMethod: () => {
1652
+ },
1653
+ showMoreShippingMethod: false,
1654
+ setShowMoreShippingMethod: () => {
1655
+ },
1656
+ variant: {},
1657
+ product: {},
1658
+ shippingMethodsContext: {
1659
+ freeShippingMethods: [],
1660
+ paymentShippingMethods: [],
1661
+ nddOverweight: false,
1662
+ tddOverweight: false,
1663
+ nddCoupon: void 0,
1664
+ tddCoupon: void 0,
1665
+ isLoadingCoupon: false
1666
+ },
1667
+ selectedPlusMemberVariant: void 0,
1668
+ showPlusMemberBenefit: false,
1669
+ setShowPlusMemberBenefit: () => {
1670
+ },
1671
+ profile: void 0
1672
+ });
1673
+ var PlusMemberContext = react.createContext(createInitialValue());
1674
+ function usePlusMemberContext() {
1675
+ return react.useContext(PlusMemberContext);
1699
1676
  }
1700
1677
  function useProductsByHandles(options = {}) {
1701
1678
  const { client, locale } = useShopify();
@@ -1715,1152 +1692,1349 @@ function useProductsByHandles(options = {}) {
1715
1692
  metafieldIdentifiers
1716
1693
  });
1717
1694
  },
1718
- swrOptions || {
1719
- revalidateOnFocus: false
1695
+ {
1696
+ revalidateOnFocus: false,
1697
+ ...swrOptions
1720
1698
  }
1721
1699
  );
1722
1700
  }
1723
- function getFirstAvailableVariant(product) {
1724
- const availableVariant = product.variants.find((v) => v.availableForSale);
1725
- return availableVariant || product.variants[0];
1726
- }
1727
- function getVariantFromSelectedOptions(product, selectedOptions) {
1728
- return product.variants.find((variant) => {
1729
- return variant.selectedOptions.every((option) => {
1730
- return selectedOptions[option.name] === option.value;
1731
- });
1732
- });
1733
- }
1734
- function useVariant({
1735
- product,
1736
- selectedOptions
1701
+
1702
+ // src/hooks/member/plus/use-plus-member-variants.ts
1703
+ function usePlusMemberVariants({
1704
+ memberSetting
1737
1705
  }) {
1738
- const [variant, setVariant] = react.useState(
1739
- product ? getFirstAvailableVariant(product) : void 0
1740
- );
1741
- react.useEffect(() => {
1742
- if (!product) {
1743
- setVariant(void 0);
1744
- return;
1745
- }
1746
- const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
1747
- if (newVariant && newVariant.id !== variant?.id) {
1748
- setVariant(newVariant);
1749
- } else if (!newVariant) {
1750
- setVariant(getFirstAvailableVariant(product));
1751
- }
1752
- }, [selectedOptions, product, variant?.id]);
1753
- return variant;
1754
- }
1755
- var FAKE_PRICE = 999999999e-2;
1756
- function formatPrice({
1757
- amount,
1758
- currencyCode,
1759
- locale,
1760
- maximumFractionDigits,
1761
- minimumFractionDigits,
1762
- removeTrailingZeros
1763
- }) {
1764
- const formatter = new Intl.NumberFormat(locale, {
1765
- style: "currency",
1766
- currency: currencyCode,
1767
- maximumFractionDigits: maximumFractionDigits ?? 2,
1768
- minimumFractionDigits: minimumFractionDigits ?? 2
1706
+ const plusMonthly = memberSetting?.plus_monthly_product;
1707
+ const plusAnnual = memberSetting?.plus_annual_product;
1708
+ const plusMemberHandles = react.useMemo(() => {
1709
+ return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
1710
+ }, [plusMonthly?.handle, plusAnnual?.handle]);
1711
+ const { data: plusMemberProducts = [] } = useProductsByHandles({
1712
+ handles: plusMemberHandles
1769
1713
  });
1770
- let formatted = formatter.format(amount);
1771
- if (removeTrailingZeros) {
1772
- formatted = formatted.replace(/\.00$/, "");
1773
- }
1774
- return formatted;
1775
- }
1776
- function formatVariantPrice({
1777
- amount,
1778
- baseAmount,
1779
- currencyCode,
1780
- locale,
1781
- maximumFractionDigits,
1782
- minimumFractionDigits,
1783
- removeTrailingZeros
1784
- }) {
1714
+ const monthlyProduct = react.useMemo(() => {
1715
+ return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
1716
+ }, [plusMemberProducts, plusMonthly]);
1717
+ const annualProduct = react.useMemo(() => {
1718
+ return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
1719
+ }, [plusMemberProducts, plusAnnual]);
1720
+ const monthlyVariant = react.useMemo(() => {
1721
+ return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
1722
+ }, [monthlyProduct, plusMonthly]);
1723
+ const annualVariant = react.useMemo(() => {
1724
+ return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
1725
+ }, [annualProduct, plusAnnual]);
1785
1726
  return {
1786
- price: formatPrice({
1787
- amount,
1788
- currencyCode,
1789
- locale,
1790
- maximumFractionDigits,
1791
- minimumFractionDigits,
1792
- removeTrailingZeros
1793
- }),
1794
- basePrice: formatPrice({
1795
- amount: baseAmount,
1796
- currencyCode,
1797
- locale,
1798
- maximumFractionDigits,
1799
- minimumFractionDigits,
1800
- removeTrailingZeros
1801
- })
1727
+ monthlyVariant: monthlyVariant ? {
1728
+ ...monthlyVariant,
1729
+ product: monthlyProduct
1730
+ } : void 0,
1731
+ annualVariant: annualVariant ? {
1732
+ ...annualVariant,
1733
+ product: annualProduct
1734
+ } : void 0
1802
1735
  };
1803
1736
  }
1804
- function usePrice({
1805
- amount,
1806
- baseAmount,
1807
- currencyCode,
1808
- soldOutDescription = "",
1809
- maximumFractionDigits,
1810
- minimumFractionDigits,
1811
- removeTrailingZeros
1812
- }) {
1813
- const { locale } = useShopify();
1814
- const value = react.useMemo(() => {
1815
- if (typeof amount !== "number" || !currencyCode) {
1816
- return "";
1817
- }
1818
- if (soldOutDescription && amount >= FAKE_PRICE) {
1819
- return soldOutDescription;
1737
+ var useAvailableDeliveryCoupon = ({
1738
+ profile
1739
+ }) => {
1740
+ const { data: availableDeliveryCoupon, isLoading } = useSWR__default.default(
1741
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
1742
+ async ([apiPath]) => {
1743
+ return fetch(apiPath).then((res) => res.json());
1820
1744
  }
1821
- return baseAmount ? formatVariantPrice({
1822
- amount,
1823
- baseAmount,
1824
- currencyCode,
1825
- locale,
1826
- maximumFractionDigits,
1827
- minimumFractionDigits,
1828
- removeTrailingZeros
1829
- }) : formatPrice({
1830
- amount,
1831
- currencyCode,
1832
- locale,
1833
- maximumFractionDigits,
1834
- minimumFractionDigits,
1835
- removeTrailingZeros
1745
+ );
1746
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
1747
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
1748
+ return {
1749
+ nddCoupon,
1750
+ tddCoupon,
1751
+ isLoading
1752
+ };
1753
+ };
1754
+
1755
+ // src/hooks/member/plus/use-shipping-methods.ts
1756
+ function useShippingMethods(options) {
1757
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
1758
+ const isPlus = profile?.isPlus || false;
1759
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
1760
+ const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
1761
+ const nddOverweight = react.useMemo(() => {
1762
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
1763
+ }, [shippingMethod?.overWeight_ndd, variant?.weight]);
1764
+ const tddOverweight = react.useMemo(() => {
1765
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
1766
+ }, [shippingMethod?.overWeight_tdd, variant?.weight]);
1767
+ const paymentShippingMethods = react.useMemo(() => {
1768
+ const weight = variant?.weight || 0;
1769
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
1770
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1771
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
1772
+ }) || [];
1773
+ return methods.map((method) => {
1774
+ let disabled = false;
1775
+ const selectedFreeMember = selectedPlusMemberMode === "free";
1776
+ if (method.__mode === "ndd" /* NDD */) {
1777
+ disabled = selectedFreeMember || nddOverweight;
1778
+ } else if (method.__mode === "tdd" /* TDD */) {
1779
+ disabled = selectedFreeMember || tddOverweight;
1780
+ }
1781
+ return {
1782
+ ...method,
1783
+ id: method.__mode + method.__code,
1784
+ useCoupon: false,
1785
+ subtitle: plus_shipping?.directly || "",
1786
+ disabled
1787
+ };
1836
1788
  });
1837
1789
  }, [
1838
- amount,
1839
- baseAmount,
1840
- currencyCode,
1841
- locale,
1842
- maximumFractionDigits,
1843
- minimumFractionDigits,
1844
- soldOutDescription,
1845
- removeTrailingZeros
1790
+ nddOverweight,
1791
+ plus_shipping?.directly,
1792
+ plus_shipping?.shipping_methods,
1793
+ selectedPlusMemberMode,
1794
+ tddOverweight,
1795
+ variant?.weight
1846
1796
  ]);
1847
- const result = react.useMemo(() => {
1848
- const free = Boolean(amount && amount <= 0);
1849
- return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
1850
- }, [value, amount]);
1851
- return result;
1852
- }
1853
- function optionsConstructor(selectedOptions) {
1854
- return selectedOptions.reduce((acc, option) => {
1855
- acc[option.name] = option.value;
1856
- return acc;
1857
- }, {});
1858
- }
1859
- function decodeShopifyId(gid) {
1860
- try {
1861
- const base64 = gid.split("/").pop() || "";
1862
- return atob(base64);
1863
- } catch {
1864
- return gid;
1865
- }
1866
- }
1867
- function useSelectedOptions(product, sku) {
1868
- const [options, setOptions] = react.useState({});
1869
- react.useEffect(() => {
1870
- if (!product || !product.variants.length) {
1871
- setOptions({});
1872
- return;
1873
- }
1874
- let variant = product.variants[0];
1875
- if (typeof window !== "undefined") {
1876
- const searchParams = new URLSearchParams(window.location.search);
1877
- const variantIdParam = searchParams.get("variant");
1878
- if (variantIdParam) {
1879
- const foundVariant = product.variants.find((v) => {
1880
- if (sku) return v.sku === sku;
1881
- return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
1882
- });
1883
- if (foundVariant) {
1884
- variant = foundVariant;
1885
- }
1797
+ const nddPrice = react.useMemo(() => {
1798
+ const weight = variant?.weight || 0;
1799
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1800
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1801
+ return __mode === "ndd" && fitWeight;
1802
+ });
1803
+ return nddMethod?.price || 0;
1804
+ }, [variant?.weight, paymentShippingMethods]);
1805
+ const tddPrice = react.useMemo(() => {
1806
+ const weight = variant?.weight || 0;
1807
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1808
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1809
+ return __mode === "tdd" && fitWeight;
1810
+ });
1811
+ return tddMethod?.price || 0;
1812
+ }, [variant?.weight, paymentShippingMethods]);
1813
+ const freeShippingMethods = react.useMemo(() => {
1814
+ const weight = variant?.weight || 0;
1815
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
1816
+ if (__mode === "free" /* FREE */) {
1817
+ return true;
1886
1818
  }
1819
+ if (isPlus) {
1820
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
1821
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1822
+ return hasCoupon && fitWeight && !__plus;
1823
+ } else {
1824
+ return __plus;
1825
+ }
1826
+ }) || [];
1827
+ if (isPlus) {
1828
+ methods = methods.sort((a, b) => {
1829
+ if (b.__mode === "free" /* FREE */) return -1;
1830
+ return 0;
1831
+ });
1887
1832
  }
1888
- if (variant) {
1889
- const newOptions = optionsConstructor(variant.selectedOptions);
1890
- setOptions(newOptions);
1891
- }
1892
- }, [product, sku]);
1893
- return [options, setOptions];
1894
- }
1895
- function decodeShopifyId2(gid) {
1896
- try {
1897
- const parts = gid.split("/");
1898
- return parts[parts.length - 1] || gid;
1899
- } catch {
1900
- return gid;
1901
- }
1902
- }
1903
- function useProductUrl(otherQuery) {
1904
- const { routerAdapter } = useShopify();
1905
- return react.useCallback(
1906
- ({ product, variant }) => {
1907
- if (!product) return "";
1908
- const queryParams = new URLSearchParams();
1909
- if (variant?.id) {
1910
- const variantId = decodeShopifyId2(variant.id);
1911
- if (variantId) {
1912
- queryParams.set("variant", variantId);
1833
+ return methods.map((method) => {
1834
+ let price = 0;
1835
+ let coupon;
1836
+ let disabled;
1837
+ if (method.__mode !== "free" /* FREE */) {
1838
+ switch (method.__mode) {
1839
+ case "tdd":
1840
+ price = tddPrice;
1841
+ coupon = tddCoupon || nddCoupon;
1842
+ break;
1843
+ case "ndd":
1844
+ price = nddPrice;
1845
+ coupon = nddCoupon;
1846
+ break;
1847
+ }
1848
+ disabled = selectedPlusMemberMode === "free";
1849
+ if (method.__mode === "ndd" /* NDD */) {
1850
+ disabled = disabled || nddOverweight;
1851
+ } else if (method.__mode === "tdd" /* TDD */) {
1852
+ disabled = disabled || tddOverweight;
1913
1853
  }
1914
1854
  }
1915
- if (otherQuery) {
1916
- Object.entries(otherQuery).forEach(([key, value]) => {
1917
- queryParams.set(key, value);
1918
- });
1919
- }
1920
- const queryString = queryParams.toString();
1921
- const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
1922
- if (routerAdapter?.getLocalizedPath) {
1923
- return routerAdapter.getLocalizedPath(path);
1855
+ return {
1856
+ ...method,
1857
+ id: method.__mode + method.__code,
1858
+ useCoupon: true,
1859
+ disabled,
1860
+ coupon,
1861
+ price
1862
+ };
1863
+ });
1864
+ }, [
1865
+ variant?.weight,
1866
+ plus_shipping?.shipping_methods,
1867
+ isPlus,
1868
+ nddCoupon,
1869
+ tddCoupon,
1870
+ selectedPlusMemberMode,
1871
+ tddPrice,
1872
+ nddPrice,
1873
+ nddOverweight,
1874
+ tddOverweight
1875
+ ]);
1876
+ return {
1877
+ freeShippingMethods,
1878
+ paymentShippingMethods,
1879
+ nddOverweight,
1880
+ tddOverweight,
1881
+ nddCoupon,
1882
+ tddCoupon,
1883
+ isLoadingCoupon: isLoading
1884
+ };
1885
+ }
1886
+ var useReplaceCartPlusMember = () => {
1887
+ const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
1888
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1889
+ const { cart } = useCartContext();
1890
+ const plusMonthly = plusMemberMetafields?.plus_monthly_product;
1891
+ const plusAnnual = plusMemberMetafields?.plus_annual_product;
1892
+ const handler = react.useCallback(async () => {
1893
+ const plusMonthlyInCart = cart?.lineItems.find(
1894
+ (item) => item.variant?.sku === plusMonthly?.sku
1895
+ );
1896
+ const plusAnnualInCart = cart?.lineItems.find(
1897
+ (item) => item.variant?.sku === plusAnnual?.sku
1898
+ );
1899
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
1900
+ await removeCartLines2({
1901
+ lineIds: [plusMonthlyInCart.id]
1902
+ });
1903
+ } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
1904
+ await removeCartLines2({
1905
+ lineIds: [plusAnnualInCart.id]
1906
+ });
1907
+ }
1908
+ }, [
1909
+ cart?.lineItems,
1910
+ selectedPlusMemberMode,
1911
+ plusMonthly?.sku,
1912
+ plusAnnual?.sku,
1913
+ removeCartLines2
1914
+ ]);
1915
+ return handler;
1916
+ };
1917
+ var usePlusMemberCheckoutCustomAttributes = ({
1918
+ disableShipping = false,
1919
+ isPresaleContains = false
1920
+ }) => {
1921
+ const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
1922
+ return react.useMemo(() => {
1923
+ const checkoutCustomAttributes = [
1924
+ {
1925
+ key: "_last_url",
1926
+ value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
1924
1927
  }
1925
- return path;
1928
+ ];
1929
+ checkoutCustomAttributes.push({
1930
+ key: "_checkout_delivery_custom",
1931
+ value: JSON.stringify({
1932
+ allow_nextday_delivery: true,
1933
+ allow_thirdday_delivery: true,
1934
+ selected_delivery_option: {
1935
+ code: selectedShippingMethod?.__code,
1936
+ mode: selectedShippingMethod?.__mode
1937
+ },
1938
+ is_presale: isPresaleContains,
1939
+ discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
1940
+ plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
1941
+ is_prime: profile?.isPlus
1942
+ })
1943
+ });
1944
+ if (disableShipping) {
1945
+ checkoutCustomAttributes.push({
1946
+ key: "_hide_shipping",
1947
+ value: "true"
1948
+ });
1949
+ }
1950
+ return checkoutCustomAttributes;
1951
+ }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1952
+ };
1953
+ function useRemoveCartLines(options) {
1954
+ const { client, locale, cartCookieAdapter } = useShopify();
1955
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1956
+ const removeLines = react.useCallback(
1957
+ async (_key, { arg }) => {
1958
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1959
+ let updatedCart = await shopifySdk.removeCartLines(client, {
1960
+ cartId,
1961
+ lineIds,
1962
+ metafieldIdentifiers,
1963
+ cookieAdapter: cartCookieAdapter
1964
+ });
1965
+ if (updatedCart && autoRemoveInvalidCodes) {
1966
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1967
+ if (unApplicableCodes.length > 0) {
1968
+ if (onCodesRemoved) {
1969
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1970
+ if (handledCart) {
1971
+ updatedCart = handledCart;
1972
+ }
1973
+ } else {
1974
+ updatedCart = await shopifySdk.updateCartCodes(client, {
1975
+ cartId: updatedCart.id,
1976
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1977
+ metafieldIdentifiers,
1978
+ cookieAdapter: cartCookieAdapter
1979
+ }) || updatedCart;
1980
+ }
1981
+ }
1982
+ }
1983
+ if (updatedCart) {
1984
+ mutateCart(updatedCart);
1985
+ }
1986
+ return updatedCart;
1926
1987
  },
1927
- [routerAdapter, otherQuery]
1988
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1928
1989
  );
1990
+ return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1929
1991
  }
1930
- function decodeShopifyId3(gid) {
1931
- try {
1932
- const parts = gid.split("/");
1933
- return parts[parts.length - 1] || gid;
1934
- } catch {
1935
- return gid;
1936
- }
1937
- }
1938
- function useUpdateVariantQuery(variant) {
1992
+
1993
+ // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1994
+ function useAutoRemovePlusMemberInCart({
1995
+ cart,
1996
+ profile,
1997
+ memberSetting
1998
+ }) {
1999
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2000
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1939
2001
  react.useEffect(() => {
1940
- if (!variant || typeof window === "undefined") {
1941
- return;
2002
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2003
+ const removePlusProduct = async (productType) => {
2004
+ if (!productType) return;
2005
+ const product = cart.lineItems?.find(
2006
+ (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2007
+ );
2008
+ if (product) {
2009
+ await removeCartLines2({
2010
+ lineIds: [product.id]
2011
+ });
2012
+ }
2013
+ };
2014
+ if (profile?.isMonthlyPlus) {
2015
+ removePlusProduct(plus_monthly_product);
1942
2016
  }
1943
- const searchParams = new URLSearchParams(window.location.search);
1944
- const currentVariantId = searchParams.get("variant");
1945
- const newVariantId = decodeShopifyId3(variant.id);
1946
- if (newVariantId && currentVariantId !== newVariantId) {
1947
- searchParams.set("variant", newVariantId);
1948
- const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
1949
- window.history.replaceState({}, "", newUrl);
2017
+ if (profile?.isAnnualPlus) {
2018
+ removePlusProduct(plus_annual_product);
1950
2019
  }
1951
- }, [variant]);
2020
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
1952
2021
  }
1953
- function getVariantMediaList({
1954
- product,
1955
- variant
2022
+ function hasPlusMemberInCart({
2023
+ memberSetting,
2024
+ cart
1956
2025
  }) {
1957
- if (variant.image?.url) {
1958
- const variantMediaId = variant.image.url;
1959
- const variantMedia = product.media.filter((media) => {
1960
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
1961
- return media.previewImage?.url === variantMediaId;
1962
- }
1963
- return false;
1964
- });
1965
- if (variantMedia.length > 0) {
1966
- const otherMedia = product.media.filter((media) => {
1967
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
1968
- return media.previewImage.url !== variantMediaId;
1969
- }
1970
- return true;
1971
- });
1972
- return [...variantMedia, ...otherMedia];
1973
- }
2026
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2027
+ if (!cart?.lineItems) {
2028
+ return {
2029
+ hasPlusMember: false,
2030
+ hasMonthlyPlus: false,
2031
+ hasAnnualPlus: false
2032
+ };
1974
2033
  }
1975
- return product.media;
2034
+ const monthlyPlusItem = cart.lineItems.find(
2035
+ (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
2036
+ );
2037
+ const annualPlusItem = cart.lineItems.find(
2038
+ (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
2039
+ );
2040
+ const hasMonthlyPlus = !!monthlyPlusItem;
2041
+ const hasAnnualPlus = !!annualPlusItem;
2042
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
2043
+ return {
2044
+ hasPlusMember,
2045
+ hasMonthlyPlus,
2046
+ hasAnnualPlus,
2047
+ monthlyPlusItem,
2048
+ annualPlusItem
2049
+ };
1976
2050
  }
1977
- function useVariantMedia({
1978
- product,
1979
- variant
2051
+ function useHasPlusMemberInCart({
2052
+ memberSetting,
2053
+ cart
1980
2054
  }) {
1981
- const [imageList, setImageList] = react.useState([]);
1982
- const [sceneList, setSceneList] = react.useState([]);
1983
- const [videoList, setVideoList] = react.useState([]);
1984
- react.useEffect(() => {
1985
- if (!product || !variant) {
1986
- setImageList([]);
1987
- setSceneList([]);
1988
- setVideoList([]);
1989
- return;
1990
- }
1991
- const mediaList = getVariantMediaList({ product, variant });
1992
- const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
1993
- const videos = mediaList.filter(
1994
- (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
1995
- );
1996
- setImageList(images.length > 0 && images[0] ? [images[0]] : []);
1997
- setSceneList(images.length > 1 ? images.slice(1) : []);
1998
- setVideoList(videos);
1999
- }, [product, variant]);
2055
+ return react.useMemo(
2056
+ () => hasPlusMemberInCart({
2057
+ memberSetting,
2058
+ cart
2059
+ }),
2060
+ [memberSetting, cart]
2061
+ );
2062
+ }
2063
+ function hasPlusMemberInLines({
2064
+ memberSetting,
2065
+ lines
2066
+ }) {
2067
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2068
+ if (!lines || lines.length === 0) {
2069
+ return {
2070
+ hasPlusMember: false,
2071
+ hasMonthlyPlus: false,
2072
+ hasAnnualPlus: false
2073
+ };
2074
+ }
2075
+ const monthlyPlusLine = lines.find((line) => {
2076
+ const variantHandle = line.variant?.product?.handle;
2077
+ const variantSku = line.variant?.sku;
2078
+ return variantHandle === plus_monthly_product?.handle && variantSku === plus_monthly_product?.sku;
2079
+ });
2080
+ const annualPlusLine = lines.find((line) => {
2081
+ const variantHandle = line.variant?.product?.handle;
2082
+ const variantSku = line.variant?.sku;
2083
+ return variantHandle === plus_annual_product?.handle && variantSku === plus_annual_product?.sku;
2084
+ });
2085
+ const hasMonthlyPlus = !!monthlyPlusLine;
2086
+ const hasAnnualPlus = !!annualPlusLine;
2087
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
2000
2088
  return {
2001
- productList: imageList,
2002
- sceneList,
2003
- videoList
2089
+ hasPlusMember,
2090
+ hasMonthlyPlus,
2091
+ hasAnnualPlus,
2092
+ monthlyPlusLine,
2093
+ annualPlusLine
2004
2094
  };
2005
2095
  }
2006
- function useCollection(options = {}) {
2007
- const { client, locale } = useShopify();
2008
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2009
- return useSWR__default.default(
2010
- handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2011
- () => shopifySdk.getCollection(client, {
2012
- handle,
2013
- locale,
2014
- metafieldIdentifiers
2096
+ function useHasPlusMemberInLines({
2097
+ memberSetting,
2098
+ lines
2099
+ }) {
2100
+ return react.useMemo(
2101
+ () => hasPlusMemberInLines({
2102
+ memberSetting,
2103
+ lines
2015
2104
  }),
2016
- swrOptions
2105
+ [memberSetting, lines]
2017
2106
  );
2018
2107
  }
2019
- function useAllCollections(options = {}) {
2020
- const { client, locale } = useShopify();
2021
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2022
- return useSWR__default.default(
2023
- ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2024
- () => shopifySdk.getAllCollections(client, {
2025
- locale,
2026
- first,
2027
- query,
2028
- sortKey,
2029
- reverse,
2030
- metafieldIdentifiers
2031
- }),
2032
- swrOptions
2033
- );
2034
- }
2035
- function useCollections(options = {}) {
2036
- const { client, locale } = useShopify();
2037
- const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2038
- return useSWR__default.default(
2039
- ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2040
- () => shopifySdk.getCollections(client, {
2041
- locale,
2042
- first,
2043
- after,
2044
- query,
2045
- sortKey,
2046
- reverse,
2047
- metafieldIdentifiers
2048
- }),
2049
- swrOptions
2050
- );
2051
- }
2052
- function useBlog(options = {}) {
2053
- const { client, locale } = useShopify();
2054
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2055
- return useSWR__default.default(
2056
- handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2057
- () => shopifySdk.getBlog(client, { handle, locale, metafieldIdentifiers }),
2058
- swrOptions
2059
- );
2060
- }
2061
- function useAllBlogs(options = {}) {
2062
- const { client, locale } = useShopify();
2063
- const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2064
- return useSWR__default.default(
2065
- ["all-blogs", locale, first, query, metafieldIdentifiers],
2066
- () => shopifySdk.getAllBlogs(client, {
2067
- locale,
2068
- first,
2069
- query,
2070
- metafieldIdentifiers
2071
- }),
2072
- swrOptions
2073
- );
2074
- }
2075
- function useArticle(options = {}) {
2076
- const { client, locale } = useShopify();
2077
- const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2078
- return useSWR__default.default(
2079
- blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2080
- () => shopifySdk.getArticle(client, {
2081
- blogHandle,
2082
- articleHandle,
2083
- locale,
2084
- metafieldIdentifiers
2085
- }),
2086
- swrOptions
2087
- );
2108
+ function usePlusMemberNeedAddToCart({
2109
+ cart,
2110
+ profile
2111
+ }) {
2112
+ const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
2113
+ const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2114
+ memberSetting: plusMemberMetafields,
2115
+ cart
2116
+ });
2117
+ const plusMemberVariant = react.useMemo(() => {
2118
+ if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
2119
+ return void 0;
2120
+ }
2121
+ if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2122
+ return void 0;
2123
+ }
2124
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2125
+ return void 0;
2126
+ }
2127
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2128
+ return void 0;
2129
+ }
2130
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2131
+ return void 0;
2132
+ }
2133
+ return selectedPlusMemberVariant;
2134
+ }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2135
+ return plusMemberVariant;
2088
2136
  }
2089
- function useArticles(options = {}) {
2090
- const { client, locale } = useShopify();
2091
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2092
- return useSWR__default.default(
2093
- ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2094
- () => shopifySdk.getArticles(client, {
2095
- locale,
2096
- first,
2097
- query,
2098
- sortKey,
2099
- reverse,
2100
- metafieldIdentifiers
2101
- }),
2102
- swrOptions
2137
+ var PlusMemberProvider = ({
2138
+ variant,
2139
+ product,
2140
+ memberSetting,
2141
+ initialSelectedPlusMemberMode = "free",
2142
+ profile,
2143
+ children
2144
+ }) => {
2145
+ const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2146
+ initialSelectedPlusMemberMode
2103
2147
  );
2104
- }
2105
- function useArticlesInBlog(options = {}) {
2106
- const { client, locale } = useShopify();
2107
- const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2108
- return useSWR__default.default(
2109
- blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2110
- () => shopifySdk.getArticlesInBlog(client, {
2111
- blogHandle,
2112
- locale,
2113
- first,
2114
- sortKey,
2115
- reverse,
2116
- metafieldIdentifiers
2117
- }),
2118
- swrOptions
2148
+ const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2149
+ const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2150
+ const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2151
+ const shippingMethodsContext = useShippingMethods({
2152
+ variant,
2153
+ plusMemberMetafields: memberSetting,
2154
+ selectedPlusMemberMode,
2155
+ profile
2156
+ });
2157
+ const { monthlyVariant, annualVariant } = usePlusMemberVariants({
2158
+ memberSetting
2159
+ });
2160
+ const selectedPlusMemberVariant = react.useMemo(() => {
2161
+ if (selectedPlusMemberMode === "free" /* FREE */) {
2162
+ return void 0;
2163
+ }
2164
+ return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
2165
+ }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
2166
+ return /* @__PURE__ */ jsxRuntime.jsx(
2167
+ PlusMemberContext.Provider,
2168
+ {
2169
+ value: {
2170
+ variant,
2171
+ plusMemberMetafields: memberSetting,
2172
+ selectedPlusMemberMode,
2173
+ setSelectedPlusMemberMode,
2174
+ selectedShippingMethod,
2175
+ setSelectedShippingMethod,
2176
+ shippingMethodsContext,
2177
+ showMoreShippingMethod,
2178
+ setShowMoreShippingMethod,
2179
+ selectedPlusMemberVariant,
2180
+ product,
2181
+ showPlusMemberBenefit,
2182
+ setShowPlusMemberBenefit,
2183
+ profile
2184
+ },
2185
+ children
2186
+ }
2119
2187
  );
2120
- }
2121
- async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2122
- if (!searchQuery) {
2123
- return void 0;
2124
- }
2125
- const query = (
2126
- /* GraphQL */
2127
- `
2128
- query search($query: String!, $first: Int!, $types: [SearchType!])
2129
- @inContext(language: $language) {
2130
- search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2131
- totalCount
2132
- edges {
2133
- node {
2134
- ... on Article {
2135
- __typename
2136
- id
2137
- handle
2138
- title
2139
- excerpt
2140
- image {
2141
- url
2142
- altText
2143
- }
2144
- }
2145
- ... on Page {
2146
- __typename
2147
- id
2148
- handle
2149
- title
2150
- }
2151
- ... on Product {
2152
- __typename
2153
- id
2154
- handle
2155
- title
2156
- description
2157
- featuredImage {
2158
- url
2159
- altText
2188
+ };
2189
+
2190
+ // src/hooks/cart/use-add-to-cart.ts
2191
+ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2192
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
2193
+ const { cart, addCustomAttributes, memberSetting, profile, customer } = useCartContext();
2194
+ const { trigger: applyCartCodes } = useApplyCartCodes();
2195
+ const { trigger: removeInvalidCodes } = useRemoveCartCodes();
2196
+ const { trigger: addCartLines2 } = useAddCartLines();
2197
+ const { trigger: createCart4 } = useCreateCart({
2198
+ updateCookie: true
2199
+ });
2200
+ const { hasPlusMember } = useHasPlusMemberInCart({
2201
+ memberSetting,
2202
+ cart
2203
+ });
2204
+ const { attributes: cartAttributes } = useCartAttributes({
2205
+ profile,
2206
+ customer,
2207
+ cart,
2208
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2209
+ });
2210
+ const addToCart = react.useCallback(
2211
+ async (_key, { arg }) => {
2212
+ const {
2213
+ lineItems,
2214
+ cartId: providedCartId,
2215
+ discountCodes,
2216
+ gtmParams = {},
2217
+ buyerIdentity,
2218
+ needCreateCart = false,
2219
+ onCodesInvalid,
2220
+ replaceExistingCodes,
2221
+ customAttributes
2222
+ } = arg;
2223
+ if (!lineItems || lineItems.length === 0) {
2224
+ return;
2225
+ }
2226
+ performanceAdapter?.addToCartStart();
2227
+ const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
2228
+ const lines = linesWithFunctionAttributes.map((item) => ({
2229
+ merchandiseId: item.variant?.id || "",
2230
+ quantity: item.quantity || 1,
2231
+ attributes: item.attributes,
2232
+ sellingPlanId: item.sellingPlanId
2233
+ })).filter((item) => item.merchandiseId && item.quantity);
2234
+ if (lines.length === 0) {
2235
+ return;
2236
+ }
2237
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
2238
+ let resultCart = null;
2239
+ if (!cartId) {
2240
+ resultCart = await createCart4({
2241
+ lines,
2242
+ buyerIdentity,
2243
+ discountCodes,
2244
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2245
+ // 初次加购时,就把所有 cart attributes 带上
2246
+ });
2247
+ } else {
2248
+ resultCart = await addCartLines2({
2249
+ cartId,
2250
+ lines
2251
+ });
2252
+ console.log("npm addCartLines resultCart", resultCart);
2253
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
2254
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
2255
+ if (unapplicableCodes.length > 0) {
2256
+ if (onCodesInvalid) {
2257
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
2258
+ if (handledCart) {
2259
+ resultCart = handledCart;
2160
2260
  }
2261
+ } else {
2262
+ await removeInvalidCodes({
2263
+ discountCodes: unapplicableCodes
2264
+ });
2161
2265
  }
2162
2266
  }
2163
2267
  }
2164
- pageInfo {
2165
- hasNextPage
2166
- endCursor
2268
+ if (resultCart && discountCodes && discountCodes.length > 0) {
2269
+ applyCartCodes({
2270
+ replaceExistingCodes,
2271
+ discountCodes
2272
+ });
2273
+ }
2274
+ if (customAttributes && customAttributes.length > 0) {
2275
+ addCustomAttributes(customAttributes);
2167
2276
  }
2168
2277
  }
2169
- }
2170
- `
2278
+ if (withTrack) {
2279
+ trackAddToCartGA({
2280
+ lineItems,
2281
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2282
+ });
2283
+ trackAddToCartFBQ({ lineItems });
2284
+ }
2285
+ performanceAdapter?.addToCartEnd();
2286
+ return resultCart;
2287
+ },
2288
+ [
2289
+ client,
2290
+ locale,
2291
+ cartCookieAdapter,
2292
+ userAdapter,
2293
+ cart,
2294
+ withTrack,
2295
+ performanceAdapter,
2296
+ createCart4,
2297
+ addCartLines2,
2298
+ applyCartCodes,
2299
+ removeInvalidCodes,
2300
+ addCustomAttributes,
2301
+ config
2302
+ ]
2171
2303
  );
2172
- const data = await client.query(query, {
2173
- query: searchQuery,
2174
- first,
2175
- types
2176
- });
2177
- if (!data || !data.search) {
2178
- return void 0;
2179
- }
2180
- const items = data.search.edges?.map((edge) => {
2181
- const node = edge.node;
2182
- const item = {
2183
- type: node.__typename.toUpperCase(),
2184
- id: node.id,
2185
- handle: node.handle,
2186
- title: node.title
2187
- };
2188
- if (node.__typename === "Product") {
2189
- item.description = node.description;
2190
- item.image = node.featuredImage ? {
2191
- url: node.featuredImage.url,
2192
- altText: node.featuredImage.altText
2193
- } : void 0;
2194
- } else if (node.__typename === "Article") {
2195
- item.description = node.excerpt;
2196
- item.image = node.image ? {
2197
- url: node.image.url,
2198
- altText: node.image.altText
2199
- } : void 0;
2200
- }
2201
- return item;
2202
- }) || [];
2203
- return {
2204
- items,
2205
- totalCount: data.search.totalCount || 0,
2206
- pageInfo: data.search.pageInfo
2207
- };
2304
+ return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
2208
2305
  }
2209
- function useSearch(options = {}) {
2210
- const { client, locale } = useShopify();
2211
- const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2212
- return useSWR__default.default(
2213
- query ? ["search", locale, query, first, types] : null,
2214
- () => performSearch(client, locale, query, first, types),
2215
- swrOptions
2306
+ function useUpdateCartLines(options) {
2307
+ const { client, locale, cartCookieAdapter } = useShopify();
2308
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
2309
+ const updateLines = react.useCallback(
2310
+ async (_key, { arg }) => {
2311
+ const updatedCart = await shopifySdk.updateCartLines(client, {
2312
+ ...arg,
2313
+ metafieldIdentifiers,
2314
+ cookieAdapter: cartCookieAdapter
2315
+ });
2316
+ if (updatedCart) {
2317
+ mutateCart(updatedCart);
2318
+ }
2319
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
2320
+ return updatedCart;
2321
+ },
2322
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2216
2323
  );
2324
+ return useSWRMutation__default.default("update-cart-lines", updateLines, options);
2217
2325
  }
2218
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
2219
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2220
- const query = (
2221
- /* GraphQL */
2222
- `
2223
- query getSiteInfo(
2224
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2225
- ) @inContext(language: $language) {
2226
- shop {
2227
- name
2228
- description
2229
- primaryDomain {
2230
- url
2231
- host
2326
+ function useUpdateCartAttributes({
2327
+ mutate,
2328
+ metafieldIdentifiers,
2329
+ disabled = false,
2330
+ swrOptions
2331
+ }) {
2332
+ const { client, locale, cartCookieAdapter } = useShopify();
2333
+ const updateAttributes = react.useCallback(
2334
+ async (_key, { arg }) => {
2335
+ if (disabled) {
2336
+ return void 0;
2337
+ }
2338
+ const updatedCart = await shopifySdk.updateCartAttributes(client, {
2339
+ ...arg,
2340
+ metafieldIdentifiers,
2341
+ cookieAdapter: cartCookieAdapter
2342
+ });
2343
+ if (updatedCart) {
2344
+ mutate(updatedCart);
2345
+ }
2346
+ return updatedCart;
2347
+ },
2348
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
2349
+ );
2350
+ return useSWRMutation__default.default("update-cart-attributes", updateAttributes, swrOptions);
2351
+ }
2352
+ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2353
+ const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2354
+ const { profile, customer, memberSetting } = useCartContext();
2355
+ const isLoggedIn = userAdapter?.isLoggedIn || false;
2356
+ const buyNow = react.useCallback(
2357
+ async (_key, { arg }) => {
2358
+ const {
2359
+ lineItems,
2360
+ discountCodes,
2361
+ gtmParams = {},
2362
+ buyerIdentity,
2363
+ fbqTrackConfig,
2364
+ customAttributes,
2365
+ metafieldIdentifiers,
2366
+ redirectToCheckout
2367
+ } = arg;
2368
+ if (!lineItems || lineItems.length === 0) {
2369
+ return;
2370
+ }
2371
+ const { hasPlusMember } = hasPlusMemberInLines({
2372
+ memberSetting,
2373
+ lines: lineItems
2374
+ });
2375
+ const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2376
+ const cartAttributes = getCartAttributes({
2377
+ profile,
2378
+ customer,
2379
+ memberType,
2380
+ currentUrl: window.location.href
2381
+ });
2382
+ const linesWithFunctionAttributes = getLinesWithAttributes({
2383
+ lineItems
2384
+ });
2385
+ const lines = linesWithFunctionAttributes.map((item) => ({
2386
+ merchandiseId: item.variant?.id || "",
2387
+ quantity: item.quantity || 1,
2388
+ attributes: item.attributes,
2389
+ sellingPlanId: item.sellingPlanId
2390
+ })).filter((item) => item.merchandiseId);
2391
+ if (lines.length === 0) {
2392
+ return;
2393
+ }
2394
+ const resultCart = await shopifySdk.createCart(client, {
2395
+ lines,
2396
+ metafieldIdentifiers,
2397
+ cookieAdapter: cartCookieAdapter,
2398
+ buyerIdentity,
2399
+ discountCodes,
2400
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2401
+ });
2402
+ if (!resultCart) {
2403
+ throw new Error("Failed to create cart for buy now");
2404
+ }
2405
+ if (withTrack && resultCart.lineItems) {
2406
+ trackBuyNowGA({
2407
+ lineItems,
2408
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2409
+ });
2410
+ if (fbqTrackConfig) {
2411
+ trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
2232
2412
  }
2233
- brand {
2234
- logo {
2235
- image {
2236
- url
2237
- }
2238
- }
2239
- colors {
2240
- primary {
2241
- background
2242
- }
2243
- secondary {
2244
- background
2245
- }
2413
+ }
2414
+ if (redirectToCheckout) {
2415
+ if (resultCart.url) {
2416
+ if (typeof window !== "undefined") {
2417
+ window.location.href = resultCart.url;
2246
2418
  }
2419
+ } else {
2420
+ throw new Error("Failed to get checkout URL");
2247
2421
  }
2248
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2249
2422
  }
2250
- }
2251
- `
2423
+ return resultCart;
2424
+ },
2425
+ [client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
2252
2426
  );
2253
- const variables = {};
2254
- if (hasMetafields) {
2255
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2256
- }
2257
- const data = await client.query(query, variables);
2258
- if (!data || !data.shop) {
2259
- return void 0;
2260
- }
2261
- const shop = data.shop;
2262
- const metafields = shop.metafields?.reduce((acc, mf) => {
2263
- if (mf && mf.key) {
2264
- acc[mf.key] = mf.value;
2265
- }
2266
- return acc;
2267
- }, {});
2268
- return {
2269
- name: shop.name,
2270
- description: shop.description,
2271
- primaryDomain: shop.primaryDomain,
2272
- brand: shop.brand ? {
2273
- logo: shop.brand.logo,
2274
- colors: shop.brand.colors ? {
2275
- primary: shop.brand.colors.primary?.background,
2276
- secondary: shop.brand.colors.secondary?.background
2277
- } : void 0
2278
- } : void 0,
2279
- metafields
2280
- };
2427
+ return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
2281
2428
  }
2282
- function useSite(options = {}) {
2429
+
2430
+ // src/hooks/cart/types/price-discount.ts
2431
+ var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
2432
+ PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
2433
+ PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
2434
+ return PriceDiscountType2;
2435
+ })(PriceDiscountType || {});
2436
+ var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
2437
+ PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
2438
+ PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
2439
+ return PriceBasePriceType2;
2440
+ })(PriceBasePriceType || {});
2441
+ function useProduct(options = {}) {
2283
2442
  const { client, locale } = useShopify();
2284
- const { metafieldIdentifiers, ...swrOptions } = options;
2443
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2285
2444
  return useSWR__default.default(
2286
- ["site", locale, metafieldIdentifiers],
2287
- () => getSiteInfo(client, locale, metafieldIdentifiers),
2445
+ handle ? ["product", locale, handle, metafieldIdentifiers] : null,
2446
+ () => shopifySdk.getProduct(client, {
2447
+ handle,
2448
+ locale,
2449
+ metafieldIdentifiers
2450
+ }),
2288
2451
  swrOptions
2289
2452
  );
2290
2453
  }
2291
-
2292
- // src/hooks/member/plus/types.ts
2293
- var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
2294
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
2295
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
2296
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
2297
- return PLUS_MEMBER_TYPE2;
2298
- })(PLUS_MEMBER_TYPE || {});
2299
- var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
2300
- PlusMemberMode2["MONTHLY"] = "monthly";
2301
- PlusMemberMode2["ANNUAL"] = "annual";
2302
- return PlusMemberMode2;
2303
- })(PlusMemberMode || {});
2304
- var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
2305
- DeliveryPlusType2["FREE"] = "free";
2306
- DeliveryPlusType2["MONTHLY"] = "monthly";
2307
- DeliveryPlusType2["ANNUAL"] = "annual";
2308
- return DeliveryPlusType2;
2309
- })(DeliveryPlusType || {});
2310
- var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
2311
- ShippingMethodMode2["FREE"] = "free";
2312
- ShippingMethodMode2["TDD"] = "tdd";
2313
- ShippingMethodMode2["NDD"] = "ndd";
2314
- return ShippingMethodMode2;
2315
- })(ShippingMethodMode || {});
2316
- var createInitialValue = () => ({
2317
- zipCode: "",
2318
- plusMemberMetafields: {},
2319
- setZipCode: () => {
2320
- },
2321
- allowNextDayDelivery: false,
2322
- setAllowNextDayDelivery: () => {
2323
- },
2324
- allowThirdDayDelivery: false,
2325
- setAllowThirdDayDelivery: () => {
2326
- },
2327
- selectedPlusMemberMode: "free",
2328
- setSelectedPlusMemberMode: () => {
2329
- },
2330
- showAreaCheckModal: false,
2331
- setShowAreaCheckModal: () => {
2332
- },
2333
- selectedShippingMethod: void 0,
2334
- setSelectedShippingMethod: () => {
2335
- },
2336
- showTip: false,
2337
- setShowTip: () => {
2338
- },
2339
- showMoreShippingMethod: false,
2340
- setShowMoreShippingMethod: () => {
2341
- },
2342
- variant: {},
2343
- product: {},
2344
- shippingMethodsContext: {
2345
- freeShippingMethods: [],
2346
- paymentShippingMethods: [],
2347
- nddOverweight: false,
2348
- tddOverweight: false
2349
- },
2350
- selectedPlusMemberProduct: null,
2351
- plusMemberProducts: [],
2352
- showPlusMemberBenefit: false,
2353
- setShowPlusMemberBenefit: () => {
2354
- },
2355
- deleteMarginBottom: false,
2356
- setDeleteMarginBottom: () => {
2357
- },
2358
- profile: void 0,
2359
- locale: void 0
2360
- });
2361
- var PlusMemberContext = react.createContext(createInitialValue());
2362
- function usePlusMemberContext() {
2363
- return react.useContext(PlusMemberContext);
2364
- }
2365
- function usePlusMonthlyProductVariant() {
2366
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2367
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2368
- const plusMonthlyProductVariant = react.useMemo(() => {
2369
- const product = plusMemberProducts?.find(
2370
- (item) => item?.handle === plusMonthly?.handle
2371
- );
2372
- const productVariant = product?.variants?.find(
2373
- (item) => item.sku === plusMonthly?.sku
2374
- );
2375
- return productVariant;
2376
- }, [plusMemberProducts, plusMonthly]);
2377
- return plusMonthlyProductVariant;
2454
+ function useAllProducts(options = {}) {
2455
+ const { client, locale } = useShopify();
2456
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2457
+ return useSWR__default.default(
2458
+ ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2459
+ () => shopifySdk.getAllProducts(client, {
2460
+ locale,
2461
+ first,
2462
+ query,
2463
+ sortKey,
2464
+ reverse,
2465
+ metafieldIdentifiers
2466
+ }),
2467
+ swrOptions
2468
+ );
2378
2469
  }
2379
- function usePlusAnnualProductVariant() {
2380
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2381
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2382
- const plusAnnualProductVariant = react.useMemo(() => {
2383
- const product = plusMemberProducts?.find(
2384
- (item) => item?.handle === plusAnnual?.handle
2385
- );
2386
- const productVariant = product?.variants?.find(
2387
- (item) => item.sku === plusAnnual?.sku
2388
- );
2389
- return productVariant;
2390
- }, [plusMemberProducts, plusAnnual]);
2391
- return plusAnnualProductVariant;
2470
+ function getFirstAvailableVariant(product) {
2471
+ const availableVariant = product.variants.find((v) => v.availableForSale);
2472
+ return availableVariant || product.variants[0];
2392
2473
  }
2393
- function useShippingMethods(options) {
2394
- const {
2395
- variant,
2396
- plusMemberMetafields,
2397
- selectedPlusMemberMode,
2398
- isPlus = false,
2399
- nddCoupon,
2400
- tddCoupon
2401
- } = options;
2402
- const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2403
- const nddOverweight = react.useMemo(() => {
2404
- return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
2405
- }, [shippingMethod?.overWeight_ndd, variant?.weight]);
2406
- const tddOverweight = react.useMemo(() => {
2407
- return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
2408
- }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2409
- const paymentShippingMethods = react.useMemo(() => {
2410
- const weight = variant?.weight || 0;
2411
- const methods = plus_shipping?.shipping_methods?.filter(
2412
- ({ weight_low, weight_high, __mode, __plus }) => {
2413
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2414
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2415
- }
2416
- ) || [];
2417
- return methods.map((method) => {
2418
- let disabled = false;
2419
- const selectedFreeMember = selectedPlusMemberMode === "free";
2420
- if (method.__mode === "ndd" /* NDD */) {
2421
- disabled = selectedFreeMember || nddOverweight;
2422
- } else if (method.__mode === "tdd" /* TDD */) {
2423
- disabled = selectedFreeMember || tddOverweight;
2424
- }
2425
- return {
2426
- ...method,
2427
- id: method.__mode + method.__code,
2428
- useCoupon: false,
2429
- subtitle: plus_shipping?.directly || "",
2430
- disabled
2431
- };
2474
+ function getVariantFromSelectedOptions(product, selectedOptions) {
2475
+ return product.variants.find((variant) => {
2476
+ return variant.selectedOptions.every((option) => {
2477
+ return selectedOptions[option.name] === option.value;
2432
2478
  });
2433
- }, [
2434
- nddOverweight,
2435
- plus_shipping?.directly,
2436
- plus_shipping?.shipping_methods,
2437
- selectedPlusMemberMode,
2438
- tddOverweight,
2439
- variant?.weight
2440
- ]);
2441
- const nddPrice = react.useMemo(() => {
2442
- const weight = variant?.weight || 0;
2443
- const nddMethod = paymentShippingMethods.find(
2444
- ({ __mode, weight_high, weight_low }) => {
2445
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2446
- return __mode === "ndd" && fitWeight;
2447
- }
2448
- );
2449
- return nddMethod?.price || 0;
2450
- }, [variant?.weight, paymentShippingMethods]);
2451
- const tddPrice = react.useMemo(() => {
2452
- const weight = variant?.weight || 0;
2453
- const tddMethod = paymentShippingMethods.find(
2454
- ({ __mode, weight_high, weight_low }) => {
2455
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2456
- return __mode === "tdd" && fitWeight;
2457
- }
2458
- );
2459
- return tddMethod?.price || 0;
2460
- }, [variant?.weight, paymentShippingMethods]);
2461
- const freeShippingMethods = react.useMemo(() => {
2462
- const weight = variant?.weight || 0;
2463
- let methods = plus_shipping?.shipping_methods?.filter(
2464
- ({ __mode, __plus, weight_low, weight_high }) => {
2465
- if (__mode === "free" /* FREE */) {
2466
- return true;
2467
- }
2468
- if (isPlus) {
2469
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2470
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2471
- return hasCoupon && fitWeight && !__plus;
2472
- } else {
2473
- return __plus;
2474
- }
2475
- }
2476
- ) || [];
2477
- if (isPlus) {
2478
- methods = methods.sort((a, b) => {
2479
- if (b.__mode === "free" /* FREE */) return -1;
2480
- return 0;
2481
- });
2479
+ });
2480
+ }
2481
+ function useVariant({
2482
+ product,
2483
+ selectedOptions
2484
+ }) {
2485
+ const [variant, setVariant] = react.useState(
2486
+ product ? getFirstAvailableVariant(product) : void 0
2487
+ );
2488
+ react.useEffect(() => {
2489
+ if (!product) {
2490
+ setVariant(void 0);
2491
+ return;
2482
2492
  }
2483
- return methods.map((method) => {
2484
- let price = 0;
2485
- let coupon;
2486
- let disabled;
2487
- if (method.__mode !== "free" /* FREE */) {
2488
- switch (method.__mode) {
2489
- case "tdd":
2490
- price = tddPrice;
2491
- coupon = tddCoupon || nddCoupon;
2492
- break;
2493
- case "ndd":
2494
- price = nddPrice;
2495
- coupon = nddCoupon;
2496
- break;
2497
- }
2498
- disabled = selectedPlusMemberMode === "free";
2499
- if (method.__mode === "ndd" /* NDD */) {
2500
- disabled = disabled || nddOverweight;
2501
- } else if (method.__mode === "tdd" /* TDD */) {
2502
- disabled = disabled || tddOverweight;
2503
- }
2504
- }
2505
- return {
2506
- ...method,
2507
- id: method.__mode + method.__code,
2508
- useCoupon: true,
2509
- disabled,
2510
- coupon,
2511
- price
2512
- };
2513
- });
2514
- }, [
2515
- variant?.weight,
2516
- plus_shipping?.shipping_methods,
2517
- isPlus,
2518
- nddCoupon,
2519
- tddCoupon,
2520
- selectedPlusMemberMode,
2521
- tddPrice,
2522
- nddPrice,
2523
- nddOverweight,
2524
- tddOverweight
2525
- ]);
2493
+ const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
2494
+ if (newVariant && newVariant.id !== variant?.id) {
2495
+ setVariant(newVariant);
2496
+ } else if (!newVariant) {
2497
+ setVariant(getFirstAvailableVariant(product));
2498
+ }
2499
+ }, [selectedOptions, product, variant?.id]);
2500
+ return variant;
2501
+ }
2502
+ var FAKE_PRICE = 999999999e-2;
2503
+ function formatPrice({
2504
+ amount,
2505
+ currencyCode,
2506
+ locale,
2507
+ maximumFractionDigits,
2508
+ minimumFractionDigits,
2509
+ removeTrailingZeros
2510
+ }) {
2511
+ const formatter = new Intl.NumberFormat(locale, {
2512
+ style: "currency",
2513
+ currency: currencyCode,
2514
+ maximumFractionDigits: maximumFractionDigits ?? 2,
2515
+ minimumFractionDigits: minimumFractionDigits ?? 2
2516
+ });
2517
+ let formatted = formatter.format(amount);
2518
+ if (removeTrailingZeros) {
2519
+ formatted = formatted.replace(/\.00$/, "");
2520
+ }
2521
+ return formatted;
2522
+ }
2523
+ function formatVariantPrice({
2524
+ amount,
2525
+ baseAmount,
2526
+ currencyCode,
2527
+ locale,
2528
+ maximumFractionDigits,
2529
+ minimumFractionDigits,
2530
+ removeTrailingZeros
2531
+ }) {
2526
2532
  return {
2527
- freeShippingMethods,
2528
- paymentShippingMethods,
2529
- nddOverweight,
2530
- tddOverweight
2533
+ price: formatPrice({
2534
+ amount,
2535
+ currencyCode,
2536
+ locale,
2537
+ maximumFractionDigits,
2538
+ minimumFractionDigits,
2539
+ removeTrailingZeros
2540
+ }),
2541
+ basePrice: formatPrice({
2542
+ amount: baseAmount,
2543
+ currencyCode,
2544
+ locale,
2545
+ maximumFractionDigits,
2546
+ minimumFractionDigits,
2547
+ removeTrailingZeros
2548
+ })
2531
2549
  };
2532
2550
  }
2533
- function useShippingMethodAvailableCheck() {
2534
- const {
2535
- zipCode,
2536
- allowNextDayDelivery,
2537
- allowThirdDayDelivery,
2538
- selectedShippingMethod,
2539
- setSelectedShippingMethod,
2540
- setShowTip,
2541
- shippingMethodsContext
2542
- } = usePlusMemberContext();
2543
- react.useEffect(() => {
2544
- const freeShippingMethod = shippingMethodsContext.freeShippingMethods[0];
2545
- const standardShippingMethod = shippingMethodsContext.freeShippingMethods?.find(
2546
- (item) => item.__mode === "free" /* FREE */
2547
- );
2548
- const freeTDD = shippingMethodsContext.freeShippingMethods.find(
2549
- (item) => item.__mode === "tdd" /* TDD */
2550
- );
2551
- const paymentTDD = shippingMethodsContext.paymentShippingMethods.find(
2552
- (item) => item.__mode === "tdd" /* TDD */
2553
- );
2554
- if (zipCode) {
2555
- console.log(
2556
- "allowNextDayDelivery, allowThirdDayDelivery:",
2557
- allowNextDayDelivery,
2558
- allowThirdDayDelivery
2559
- );
2560
- if (!allowNextDayDelivery && !allowThirdDayDelivery) {
2561
- setShowTip(true);
2562
- setSelectedShippingMethod(standardShippingMethod);
2563
- } else {
2564
- if (selectedShippingMethod?.__mode === "ndd" /* NDD */ && !allowNextDayDelivery) {
2565
- setShowTip(true);
2566
- if (allowThirdDayDelivery) {
2567
- if (selectedShippingMethod.useCoupon) {
2568
- const method = freeTDD || freeShippingMethod;
2569
- if (method) setSelectedShippingMethod(method);
2570
- } else {
2571
- const method = paymentTDD || freeShippingMethod;
2572
- if (method) setSelectedShippingMethod(method);
2573
- }
2574
- } else {
2575
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2576
- }
2577
- } else if (
2578
- // TDD 无法使用
2579
- selectedShippingMethod?.__mode === "tdd" /* TDD */ && !allowThirdDayDelivery
2580
- ) {
2581
- setShowTip(true);
2582
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2583
- }
2584
- }
2551
+ function usePrice({
2552
+ amount,
2553
+ baseAmount,
2554
+ currencyCode,
2555
+ soldOutDescription = "",
2556
+ maximumFractionDigits,
2557
+ minimumFractionDigits,
2558
+ removeTrailingZeros
2559
+ }) {
2560
+ const { locale } = useShopify();
2561
+ const value = react.useMemo(() => {
2562
+ if (typeof amount !== "number" || !currencyCode) {
2563
+ return "";
2564
+ }
2565
+ if (soldOutDescription && amount >= FAKE_PRICE) {
2566
+ return soldOutDescription;
2585
2567
  }
2568
+ return baseAmount ? formatVariantPrice({
2569
+ amount,
2570
+ baseAmount,
2571
+ currencyCode,
2572
+ locale,
2573
+ maximumFractionDigits,
2574
+ minimumFractionDigits,
2575
+ removeTrailingZeros
2576
+ }) : formatPrice({
2577
+ amount,
2578
+ currencyCode,
2579
+ locale,
2580
+ maximumFractionDigits,
2581
+ minimumFractionDigits,
2582
+ removeTrailingZeros
2583
+ });
2586
2584
  }, [
2587
- allowNextDayDelivery,
2588
- allowThirdDayDelivery,
2589
- zipCode,
2590
- shippingMethodsContext,
2591
- selectedShippingMethod,
2592
- setSelectedShippingMethod,
2593
- setShowTip
2585
+ amount,
2586
+ baseAmount,
2587
+ currencyCode,
2588
+ locale,
2589
+ maximumFractionDigits,
2590
+ minimumFractionDigits,
2591
+ soldOutDescription,
2592
+ removeTrailingZeros
2594
2593
  ]);
2594
+ const result = react.useMemo(() => {
2595
+ const free = Boolean(amount && amount <= 0);
2596
+ return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
2597
+ }, [value, amount]);
2598
+ return result;
2595
2599
  }
2596
- var useReplaceCartPlusMember = () => {
2597
- const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
2598
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2599
- const { cart } = useCartContext();
2600
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2601
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2602
- const handler = react.useCallback(async () => {
2603
- const plusMonthlyInCart = cart?.lineItems.find(
2604
- (item) => item.variant?.sku === plusMonthly?.sku
2605
- );
2606
- const plusAnnualInCart = cart?.lineItems.find(
2607
- (item) => item.variant?.sku === plusAnnual?.sku
2608
- );
2609
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
2610
- await removeCartLines2({
2611
- lineIds: [plusMonthlyInCart.id]
2612
- });
2613
- } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
2614
- await removeCartLines2({
2615
- lineIds: [plusAnnualInCart.id]
2616
- });
2600
+ function optionsConstructor(selectedOptions) {
2601
+ return selectedOptions.reduce((acc, option) => {
2602
+ acc[option.name] = option.value;
2603
+ return acc;
2604
+ }, {});
2605
+ }
2606
+ function decodeShopifyId(gid) {
2607
+ try {
2608
+ const base64 = gid.split("/").pop() || "";
2609
+ return atob(base64);
2610
+ } catch {
2611
+ return gid;
2612
+ }
2613
+ }
2614
+ function useSelectedOptions(product, sku) {
2615
+ const [options, setOptions] = react.useState({});
2616
+ react.useEffect(() => {
2617
+ if (!product || !product.variants.length) {
2618
+ setOptions({});
2619
+ return;
2617
2620
  }
2618
- }, [
2619
- cart?.lineItems,
2620
- selectedPlusMemberMode,
2621
- plusMonthly?.sku,
2622
- plusAnnual?.sku,
2623
- removeCartLines2
2624
- ]);
2625
- return handler;
2626
- };
2627
- var usePlusMemberDeliveryCodes = ({
2628
- deliveryData
2629
- }) => {
2630
- return react.useMemo(
2631
- () => deliveryData?.deliveryCustomData?.discount_code,
2632
- [deliveryData]
2633
- );
2634
- };
2635
- var usePlusMemberItemCustomAttributes = ({
2636
- deliveryData
2637
- }) => {
2638
- const { deliveryCustomData } = deliveryData || {};
2639
- return react.useMemo(() => {
2640
- const itemCustomAttributes = [];
2641
- if (deliveryCustomData?.is_presale) {
2642
- itemCustomAttributes.push({
2643
- key: "_is_presale",
2644
- value: "true"
2645
- });
2621
+ let variant = product.variants[0];
2622
+ if (typeof window !== "undefined") {
2623
+ const searchParams = new URLSearchParams(window.location.search);
2624
+ const variantIdParam = searchParams.get("variant");
2625
+ if (variantIdParam) {
2626
+ const foundVariant = product.variants.find((v) => {
2627
+ if (sku) return v.sku === sku;
2628
+ return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
2629
+ });
2630
+ if (foundVariant) {
2631
+ variant = foundVariant;
2632
+ }
2633
+ }
2646
2634
  }
2647
- return itemCustomAttributes;
2648
- }, [deliveryCustomData]);
2649
- };
2650
- var usePlusMemberCheckoutCustomAttributes = ({
2651
- deliveryData,
2652
- product,
2653
- variant,
2654
- customer,
2655
- isShowShippingBenefits
2656
- }) => {
2657
- const { deliveryCustomData } = deliveryData || {};
2658
- const { profile } = usePlusMemberContext();
2659
- const userType = react.useMemo(() => {
2660
- const customerInfo = customer;
2661
- if (!customerInfo) {
2662
- return "new_user_unlogin";
2663
- }
2664
- if (customer) {
2665
- const { orders = {} } = customer;
2666
- const edgesLength = orders?.edges?.length;
2667
- if (edgesLength === 1) {
2668
- return "old_user_orders_once";
2669
- } else if (edgesLength && edgesLength > 1) {
2670
- return "old_user_orders_twice";
2635
+ if (variant) {
2636
+ const newOptions = optionsConstructor(variant.selectedOptions);
2637
+ setOptions(newOptions);
2638
+ }
2639
+ }, [product, sku]);
2640
+ return [options, setOptions];
2641
+ }
2642
+ function decodeShopifyId2(gid) {
2643
+ try {
2644
+ const parts = gid.split("/");
2645
+ return parts[parts.length - 1] || gid;
2646
+ } catch {
2647
+ return gid;
2648
+ }
2649
+ }
2650
+ function useProductUrl(otherQuery) {
2651
+ const { routerAdapter } = useShopify();
2652
+ return react.useCallback(
2653
+ ({ product, variant }) => {
2654
+ if (!product) return "";
2655
+ const queryParams = new URLSearchParams();
2656
+ if (variant?.id) {
2657
+ const variantId = decodeShopifyId2(variant.id);
2658
+ if (variantId) {
2659
+ queryParams.set("variant", variantId);
2660
+ }
2671
2661
  }
2672
- }
2673
- return "new_user_login";
2674
- }, [customer]);
2675
- return react.useMemo(() => {
2676
- const checkoutCustomAttributes = [
2677
- {
2678
- key: "_token",
2679
- value: profile?.token || ""
2680
- },
2681
- {
2682
- key: "_last_url",
2683
- value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2684
- },
2685
- {
2686
- key: "_user_type",
2687
- value: userType
2662
+ if (otherQuery) {
2663
+ Object.entries(otherQuery).forEach(([key, value]) => {
2664
+ queryParams.set(key, value);
2665
+ });
2688
2666
  }
2689
- ];
2690
- if (profile) {
2691
- checkoutCustomAttributes.push({
2692
- key: "_login_user",
2693
- value: "1"
2694
- });
2695
- }
2696
- if (deliveryCustomData) {
2697
- checkoutCustomAttributes.push({
2698
- key: "_checkout_delivery_custom",
2699
- value: JSON.stringify({
2700
- ...deliveryCustomData,
2701
- is_prime: profile?.isPlus
2702
- })
2703
- });
2667
+ const queryString = queryParams.toString();
2668
+ const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
2669
+ if (routerAdapter?.getLocalizedPath) {
2670
+ return routerAdapter.getLocalizedPath(path);
2671
+ }
2672
+ return path;
2673
+ },
2674
+ [routerAdapter, otherQuery]
2675
+ );
2676
+ }
2677
+ function decodeShopifyId3(gid) {
2678
+ try {
2679
+ const parts = gid.split("/");
2680
+ return parts[parts.length - 1] || gid;
2681
+ } catch {
2682
+ return gid;
2683
+ }
2684
+ }
2685
+ function useUpdateVariantQuery(variant) {
2686
+ react.useEffect(() => {
2687
+ if (!variant || typeof window === "undefined") {
2688
+ return;
2704
2689
  }
2705
- if (variant?.metafields?.presell) {
2706
- checkoutCustomAttributes.push({
2707
- key: "_presale",
2708
- value: "true"
2709
- });
2690
+ const searchParams = new URLSearchParams(window.location.search);
2691
+ const currentVariantId = searchParams.get("variant");
2692
+ const newVariantId = decodeShopifyId3(variant.id);
2693
+ if (newVariantId && currentVariantId !== newVariantId) {
2694
+ searchParams.set("variant", newVariantId);
2695
+ const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
2696
+ window.history.replaceState({}, "", newUrl);
2710
2697
  }
2711
- if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2712
- checkoutCustomAttributes.push({
2713
- key: "_hide_shipping",
2714
- value: "true"
2698
+ }, [variant]);
2699
+ }
2700
+ function getVariantMediaList({
2701
+ product,
2702
+ variant
2703
+ }) {
2704
+ if (variant.image?.url) {
2705
+ const variantMediaId = variant.image.url;
2706
+ const variantMedia = product.media.filter((media) => {
2707
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2708
+ return media.previewImage?.url === variantMediaId;
2709
+ }
2710
+ return false;
2711
+ });
2712
+ if (variantMedia.length > 0) {
2713
+ const otherMedia = product.media.filter((media) => {
2714
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2715
+ return media.previewImage.url !== variantMediaId;
2716
+ }
2717
+ return true;
2715
2718
  });
2719
+ return [...variantMedia, ...otherMedia];
2716
2720
  }
2717
- return checkoutCustomAttributes;
2718
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2719
- };
2720
- function useAutoRemovePlusMemberInCart({
2721
- cart,
2722
- profile,
2723
- memberSetting
2721
+ }
2722
+ return product.media;
2723
+ }
2724
+ function useVariantMedia({
2725
+ product,
2726
+ variant
2724
2727
  }) {
2725
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2726
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2728
+ const [imageList, setImageList] = react.useState([]);
2729
+ const [sceneList, setSceneList] = react.useState([]);
2730
+ const [videoList, setVideoList] = react.useState([]);
2727
2731
  react.useEffect(() => {
2728
- if (!cart || !plus_monthly_product || !plus_annual_product) return;
2729
- const removePlusProduct = async (productType) => {
2730
- if (!productType) return;
2731
- const product = cart.lineItems?.find(
2732
- (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2733
- );
2734
- if (product) {
2735
- await removeCartLines2({
2736
- lineIds: [product.id]
2737
- });
2732
+ if (!product || !variant) {
2733
+ setImageList([]);
2734
+ setSceneList([]);
2735
+ setVideoList([]);
2736
+ return;
2737
+ }
2738
+ const mediaList = getVariantMediaList({ product, variant });
2739
+ const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
2740
+ const videos = mediaList.filter(
2741
+ (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
2742
+ );
2743
+ setImageList(images.length > 0 && images[0] ? [images[0]] : []);
2744
+ setSceneList(images.length > 1 ? images.slice(1) : []);
2745
+ setVideoList(videos);
2746
+ }, [product, variant]);
2747
+ return {
2748
+ productList: imageList,
2749
+ sceneList,
2750
+ videoList
2751
+ };
2752
+ }
2753
+ function useCollection(options = {}) {
2754
+ const { client, locale } = useShopify();
2755
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2756
+ return useSWR__default.default(
2757
+ handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2758
+ () => shopifySdk.getCollection(client, {
2759
+ handle,
2760
+ locale,
2761
+ metafieldIdentifiers
2762
+ }),
2763
+ swrOptions
2764
+ );
2765
+ }
2766
+ function useAllCollections(options = {}) {
2767
+ const { client, locale } = useShopify();
2768
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2769
+ return useSWR__default.default(
2770
+ ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2771
+ () => shopifySdk.getAllCollections(client, {
2772
+ locale,
2773
+ first,
2774
+ query,
2775
+ sortKey,
2776
+ reverse,
2777
+ metafieldIdentifiers
2778
+ }),
2779
+ swrOptions
2780
+ );
2781
+ }
2782
+ function useCollections(options = {}) {
2783
+ const { client, locale } = useShopify();
2784
+ const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2785
+ return useSWR__default.default(
2786
+ ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2787
+ () => shopifySdk.getCollections(client, {
2788
+ locale,
2789
+ first,
2790
+ after,
2791
+ query,
2792
+ sortKey,
2793
+ reverse,
2794
+ metafieldIdentifiers
2795
+ }),
2796
+ swrOptions
2797
+ );
2798
+ }
2799
+ function useBlog(options = {}) {
2800
+ const { client, locale } = useShopify();
2801
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2802
+ return useSWR__default.default(
2803
+ handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2804
+ () => shopifySdk.getBlog(client, { handle, locale, metafieldIdentifiers }),
2805
+ swrOptions
2806
+ );
2807
+ }
2808
+ function useAllBlogs(options = {}) {
2809
+ const { client, locale } = useShopify();
2810
+ const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2811
+ return useSWR__default.default(
2812
+ ["all-blogs", locale, first, query, metafieldIdentifiers],
2813
+ () => shopifySdk.getAllBlogs(client, {
2814
+ locale,
2815
+ first,
2816
+ query,
2817
+ metafieldIdentifiers
2818
+ }),
2819
+ swrOptions
2820
+ );
2821
+ }
2822
+ function useArticle(options = {}) {
2823
+ const { client, locale } = useShopify();
2824
+ const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2825
+ return useSWR__default.default(
2826
+ blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2827
+ () => shopifySdk.getArticle(client, {
2828
+ blogHandle,
2829
+ articleHandle,
2830
+ locale,
2831
+ metafieldIdentifiers
2832
+ }),
2833
+ swrOptions
2834
+ );
2835
+ }
2836
+ function useArticles(options = {}) {
2837
+ const { client, locale } = useShopify();
2838
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2839
+ return useSWR__default.default(
2840
+ ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2841
+ () => shopifySdk.getArticles(client, {
2842
+ locale,
2843
+ first,
2844
+ query,
2845
+ sortKey,
2846
+ reverse,
2847
+ metafieldIdentifiers
2848
+ }),
2849
+ swrOptions
2850
+ );
2851
+ }
2852
+ function useArticlesInBlog(options = {}) {
2853
+ const { client, locale } = useShopify();
2854
+ const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2855
+ return useSWR__default.default(
2856
+ blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2857
+ () => shopifySdk.getArticlesInBlog(client, {
2858
+ blogHandle,
2859
+ locale,
2860
+ first,
2861
+ sortKey,
2862
+ reverse,
2863
+ metafieldIdentifiers
2864
+ }),
2865
+ swrOptions
2866
+ );
2867
+ }
2868
+ async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2869
+ if (!searchQuery) {
2870
+ return void 0;
2871
+ }
2872
+ const query = (
2873
+ /* GraphQL */
2874
+ `
2875
+ query search($query: String!, $first: Int!, $types: [SearchType!])
2876
+ @inContext(language: $language) {
2877
+ search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2878
+ totalCount
2879
+ edges {
2880
+ node {
2881
+ ... on Article {
2882
+ __typename
2883
+ id
2884
+ handle
2885
+ title
2886
+ excerpt
2887
+ image {
2888
+ url
2889
+ altText
2890
+ }
2891
+ }
2892
+ ... on Page {
2893
+ __typename
2894
+ id
2895
+ handle
2896
+ title
2897
+ }
2898
+ ... on Product {
2899
+ __typename
2900
+ id
2901
+ handle
2902
+ title
2903
+ description
2904
+ featuredImage {
2905
+ url
2906
+ altText
2907
+ }
2908
+ }
2909
+ }
2910
+ }
2911
+ pageInfo {
2912
+ hasNextPage
2913
+ endCursor
2914
+ }
2738
2915
  }
2739
- };
2740
- if (profile?.isMonthlyPlus) {
2741
- removePlusProduct(plus_monthly_product);
2742
2916
  }
2743
- if (profile?.isAnnualPlus) {
2744
- removePlusProduct(plus_annual_product);
2745
- }
2746
- }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2747
- }
2748
- function useAddPlusMemberProductsToCart({
2749
- cart,
2750
- profile
2751
- }) {
2752
- const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2753
- const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2754
- memberSetting: plusMemberMetafields,
2755
- cart
2917
+ `
2918
+ );
2919
+ const data = await client.query(query, {
2920
+ query: searchQuery,
2921
+ first,
2922
+ types
2756
2923
  });
2757
- const plusMemberProduct = react.useMemo(() => {
2758
- if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2759
- return void 0;
2760
- }
2761
- if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2762
- return void 0;
2763
- }
2764
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2765
- return void 0;
2766
- }
2767
- if (profile.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2768
- return void 0;
2769
- }
2770
- if (!profile.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2771
- return void 0;
2924
+ if (!data || !data.search) {
2925
+ return void 0;
2926
+ }
2927
+ const items = data.search.edges?.map((edge) => {
2928
+ const node = edge.node;
2929
+ const item = {
2930
+ type: node.__typename.toUpperCase(),
2931
+ id: node.id,
2932
+ handle: node.handle,
2933
+ title: node.title
2934
+ };
2935
+ if (node.__typename === "Product") {
2936
+ item.description = node.description;
2937
+ item.image = node.featuredImage ? {
2938
+ url: node.featuredImage.url,
2939
+ altText: node.featuredImage.altText
2940
+ } : void 0;
2941
+ } else if (node.__typename === "Article") {
2942
+ item.description = node.excerpt;
2943
+ item.image = node.image ? {
2944
+ url: node.image.url,
2945
+ altText: node.image.altText
2946
+ } : void 0;
2772
2947
  }
2773
- return selectedPlusMemberProduct;
2774
- }, [
2775
- selectedPlusMemberMode,
2776
- selectedPlusMemberProduct?.variant,
2777
- selectedPlusMemberProduct?.product,
2778
- hasMonthlyPlus,
2779
- hasAnnualPlus
2780
- ]);
2781
- return plusMemberProduct;
2948
+ return item;
2949
+ }) || [];
2950
+ return {
2951
+ items,
2952
+ totalCount: data.search.totalCount || 0,
2953
+ pageInfo: data.search.pageInfo
2954
+ };
2782
2955
  }
2783
- var PlusMemberProvider = ({
2784
- variant,
2785
- product,
2786
- memberSetting,
2787
- initialSelectedPlusMemberMode = "free",
2788
- profile,
2789
- locale,
2790
- children
2791
- }) => {
2792
- const [zipCode, setZipCode] = react.useState("");
2793
- const [showTip, setShowTip] = react.useState(false);
2794
- const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2795
- initialSelectedPlusMemberMode
2956
+ function useSearch(options = {}) {
2957
+ const { client, locale } = useShopify();
2958
+ const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2959
+ return useSWR__default.default(
2960
+ query ? ["search", locale, query, first, types] : null,
2961
+ () => performSearch(client, locale, query, first, types),
2962
+ swrOptions
2796
2963
  );
2797
- const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2798
- const [allowNextDayDelivery, setAllowNextDayDelivery] = react.useState(false);
2799
- const [allowThirdDayDelivery, setAllowThirdDayDelivery] = react.useState(false);
2800
- const [showAreaCheckModal, setShowAreaCheckModal] = react.useState(false);
2801
- const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2802
- const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2803
- const [deleteMarginBottom, setDeleteMarginBottom] = react.useState(false);
2804
- const shippingMethodsContext = useShippingMethods({
2805
- variant,
2806
- plusMemberMetafields: memberSetting,
2807
- selectedPlusMemberMode});
2808
- const plusMemberHandles = react.useMemo(() => {
2809
- return [
2810
- memberSetting?.plus_monthly_product?.handle,
2811
- memberSetting?.plus_annual_product?.handle
2812
- ].filter(Boolean);
2813
- }, [memberSetting]);
2814
- const { data: plusMemberProducts = [] } = useProductsByHandles({
2815
- handles: plusMemberHandles
2816
- });
2817
- const selectedPlusMemberProduct = react.useMemo(() => {
2818
- if (selectedPlusMemberMode === "free" /* FREE */) {
2819
- return null;
2964
+ }
2965
+ async function getSiteInfo(client, locale, metafieldIdentifiers) {
2966
+ const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2967
+ const query = (
2968
+ /* GraphQL */
2969
+ `
2970
+ query getSiteInfo(
2971
+ ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2972
+ ) @inContext(language: $language) {
2973
+ shop {
2974
+ name
2975
+ description
2976
+ primaryDomain {
2977
+ url
2978
+ host
2979
+ }
2980
+ brand {
2981
+ logo {
2982
+ image {
2983
+ url
2984
+ }
2985
+ }
2986
+ colors {
2987
+ primary {
2988
+ background
2989
+ }
2990
+ secondary {
2991
+ background
2992
+ }
2993
+ }
2994
+ }
2995
+ ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2996
+ }
2820
2997
  }
2821
- const handle = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.handle : memberSetting?.plus_annual_product?.handle;
2822
- const sku = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.sku : memberSetting?.plus_annual_product?.sku;
2823
- const product2 = plusMemberProducts?.find((p) => p.handle === handle);
2824
- const variant2 = product2?.variants?.find((v) => v.sku === sku);
2825
- return product2 && variant2 ? { product: product2, variant: variant2 } : null;
2826
- }, [plusMemberProducts, memberSetting, selectedPlusMemberMode]);
2827
- return /* @__PURE__ */ jsxRuntime.jsx(
2828
- PlusMemberContext.Provider,
2829
- {
2830
- value: {
2831
- variant,
2832
- zipCode,
2833
- setZipCode,
2834
- allowNextDayDelivery,
2835
- setAllowNextDayDelivery,
2836
- allowThirdDayDelivery,
2837
- setAllowThirdDayDelivery,
2838
- plusMemberMetafields: memberSetting,
2839
- selectedPlusMemberMode,
2840
- setSelectedPlusMemberMode,
2841
- showAreaCheckModal,
2842
- setShowAreaCheckModal,
2843
- selectedShippingMethod,
2844
- setSelectedShippingMethod,
2845
- shippingMethodsContext,
2846
- showTip,
2847
- setShowTip,
2848
- showMoreShippingMethod,
2849
- setShowMoreShippingMethod,
2850
- selectedPlusMemberProduct,
2851
- plusMemberProducts,
2852
- product,
2853
- showPlusMemberBenefit,
2854
- setShowPlusMemberBenefit,
2855
- deleteMarginBottom,
2856
- setDeleteMarginBottom,
2857
- profile,
2858
- locale
2859
- },
2860
- children
2998
+ `
2999
+ );
3000
+ const variables = {};
3001
+ if (hasMetafields) {
3002
+ variables.shopMetafieldIdentifiers = metafieldIdentifiers;
3003
+ }
3004
+ const data = await client.query(query, variables);
3005
+ if (!data || !data.shop) {
3006
+ return void 0;
3007
+ }
3008
+ const shop = data.shop;
3009
+ const metafields = shop.metafields?.reduce((acc, mf) => {
3010
+ if (mf && mf.key) {
3011
+ acc[mf.key] = mf.value;
2861
3012
  }
3013
+ return acc;
3014
+ }, {});
3015
+ return {
3016
+ name: shop.name,
3017
+ description: shop.description,
3018
+ primaryDomain: shop.primaryDomain,
3019
+ brand: shop.brand ? {
3020
+ logo: shop.brand.logo,
3021
+ colors: shop.brand.colors ? {
3022
+ primary: shop.brand.colors.primary?.background,
3023
+ secondary: shop.brand.colors.secondary?.background
3024
+ } : void 0
3025
+ } : void 0,
3026
+ metafields
3027
+ };
3028
+ }
3029
+ function useSite(options = {}) {
3030
+ const { client, locale } = useShopify();
3031
+ const { metafieldIdentifiers, ...swrOptions } = options;
3032
+ return useSWR__default.default(
3033
+ ["site", locale, metafieldIdentifiers],
3034
+ () => getSiteInfo(client, locale, metafieldIdentifiers),
3035
+ swrOptions
2862
3036
  );
2863
- };
3037
+ }
2864
3038
  function useIntersection(targetRef, options) {
2865
3039
  const {
2866
3040
  callback,
@@ -3054,7 +3228,7 @@ function CartProvider({
3054
3228
  }) {
3055
3229
  const { client, cartCookieAdapter } = useShopify();
3056
3230
  const [customAttributes, setCustomAttributes] = react.useState([]);
3057
- const [customAttributesNeedDelete, setCustomAttributesNeedDelete] = react.useState(
3231
+ const [customAttributesNeedRemove, setCustomAttributesNeedRemove] = react.useState(
3058
3232
  []
3059
3233
  );
3060
3234
  const [isCodeChanging, setIsCodeChanging] = react.useState(false);
@@ -3082,15 +3256,34 @@ function CartProvider({
3082
3256
  refreshDeps: [locale]
3083
3257
  }
3084
3258
  );
3085
- const { trigger: updateAttributes } = useUpdateCartAttributes(mutateCart, metafieldIdentifiers);
3086
- const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
3259
+ const { trigger: updateAttributes } = useUpdateCartAttributes({
3260
+ mutate: mutateCart,
3261
+ metafieldIdentifiers,
3262
+ disabled: isCartLoading
3263
+ });
3264
+ const { hasPlusMember } = useHasPlusMemberInCart({
3265
+ memberSetting,
3266
+ cart
3267
+ });
3268
+ const { attributes: commonAttributes } = useCartAttributes({
3269
+ profile,
3270
+ customer,
3271
+ cart,
3272
+ memberType: hasPlusMember ? "2" : profile?.memberType
3273
+ });
3087
3274
  ahooks.useRequest(
3088
3275
  () => {
3089
- const newAttributes = [...attributes, ...customAttributes];
3090
- const needUpdate = cart && !checkAttributesUpdateNeeded(
3276
+ const filteredSameCommonAttributes = commonAttributes.filter(
3277
+ (attr) => !customAttributes.some((a) => a.key === attr.key)
3278
+ );
3279
+ const newAttributes = [
3280
+ ...filteredSameCommonAttributes,
3281
+ ...customAttributes
3282
+ ];
3283
+ const needUpdate = cart && checkAttributesUpdateNeeded(
3091
3284
  cart.customAttributes,
3092
3285
  newAttributes,
3093
- customAttributesNeedDelete
3286
+ customAttributesNeedRemove
3094
3287
  );
3095
3288
  if (needUpdate) {
3096
3289
  return updateAttributes({ attributes: newAttributes });
@@ -3103,44 +3296,39 @@ function CartProvider({
3103
3296
  // 1 秒内只触发最后一次更新
3104
3297
  throttleTrailing: true,
3105
3298
  throttleLeading: false,
3106
- refreshDeps: [attributes, customAttributes]
3299
+ refreshDeps: [commonAttributes, customAttributes, customAttributesNeedRemove]
3107
3300
  }
3108
3301
  );
3109
3302
  useUpdateLineCodeAmountAttributes({
3110
3303
  cart,
3111
3304
  mutateCart,
3112
3305
  isCartLoading: isCartLoading || isCodeChanging,
3113
- setLoadingState
3306
+ setLoadingState,
3307
+ metafieldIdentifiers
3114
3308
  });
3115
3309
  const removeCustomAttributes = react.useCallback(
3116
- (attributes2) => {
3117
- setCustomAttributesNeedDelete(attributes2);
3310
+ (attributes) => {
3311
+ setCustomAttributesNeedRemove(attributes);
3118
3312
  },
3119
- [setCustomAttributesNeedDelete]
3313
+ [setCustomAttributesNeedRemove]
3120
3314
  );
3121
3315
  const addCustomAttributes = react.useCallback(
3122
- (attributes2) => {
3123
- const sameAttributes = attributes2.filter(
3124
- (attr) => customAttributes.some((a) => a.key === attr.key)
3125
- );
3126
- if (sameAttributes.length) {
3127
- setCustomAttributes((prev) => {
3128
- const removedAttributes = prev.filter(
3129
- (attr) => !sameAttributes.some((a) => a.key === attr.key)
3130
- );
3131
- return [...removedAttributes, ...attributes2];
3132
- });
3133
- } else {
3134
- setCustomAttributes((prev) => [...prev, ...attributes2]);
3135
- }
3316
+ (attributes) => {
3317
+ setCustomAttributes((oldCustomAttributes) => {
3318
+ const filteredSameAttributes = oldCustomAttributes.filter(
3319
+ (attr) => !attributes.some((a) => a.key === attr.key)
3320
+ );
3321
+ return [...filteredSameAttributes, ...attributes];
3322
+ });
3136
3323
  },
3137
- [customAttributes]
3324
+ [setCustomAttributes]
3138
3325
  );
3139
3326
  const functionAutoFreeGiftResult = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer);
3140
3327
  const scriptAutoFreeGiftResult = useScriptAutoFreeGift({
3141
3328
  campaign: gradientGiftsConfig || null,
3142
3329
  _giveaway: CUSTOMER_SCRIPT_GIFT_KEY,
3143
- cart
3330
+ cart,
3331
+ profile
3144
3332
  });
3145
3333
  const formattedScriptGifts = react.useMemo(() => {
3146
3334
  return formatScriptAutoFreeGift({
@@ -3191,16 +3379,23 @@ function CartProvider({
3191
3379
  );
3192
3380
  return result;
3193
3381
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
3382
+ const totalQuantity = react.useMemo(() => {
3383
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
3384
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3385
+ return cartLinesCount + giftLinesCount;
3386
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
3194
3387
  const value = react.useMemo(
3195
3388
  () => ({
3389
+ totalQuantity,
3196
3390
  cart,
3197
3391
  isCartLoading,
3198
3392
  triggerFetch: fetchCart,
3199
3393
  mutateCart,
3200
3394
  addCustomAttributes,
3201
3395
  removeCustomAttributes,
3202
- setCustomAttributes,
3203
3396
  locale,
3397
+ profile,
3398
+ customer,
3204
3399
  isCodeChanging,
3205
3400
  setIsCodeChanging,
3206
3401
  autoFreeGiftConfig,
@@ -3216,10 +3411,12 @@ function CartProvider({
3216
3411
  scriptAutoFreeGiftResult,
3217
3412
  setScriptAutoFreeGift,
3218
3413
  giftNeedAddToCartLines,
3219
- metafieldIdentifiers
3414
+ metafieldIdentifiers,
3415
+ memberSetting
3220
3416
  }),
3221
3417
  [
3222
3418
  cart,
3419
+ totalQuantity,
3223
3420
  isCartLoading,
3224
3421
  fetchCart,
3225
3422
  mutateCart,
@@ -3239,43 +3436,23 @@ function CartProvider({
3239
3436
  scriptAutoFreeGiftResult,
3240
3437
  setScriptAutoFreeGift,
3241
3438
  giftNeedAddToCartLines,
3242
- metafieldIdentifiers
3439
+ metafieldIdentifiers,
3440
+ customer,
3441
+ profile,
3442
+ memberSetting
3243
3443
  ]
3244
3444
  );
3245
3445
  return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
3246
3446
  }
3247
- function useCartContext() {
3447
+ function useCartContext(options) {
3248
3448
  const context = react.useContext(CartContext);
3249
- if (!context) {
3449
+ if (!context && !options?.optional) {
3250
3450
  throw new Error("useCartContext must be used within a CartProvider");
3251
3451
  }
3252
3452
  return context;
3253
3453
  }
3254
3454
 
3255
- Object.defineProperty(exports, "ShopifyConfig", {
3256
- enumerable: true,
3257
- get: function () { return shopifySdk.ShopifyConfig; }
3258
- });
3259
- Object.defineProperty(exports, "clearLocalStorage", {
3260
- enumerable: true,
3261
- get: function () { return shopifySdk.clearLocalStorage; }
3262
- });
3263
- Object.defineProperty(exports, "createShopifyClient", {
3264
- enumerable: true,
3265
- get: function () { return shopifySdk.createShopifyClient; }
3266
- });
3267
- Object.defineProperty(exports, "getLocalStorage", {
3268
- enumerable: true,
3269
- get: function () { return shopifySdk.getLocalStorage; }
3270
- });
3271
- Object.defineProperty(exports, "removeLocalStorage", {
3272
- enumerable: true,
3273
- get: function () { return shopifySdk.removeLocalStorage; }
3274
- });
3275
- Object.defineProperty(exports, "setLocalStorage", {
3276
- enumerable: true,
3277
- get: function () { return shopifySdk.setLocalStorage; }
3278
- });
3455
+ exports.BrowserPerformanceAdapter = BrowserPerformanceAdapter;
3279
3456
  exports.BuyRuleType = BuyRuleType;
3280
3457
  exports.CODE_AMOUNT_KEY = CODE_AMOUNT_KEY;
3281
3458
  exports.CUSTOMER_ATTRIBUTE_KEY = CUSTOMER_ATTRIBUTE_KEY;
@@ -3283,6 +3460,7 @@ exports.CUSTOMER_SCRIPT_GIFT_KEY = CUSTOMER_SCRIPT_GIFT_KEY;
3283
3460
  exports.CartProvider = CartProvider;
3284
3461
  exports.DeliveryPlusType = DeliveryPlusType;
3285
3462
  exports.MAIN_PRODUCT_CODE = MAIN_PRODUCT_CODE;
3463
+ exports.MEMBER_PRICE_ATTRIBUTE_KEY = MEMBER_PRICE_ATTRIBUTE_KEY;
3286
3464
  exports.OrderBasePriceType = OrderBasePriceType;
3287
3465
  exports.OrderDiscountType = OrderDiscountType;
3288
3466
  exports.PLUS_MEMBER_TYPE = PLUS_MEMBER_TYPE;
@@ -3297,11 +3475,8 @@ exports.ShippingMethodMode = ShippingMethodMode;
3297
3475
  exports.ShopifyContext = ShopifyContext;
3298
3476
  exports.ShopifyProvider = ShopifyProvider;
3299
3477
  exports.SpendMoneyType = SpendMoneyType;
3300
- exports.atobID = atobID;
3301
3478
  exports.browserCartCookieAdapter = browserCartCookieAdapter;
3302
3479
  exports.browserCookieAdapter = browserCookieAdapter;
3303
- exports.btoaID = btoaID;
3304
- exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
3305
3480
  exports.clearGeoLocationCache = clearGeoLocationCache;
3306
3481
  exports.createMockCartFromLines = createMockCartFromLines;
3307
3482
  exports.currencyCodeMapping = currencyCodeMapping;
@@ -3310,10 +3485,14 @@ exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
3310
3485
  exports.formatScriptAutoFreeGift = formatScriptAutoFreeGift;
3311
3486
  exports.gaTrack = gaTrack;
3312
3487
  exports.getCachedGeoLocation = getCachedGeoLocation;
3488
+ exports.getCartAttributes = getCartAttributes;
3313
3489
  exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
3314
3490
  exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
3315
3491
  exports.getQuery = getQuery;
3316
3492
  exports.getReferralAttributes = getReferralAttributes;
3493
+ exports.getUserType = getUserType;
3494
+ exports.hasPlusMemberInCart = hasPlusMemberInCart;
3495
+ exports.hasPlusMemberInLines = hasPlusMemberInLines;
3317
3496
  exports.normalizeAddToCartLines = normalizeAddToCartLines;
3318
3497
  exports.preCheck = preCheck;
3319
3498
  exports.safeParse = safeParse;
@@ -3323,7 +3502,6 @@ exports.trackBeginCheckoutGA = trackBeginCheckoutGA;
3323
3502
  exports.trackBuyNowFBQ = trackBuyNowFBQ;
3324
3503
  exports.trackBuyNowGA = trackBuyNowGA;
3325
3504
  exports.useAddCartLines = useAddCartLines;
3326
- exports.useAddPlusMemberProductsToCart = useAddPlusMemberProductsToCart;
3327
3505
  exports.useAddToCart = useAddToCart;
3328
3506
  exports.useAllBlogs = useAllBlogs;
3329
3507
  exports.useAllCollections = useAllCollections;
@@ -3333,6 +3511,7 @@ exports.useArticle = useArticle;
3333
3511
  exports.useArticles = useArticles;
3334
3512
  exports.useArticlesInBlog = useArticlesInBlog;
3335
3513
  exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
3514
+ exports.useAvailableDeliveryCoupon = useAvailableDeliveryCoupon;
3336
3515
  exports.useBlog = useBlog;
3337
3516
  exports.useBuyNow = useBuyNow;
3338
3517
  exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
@@ -3347,13 +3526,12 @@ exports.useCreateCart = useCreateCart;
3347
3526
  exports.useExposure = useExposure;
3348
3527
  exports.useGeoLocation = useGeoLocation;
3349
3528
  exports.useHasPlusMemberInCart = useHasPlusMemberInCart;
3529
+ exports.useHasPlusMemberInLines = useHasPlusMemberInLines;
3350
3530
  exports.useIntersection = useIntersection;
3351
- exports.usePlusAnnualProductVariant = usePlusAnnualProductVariant;
3352
3531
  exports.usePlusMemberCheckoutCustomAttributes = usePlusMemberCheckoutCustomAttributes;
3353
3532
  exports.usePlusMemberContext = usePlusMemberContext;
3354
- exports.usePlusMemberDeliveryCodes = usePlusMemberDeliveryCodes;
3355
- exports.usePlusMemberItemCustomAttributes = usePlusMemberItemCustomAttributes;
3356
- exports.usePlusMonthlyProductVariant = usePlusMonthlyProductVariant;
3533
+ exports.usePlusMemberNeedAddToCart = usePlusMemberNeedAddToCart;
3534
+ exports.usePlusMemberVariants = usePlusMemberVariants;
3357
3535
  exports.usePrice = usePrice;
3358
3536
  exports.useProduct = useProduct;
3359
3537
  exports.useProductUrl = useProductUrl;
@@ -3364,7 +3542,6 @@ exports.useReplaceCartPlusMember = useReplaceCartPlusMember;
3364
3542
  exports.useScriptAutoFreeGift = useScriptAutoFreeGift;
3365
3543
  exports.useSearch = useSearch;
3366
3544
  exports.useSelectedOptions = useSelectedOptions;
3367
- exports.useShippingMethodAvailableCheck = useShippingMethodAvailableCheck;
3368
3545
  exports.useShippingMethods = useShippingMethods;
3369
3546
  exports.useShopify = useShopify;
3370
3547
  exports.useSite = useSite;
@@ -3374,5 +3551,11 @@ exports.useUpdateLineCodeAmountAttributes = useUpdateLineCodeAmountAttributes;
3374
3551
  exports.useUpdateVariantQuery = useUpdateVariantQuery;
3375
3552
  exports.useVariant = useVariant;
3376
3553
  exports.useVariantMedia = useVariantMedia;
3554
+ Object.keys(shopifySdk).forEach(function (k) {
3555
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
3556
+ enumerable: true,
3557
+ get: function () { return shopifySdk[k]; }
3558
+ });
3559
+ });
3377
3560
  //# sourceMappingURL=index.js.map
3378
3561
  //# sourceMappingURL=index.js.map