@anker-in/shopify-react 0.1.1-beta.8 → 0.1.1

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,30 +1172,55 @@ 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: [
1229
1213
  {
1230
1214
  key: scriptGiveawayKey,
1231
- value: "true"
1215
+ value: scriptGiveawayKey
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,121 +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 ?? 0)
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
- const hasFunctionEnvAttribute = cart?.lineItems.some(
1451
- (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1452
- );
1453
- const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1454
- return hasFunctionEnvAttribute ? [
1455
- {
1456
- key: "_discounts_function_env",
1457
- value: JSON.stringify({
1458
- discount_code: discountCodes,
1459
- user_tags: customer?.tags || []
1460
- })
1461
- }
1462
- ] : [];
1463
- }, [cart]);
1464
- const presellAttributes = react.useMemo(() => {
1465
- return [
1466
- {
1467
- key: "_presale",
1468
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1469
- }
1470
- ];
1471
- }, [cart]);
1472
- const weightAttributes = react.useMemo(() => {
1473
- return [
1474
- {
1475
- key: "_weight",
1476
- value: cart?.lineItems.reduce((acc, item) => {
1477
- return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1478
- }, 0).toString()
1479
- },
1480
- {
1481
- key: "_app_source_name",
1482
- value: "dtc"
1483
- }
1484
- ];
1485
- }, [cart]);
1486
- const trackingAttributes = react.useMemo(() => {
1487
- return [
1488
- {
1489
- key: "utm_params",
1490
- value: currentUrl
1491
- }
1492
- ];
1493
- }, [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]);
1494
1465
  return react.useMemo(
1495
1466
  () => ({
1496
- attributes: [
1497
- ...memberAttributes,
1498
- ...functionAttributes,
1499
- ...presellAttributes,
1500
- ...weightAttributes,
1501
- ...trackingAttributes,
1502
- ...getReferralAttributes()
1503
- ].filter((item) => item?.value)
1467
+ attributes
1504
1468
  }),
1505
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1469
+ [attributes]
1506
1470
  );
1507
1471
  };
1508
1472
  var DEFAULT_MIN = 1;
@@ -1565,7 +1529,7 @@ var useUpdateLineCodeAmountAttributes = ({
1565
1529
  );
1566
1530
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1567
1531
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1568
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1532
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1569
1533
  attrNeedUpdate.push({
1570
1534
  key: CUSTOMER_ATTRIBUTE_KEY,
1571
1535
  value: JSON.stringify({
@@ -1604,29 +1568,22 @@ var useUpdateLineCodeAmountAttributes = ({
1604
1568
  }).filter(
1605
1569
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1606
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
+ }
1607
1578
  if (attrNeedUpdate.length) {
1608
- return {
1609
- id: line.id,
1610
- attributes: [
1611
- ...line.customAttributes?.filter(
1612
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1613
- ) || [],
1614
- ...attrNeedUpdate
1615
- ]
1616
- };
1617
- } else if (attrNeedDelete.length) {
1618
- return {
1619
- id: line.id,
1620
- attributes: line.customAttributes?.filter(
1621
- (attr) => !attrNeedDelete.includes(attr.key)
1622
- ) || []
1623
- };
1624
- } else {
1625
- return {
1626
- id: line.id,
1627
- attributes: line.customAttributes || []
1628
- };
1579
+ attributes = attributes.filter(
1580
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1581
+ ).concat(attrNeedUpdate);
1629
1582
  }
1583
+ return {
1584
+ id: lineId,
1585
+ attributes
1586
+ };
1630
1587
  }),
1631
1588
  [cart?.lineItems, mainProductDiscountCodes]
1632
1589
  );
@@ -1661,45 +1618,61 @@ var useUpdateLineCodeAmountAttributes = ({
1661
1618
  }, [loading, setLoadingState]);
1662
1619
  };
1663
1620
 
1664
- // src/hooks/cart/types/price-discount.ts
1665
- var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
1666
- PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1667
- PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1668
- return PriceDiscountType2;
1669
- })(PriceDiscountType || {});
1670
- var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
1671
- PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
1672
- PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
1673
- return PriceBasePriceType2;
1674
- })(PriceBasePriceType || {});
1675
- function useProduct(options = {}) {
1676
- const { client, locale } = useShopify();
1677
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
1678
- return useSWR__default.default(
1679
- handle ? ["product", locale, handle, metafieldIdentifiers] : null,
1680
- () => shopifySdk.getProduct(client, {
1681
- handle,
1682
- locale,
1683
- metafieldIdentifiers
1684
- }),
1685
- swrOptions
1686
- );
1687
- }
1688
- function useAllProducts(options = {}) {
1689
- const { client, locale } = useShopify();
1690
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
1691
- return useSWR__default.default(
1692
- ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
1693
- () => shopifySdk.getAllProducts(client, {
1694
- locale,
1695
- first,
1696
- query,
1697
- sortKey,
1698
- reverse,
1699
- metafieldIdentifiers
1700
- }),
1701
- swrOptions
1702
- );
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);
1703
1676
  }
1704
1677
  function useProductsByHandles(options = {}) {
1705
1678
  const { client, locale } = useShopify();
@@ -1719,1152 +1692,1349 @@ function useProductsByHandles(options = {}) {
1719
1692
  metafieldIdentifiers
1720
1693
  });
1721
1694
  },
1722
- swrOptions || {
1723
- revalidateOnFocus: false
1695
+ {
1696
+ revalidateOnFocus: false,
1697
+ ...swrOptions
1724
1698
  }
1725
1699
  );
1726
1700
  }
1727
- function getFirstAvailableVariant(product) {
1728
- const availableVariant = product.variants.find((v) => v.availableForSale);
1729
- return availableVariant || product.variants[0];
1730
- }
1731
- function getVariantFromSelectedOptions(product, selectedOptions) {
1732
- return product.variants.find((variant) => {
1733
- return variant.selectedOptions.every((option) => {
1734
- return selectedOptions[option.name] === option.value;
1735
- });
1736
- });
1737
- }
1738
- function useVariant({
1739
- product,
1740
- selectedOptions
1701
+
1702
+ // src/hooks/member/plus/use-plus-member-variants.ts
1703
+ function usePlusMemberVariants({
1704
+ memberSetting
1741
1705
  }) {
1742
- const [variant, setVariant] = react.useState(
1743
- product ? getFirstAvailableVariant(product) : void 0
1744
- );
1745
- react.useEffect(() => {
1746
- if (!product) {
1747
- setVariant(void 0);
1748
- return;
1749
- }
1750
- const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
1751
- if (newVariant && newVariant.id !== variant?.id) {
1752
- setVariant(newVariant);
1753
- } else if (!newVariant) {
1754
- setVariant(getFirstAvailableVariant(product));
1755
- }
1756
- }, [selectedOptions, product, variant?.id]);
1757
- return variant;
1758
- }
1759
- var FAKE_PRICE = 999999999e-2;
1760
- function formatPrice({
1761
- amount,
1762
- currencyCode,
1763
- locale,
1764
- maximumFractionDigits,
1765
- minimumFractionDigits,
1766
- removeTrailingZeros
1767
- }) {
1768
- const formatter = new Intl.NumberFormat(locale, {
1769
- style: "currency",
1770
- currency: currencyCode,
1771
- maximumFractionDigits: maximumFractionDigits ?? 2,
1772
- 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
1773
1713
  });
1774
- let formatted = formatter.format(amount);
1775
- if (removeTrailingZeros) {
1776
- formatted = formatted.replace(/\.00$/, "");
1777
- }
1778
- return formatted;
1779
- }
1780
- function formatVariantPrice({
1781
- amount,
1782
- baseAmount,
1783
- currencyCode,
1784
- locale,
1785
- maximumFractionDigits,
1786
- minimumFractionDigits,
1787
- removeTrailingZeros
1788
- }) {
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]);
1789
1726
  return {
1790
- price: formatPrice({
1791
- amount,
1792
- currencyCode,
1793
- locale,
1794
- maximumFractionDigits,
1795
- minimumFractionDigits,
1796
- removeTrailingZeros
1797
- }),
1798
- basePrice: formatPrice({
1799
- amount: baseAmount,
1800
- currencyCode,
1801
- locale,
1802
- maximumFractionDigits,
1803
- minimumFractionDigits,
1804
- removeTrailingZeros
1805
- })
1727
+ monthlyVariant: monthlyVariant ? {
1728
+ ...monthlyVariant,
1729
+ product: monthlyProduct
1730
+ } : void 0,
1731
+ annualVariant: annualVariant ? {
1732
+ ...annualVariant,
1733
+ product: annualProduct
1734
+ } : void 0
1806
1735
  };
1807
1736
  }
1808
- function usePrice({
1809
- amount,
1810
- baseAmount,
1811
- currencyCode,
1812
- soldOutDescription = "",
1813
- maximumFractionDigits,
1814
- minimumFractionDigits,
1815
- removeTrailingZeros
1816
- }) {
1817
- const { locale } = useShopify();
1818
- const value = react.useMemo(() => {
1819
- if (typeof amount !== "number" || !currencyCode) {
1820
- return "";
1821
- }
1822
- if (soldOutDescription && amount >= FAKE_PRICE) {
1823
- 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());
1824
1744
  }
1825
- return baseAmount ? formatVariantPrice({
1826
- amount,
1827
- baseAmount,
1828
- currencyCode,
1829
- locale,
1830
- maximumFractionDigits,
1831
- minimumFractionDigits,
1832
- removeTrailingZeros
1833
- }) : formatPrice({
1834
- amount,
1835
- currencyCode,
1836
- locale,
1837
- maximumFractionDigits,
1838
- minimumFractionDigits,
1839
- 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
+ };
1840
1788
  });
1841
1789
  }, [
1842
- amount,
1843
- baseAmount,
1844
- currencyCode,
1845
- locale,
1846
- maximumFractionDigits,
1847
- minimumFractionDigits,
1848
- soldOutDescription,
1849
- removeTrailingZeros
1790
+ nddOverweight,
1791
+ plus_shipping?.directly,
1792
+ plus_shipping?.shipping_methods,
1793
+ selectedPlusMemberMode,
1794
+ tddOverweight,
1795
+ variant?.weight
1850
1796
  ]);
1851
- const result = react.useMemo(() => {
1852
- const free = Boolean(amount && amount <= 0);
1853
- return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
1854
- }, [value, amount]);
1855
- return result;
1856
- }
1857
- function optionsConstructor(selectedOptions) {
1858
- return selectedOptions.reduce((acc, option) => {
1859
- acc[option.name] = option.value;
1860
- return acc;
1861
- }, {});
1862
- }
1863
- function decodeShopifyId(gid) {
1864
- try {
1865
- const base64 = gid.split("/").pop() || "";
1866
- return atob(base64);
1867
- } catch {
1868
- return gid;
1869
- }
1870
- }
1871
- function useSelectedOptions(product, sku) {
1872
- const [options, setOptions] = react.useState({});
1873
- react.useEffect(() => {
1874
- if (!product || !product.variants.length) {
1875
- setOptions({});
1876
- return;
1877
- }
1878
- let variant = product.variants[0];
1879
- if (typeof window !== "undefined") {
1880
- const searchParams = new URLSearchParams(window.location.search);
1881
- const variantIdParam = searchParams.get("variant");
1882
- if (variantIdParam) {
1883
- const foundVariant = product.variants.find((v) => {
1884
- if (sku) return v.sku === sku;
1885
- return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
1886
- });
1887
- if (foundVariant) {
1888
- variant = foundVariant;
1889
- }
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;
1890
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
+ });
1891
1832
  }
1892
- if (variant) {
1893
- const newOptions = optionsConstructor(variant.selectedOptions);
1894
- setOptions(newOptions);
1895
- }
1896
- }, [product, sku]);
1897
- return [options, setOptions];
1898
- }
1899
- function decodeShopifyId2(gid) {
1900
- try {
1901
- const parts = gid.split("/");
1902
- return parts[parts.length - 1] || gid;
1903
- } catch {
1904
- return gid;
1905
- }
1906
- }
1907
- function useProductUrl(otherQuery) {
1908
- const { routerAdapter } = useShopify();
1909
- return react.useCallback(
1910
- ({ product, variant }) => {
1911
- if (!product) return "";
1912
- const queryParams = new URLSearchParams();
1913
- if (variant?.id) {
1914
- const variantId = decodeShopifyId2(variant.id);
1915
- if (variantId) {
1916
- 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;
1917
1853
  }
1918
1854
  }
1919
- if (otherQuery) {
1920
- Object.entries(otherQuery).forEach(([key, value]) => {
1921
- queryParams.set(key, value);
1922
- });
1923
- }
1924
- const queryString = queryParams.toString();
1925
- const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
1926
- if (routerAdapter?.getLocalizedPath) {
1927
- 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 : ""
1928
1927
  }
1929
- 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;
1930
1987
  },
1931
- [routerAdapter, otherQuery]
1988
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1932
1989
  );
1990
+ return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1933
1991
  }
1934
- function decodeShopifyId3(gid) {
1935
- try {
1936
- const parts = gid.split("/");
1937
- return parts[parts.length - 1] || gid;
1938
- } catch {
1939
- return gid;
1940
- }
1941
- }
1942
- 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();
1943
2001
  react.useEffect(() => {
1944
- if (!variant || typeof window === "undefined") {
1945
- 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);
1946
2016
  }
1947
- const searchParams = new URLSearchParams(window.location.search);
1948
- const currentVariantId = searchParams.get("variant");
1949
- const newVariantId = decodeShopifyId3(variant.id);
1950
- if (newVariantId && currentVariantId !== newVariantId) {
1951
- searchParams.set("variant", newVariantId);
1952
- const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
1953
- window.history.replaceState({}, "", newUrl);
2017
+ if (profile?.isAnnualPlus) {
2018
+ removePlusProduct(plus_annual_product);
1954
2019
  }
1955
- }, [variant]);
2020
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
1956
2021
  }
1957
- function getVariantMediaList({
1958
- product,
1959
- variant
2022
+ function hasPlusMemberInCart({
2023
+ memberSetting,
2024
+ cart
1960
2025
  }) {
1961
- if (variant.image?.url) {
1962
- const variantMediaId = variant.image.url;
1963
- const variantMedia = product.media.filter((media) => {
1964
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
1965
- return media.previewImage?.url === variantMediaId;
1966
- }
1967
- return false;
1968
- });
1969
- if (variantMedia.length > 0) {
1970
- const otherMedia = product.media.filter((media) => {
1971
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
1972
- return media.previewImage.url !== variantMediaId;
1973
- }
1974
- return true;
1975
- });
1976
- return [...variantMedia, ...otherMedia];
1977
- }
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
+ };
1978
2033
  }
1979
- 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
+ };
1980
2050
  }
1981
- function useVariantMedia({
1982
- product,
1983
- variant
2051
+ function useHasPlusMemberInCart({
2052
+ memberSetting,
2053
+ cart
1984
2054
  }) {
1985
- const [imageList, setImageList] = react.useState([]);
1986
- const [sceneList, setSceneList] = react.useState([]);
1987
- const [videoList, setVideoList] = react.useState([]);
1988
- react.useEffect(() => {
1989
- if (!product || !variant) {
1990
- setImageList([]);
1991
- setSceneList([]);
1992
- setVideoList([]);
1993
- return;
1994
- }
1995
- const mediaList = getVariantMediaList({ product, variant });
1996
- const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
1997
- const videos = mediaList.filter(
1998
- (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
1999
- );
2000
- setImageList(images.length > 0 && images[0] ? [images[0]] : []);
2001
- setSceneList(images.length > 1 ? images.slice(1) : []);
2002
- setVideoList(videos);
2003
- }, [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;
2004
2088
  return {
2005
- productList: imageList,
2006
- sceneList,
2007
- videoList
2089
+ hasPlusMember,
2090
+ hasMonthlyPlus,
2091
+ hasAnnualPlus,
2092
+ monthlyPlusLine,
2093
+ annualPlusLine
2008
2094
  };
2009
2095
  }
2010
- function useCollection(options = {}) {
2011
- const { client, locale } = useShopify();
2012
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2013
- return useSWR__default.default(
2014
- handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2015
- () => shopifySdk.getCollection(client, {
2016
- handle,
2017
- locale,
2018
- metafieldIdentifiers
2096
+ function useHasPlusMemberInLines({
2097
+ memberSetting,
2098
+ lines
2099
+ }) {
2100
+ return react.useMemo(
2101
+ () => hasPlusMemberInLines({
2102
+ memberSetting,
2103
+ lines
2019
2104
  }),
2020
- swrOptions
2105
+ [memberSetting, lines]
2021
2106
  );
2022
2107
  }
2023
- function useAllCollections(options = {}) {
2024
- const { client, locale } = useShopify();
2025
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2026
- return useSWR__default.default(
2027
- ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2028
- () => shopifySdk.getAllCollections(client, {
2029
- locale,
2030
- first,
2031
- query,
2032
- sortKey,
2033
- reverse,
2034
- metafieldIdentifiers
2035
- }),
2036
- swrOptions
2037
- );
2038
- }
2039
- function useCollections(options = {}) {
2040
- const { client, locale } = useShopify();
2041
- const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2042
- return useSWR__default.default(
2043
- ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2044
- () => shopifySdk.getCollections(client, {
2045
- locale,
2046
- first,
2047
- after,
2048
- query,
2049
- sortKey,
2050
- reverse,
2051
- metafieldIdentifiers
2052
- }),
2053
- swrOptions
2054
- );
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;
2055
2136
  }
2056
- function useBlog(options = {}) {
2057
- const { client, locale } = useShopify();
2058
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2059
- return useSWR__default.default(
2060
- handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2061
- () => shopifySdk.getBlog(client, { handle, locale, metafieldIdentifiers }),
2062
- 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
2063
2147
  );
2064
- }
2065
- function useAllBlogs(options = {}) {
2066
- const { client, locale } = useShopify();
2067
- const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2068
- return useSWR__default.default(
2069
- ["all-blogs", locale, first, query, metafieldIdentifiers],
2070
- () => shopifySdk.getAllBlogs(client, {
2071
- locale,
2072
- first,
2073
- query,
2074
- metafieldIdentifiers
2075
- }),
2076
- 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
+ }
2077
2187
  );
2078
- }
2079
- function useArticle(options = {}) {
2080
- const { client, locale } = useShopify();
2081
- const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2082
- return useSWR__default.default(
2083
- blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2084
- () => shopifySdk.getArticle(client, {
2085
- blogHandle,
2086
- articleHandle,
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;
2260
+ }
2261
+ } else {
2262
+ await removeInvalidCodes({
2263
+ discountCodes: unapplicableCodes
2264
+ });
2265
+ }
2266
+ }
2267
+ }
2268
+ if (resultCart && discountCodes && discountCodes.length > 0) {
2269
+ applyCartCodes({
2270
+ replaceExistingCodes,
2271
+ discountCodes
2272
+ });
2273
+ }
2274
+ if (customAttributes && customAttributes.length > 0) {
2275
+ addCustomAttributes(customAttributes);
2276
+ }
2277
+ }
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,
2087
2290
  locale,
2088
- metafieldIdentifiers
2089
- }),
2090
- swrOptions
2291
+ cartCookieAdapter,
2292
+ userAdapter,
2293
+ cart,
2294
+ withTrack,
2295
+ performanceAdapter,
2296
+ createCart4,
2297
+ addCartLines2,
2298
+ applyCartCodes,
2299
+ removeInvalidCodes,
2300
+ addCustomAttributes,
2301
+ config
2302
+ ]
2091
2303
  );
2304
+ return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
2092
2305
  }
2093
- function useArticles(options = {}) {
2094
- const { client, locale } = useShopify();
2095
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2096
- return useSWR__default.default(
2097
- ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2098
- () => shopifySdk.getArticles(client, {
2099
- locale,
2100
- first,
2101
- query,
2102
- sortKey,
2103
- reverse,
2104
- metafieldIdentifiers
2105
- }),
2106
- 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]
2107
2323
  );
2324
+ return useSWRMutation__default.default("update-cart-lines", updateLines, options);
2108
2325
  }
2109
- function useArticlesInBlog(options = {}) {
2110
- const { client, locale } = useShopify();
2111
- const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2112
- return useSWR__default.default(
2113
- blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2114
- () => shopifySdk.getArticlesInBlog(client, {
2115
- blogHandle,
2116
- locale,
2117
- first,
2118
- sortKey,
2119
- reverse,
2120
- metafieldIdentifiers
2121
- }),
2122
- swrOptions
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]
2123
2349
  );
2350
+ return useSWRMutation__default.default("update-cart-attributes", updateAttributes, swrOptions);
2124
2351
  }
2125
- async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2126
- if (!searchQuery) {
2127
- return void 0;
2128
- }
2129
- const query = (
2130
- /* GraphQL */
2131
- `
2132
- query search($query: String!, $first: Int!, $types: [SearchType!])
2133
- @inContext(language: $language) {
2134
- search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2135
- totalCount
2136
- edges {
2137
- node {
2138
- ... on Article {
2139
- __typename
2140
- id
2141
- handle
2142
- title
2143
- excerpt
2144
- image {
2145
- url
2146
- altText
2147
- }
2148
- }
2149
- ... on Page {
2150
- __typename
2151
- id
2152
- handle
2153
- title
2154
- }
2155
- ... on Product {
2156
- __typename
2157
- id
2158
- handle
2159
- title
2160
- description
2161
- featuredImage {
2162
- url
2163
- altText
2164
- }
2165
- }
2166
- }
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 = true
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 });
2167
2412
  }
2168
- pageInfo {
2169
- hasNextPage
2170
- endCursor
2413
+ }
2414
+ if (redirectToCheckout) {
2415
+ if (resultCart.url) {
2416
+ if (typeof window !== "undefined") {
2417
+ window.location.href = resultCart.url;
2418
+ }
2419
+ } else {
2420
+ throw new Error("Failed to get checkout URL");
2171
2421
  }
2172
2422
  }
2173
- }
2174
- `
2423
+ return resultCart;
2424
+ },
2425
+ [client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
2175
2426
  );
2176
- const data = await client.query(query, {
2177
- query: searchQuery,
2178
- first,
2179
- types
2180
- });
2181
- if (!data || !data.search) {
2182
- return void 0;
2183
- }
2184
- const items = data.search.edges?.map((edge) => {
2185
- const node = edge.node;
2186
- const item = {
2187
- type: node.__typename.toUpperCase(),
2188
- id: node.id,
2189
- handle: node.handle,
2190
- title: node.title
2191
- };
2192
- if (node.__typename === "Product") {
2193
- item.description = node.description;
2194
- item.image = node.featuredImage ? {
2195
- url: node.featuredImage.url,
2196
- altText: node.featuredImage.altText
2197
- } : void 0;
2198
- } else if (node.__typename === "Article") {
2199
- item.description = node.excerpt;
2200
- item.image = node.image ? {
2201
- url: node.image.url,
2202
- altText: node.image.altText
2203
- } : void 0;
2204
- }
2205
- return item;
2206
- }) || [];
2207
- return {
2208
- items,
2209
- totalCount: data.search.totalCount || 0,
2210
- pageInfo: data.search.pageInfo
2211
- };
2427
+ return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
2212
2428
  }
2213
- function useSearch(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 = {}) {
2214
2442
  const { client, locale } = useShopify();
2215
- const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2443
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2216
2444
  return useSWR__default.default(
2217
- query ? ["search", locale, query, first, types] : null,
2218
- () => performSearch(client, locale, query, first, types),
2445
+ handle ? ["product", locale, handle, metafieldIdentifiers] : null,
2446
+ () => shopifySdk.getProduct(client, {
2447
+ handle,
2448
+ locale,
2449
+ metafieldIdentifiers
2450
+ }),
2219
2451
  swrOptions
2220
2452
  );
2221
2453
  }
2222
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
2223
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2224
- const query = (
2225
- /* GraphQL */
2226
- `
2227
- query getSiteInfo(
2228
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2229
- ) @inContext(language: $language) {
2230
- shop {
2231
- name
2232
- description
2233
- primaryDomain {
2234
- url
2235
- host
2236
- }
2237
- brand {
2238
- logo {
2239
- image {
2240
- url
2241
- }
2242
- }
2243
- colors {
2244
- primary {
2245
- background
2246
- }
2247
- secondary {
2248
- background
2249
- }
2250
- }
2251
- }
2252
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2253
- }
2254
- }
2255
- `
2256
- );
2257
- const variables = {};
2258
- if (hasMetafields) {
2259
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2260
- }
2261
- const data = await client.query(query, variables);
2262
- if (!data || !data.shop) {
2263
- return void 0;
2264
- }
2265
- const shop = data.shop;
2266
- const metafields = shop.metafields?.reduce((acc, mf) => {
2267
- if (mf && mf.key) {
2268
- acc[mf.key] = mf.value;
2269
- }
2270
- return acc;
2271
- }, {});
2272
- return {
2273
- name: shop.name,
2274
- description: shop.description,
2275
- primaryDomain: shop.primaryDomain,
2276
- brand: shop.brand ? {
2277
- logo: shop.brand.logo,
2278
- colors: shop.brand.colors ? {
2279
- primary: shop.brand.colors.primary?.background,
2280
- secondary: shop.brand.colors.secondary?.background
2281
- } : void 0
2282
- } : void 0,
2283
- metafields
2284
- };
2285
- }
2286
- function useSite(options = {}) {
2454
+ function useAllProducts(options = {}) {
2287
2455
  const { client, locale } = useShopify();
2288
- const { metafieldIdentifiers, ...swrOptions } = options;
2456
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2289
2457
  return useSWR__default.default(
2290
- ["site", locale, metafieldIdentifiers],
2291
- () => getSiteInfo(client, locale, metafieldIdentifiers),
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
+ }),
2292
2467
  swrOptions
2293
2468
  );
2294
2469
  }
2295
-
2296
- // src/hooks/member/plus/types.ts
2297
- var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
2298
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
2299
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
2300
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
2301
- return PLUS_MEMBER_TYPE2;
2302
- })(PLUS_MEMBER_TYPE || {});
2303
- var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
2304
- PlusMemberMode2["MONTHLY"] = "monthly";
2305
- PlusMemberMode2["ANNUAL"] = "annual";
2306
- return PlusMemberMode2;
2307
- })(PlusMemberMode || {});
2308
- var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
2309
- DeliveryPlusType2["FREE"] = "free";
2310
- DeliveryPlusType2["MONTHLY"] = "monthly";
2311
- DeliveryPlusType2["ANNUAL"] = "annual";
2312
- return DeliveryPlusType2;
2313
- })(DeliveryPlusType || {});
2314
- var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
2315
- ShippingMethodMode2["FREE"] = "free";
2316
- ShippingMethodMode2["TDD"] = "tdd";
2317
- ShippingMethodMode2["NDD"] = "ndd";
2318
- return ShippingMethodMode2;
2319
- })(ShippingMethodMode || {});
2320
- var createInitialValue = () => ({
2321
- zipCode: "",
2322
- plusMemberMetafields: {},
2323
- setZipCode: () => {
2324
- },
2325
- allowNextDayDelivery: false,
2326
- setAllowNextDayDelivery: () => {
2327
- },
2328
- allowThirdDayDelivery: false,
2329
- setAllowThirdDayDelivery: () => {
2330
- },
2331
- selectedPlusMemberMode: "free",
2332
- setSelectedPlusMemberMode: () => {
2333
- },
2334
- showAreaCheckModal: false,
2335
- setShowAreaCheckModal: () => {
2336
- },
2337
- selectedShippingMethod: void 0,
2338
- setSelectedShippingMethod: () => {
2339
- },
2340
- showTip: false,
2341
- setShowTip: () => {
2342
- },
2343
- showMoreShippingMethod: false,
2344
- setShowMoreShippingMethod: () => {
2345
- },
2346
- variant: {},
2347
- product: {},
2348
- shippingMethodsContext: {
2349
- freeShippingMethods: [],
2350
- paymentShippingMethods: [],
2351
- nddOverweight: false,
2352
- tddOverweight: false
2353
- },
2354
- selectedPlusMemberProduct: null,
2355
- plusMemberProducts: [],
2356
- showPlusMemberBenefit: false,
2357
- setShowPlusMemberBenefit: () => {
2358
- },
2359
- deleteMarginBottom: false,
2360
- setDeleteMarginBottom: () => {
2361
- },
2362
- profile: void 0,
2363
- locale: void 0
2364
- });
2365
- var PlusMemberContext = react.createContext(createInitialValue());
2366
- function usePlusMemberContext() {
2367
- return react.useContext(PlusMemberContext);
2470
+ function getFirstAvailableVariant(product) {
2471
+ const availableVariant = product.variants.find((v) => v.availableForSale);
2472
+ return availableVariant || product.variants[0];
2368
2473
  }
2369
- function usePlusMonthlyProductVariant() {
2370
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2371
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2372
- const plusMonthlyProductVariant = react.useMemo(() => {
2373
- const product = plusMemberProducts?.find(
2374
- (item) => item?.handle === plusMonthly?.handle
2375
- );
2376
- const productVariant = product?.variants?.find(
2377
- (item) => item.sku === plusMonthly?.sku
2378
- );
2379
- return productVariant;
2380
- }, [plusMemberProducts, plusMonthly]);
2381
- return plusMonthlyProductVariant;
2474
+ function getVariantFromSelectedOptions(product, selectedOptions) {
2475
+ return product.variants.find((variant) => {
2476
+ return variant.selectedOptions.every((option) => {
2477
+ return selectedOptions[option.name] === option.value;
2478
+ });
2479
+ });
2382
2480
  }
2383
- function usePlusAnnualProductVariant() {
2384
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2385
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2386
- const plusAnnualProductVariant = react.useMemo(() => {
2387
- const product = plusMemberProducts?.find(
2388
- (item) => item?.handle === plusAnnual?.handle
2389
- );
2390
- const productVariant = product?.variants?.find(
2391
- (item) => item.sku === plusAnnual?.sku
2392
- );
2393
- return productVariant;
2394
- }, [plusMemberProducts, plusAnnual]);
2395
- return plusAnnualProductVariant;
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;
2492
+ }
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;
2396
2501
  }
2397
- function useShippingMethods(options) {
2398
- const {
2399
- variant,
2400
- plusMemberMetafields,
2401
- selectedPlusMemberMode,
2402
- isPlus = false,
2403
- nddCoupon,
2404
- tddCoupon
2405
- } = options;
2406
- const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2407
- const nddOverweight = react.useMemo(() => {
2408
- return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
2409
- }, [shippingMethod?.overWeight_ndd, variant?.weight]);
2410
- const tddOverweight = react.useMemo(() => {
2411
- return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
2412
- }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2413
- const paymentShippingMethods = react.useMemo(() => {
2414
- const weight = variant?.weight || 0;
2415
- const methods = plus_shipping?.shipping_methods?.filter(
2416
- ({ weight_low, weight_high, __mode, __plus }) => {
2417
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2418
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2419
- }
2420
- ) || [];
2421
- return methods.map((method) => {
2422
- let disabled = false;
2423
- const selectedFreeMember = selectedPlusMemberMode === "free";
2424
- if (method.__mode === "ndd" /* NDD */) {
2425
- disabled = selectedFreeMember || nddOverweight;
2426
- } else if (method.__mode === "tdd" /* TDD */) {
2427
- disabled = selectedFreeMember || tddOverweight;
2428
- }
2429
- return {
2430
- ...method,
2431
- id: method.__mode + method.__code,
2432
- useCoupon: false,
2433
- subtitle: plus_shipping?.directly || "",
2434
- disabled
2435
- };
2436
- });
2437
- }, [
2438
- nddOverweight,
2439
- plus_shipping?.directly,
2440
- plus_shipping?.shipping_methods,
2441
- selectedPlusMemberMode,
2442
- tddOverweight,
2443
- variant?.weight
2444
- ]);
2445
- const nddPrice = react.useMemo(() => {
2446
- const weight = variant?.weight || 0;
2447
- const nddMethod = paymentShippingMethods.find(
2448
- ({ __mode, weight_high, weight_low }) => {
2449
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2450
- return __mode === "ndd" && fitWeight;
2451
- }
2452
- );
2453
- return nddMethod?.price || 0;
2454
- }, [variant?.weight, paymentShippingMethods]);
2455
- const tddPrice = react.useMemo(() => {
2456
- const weight = variant?.weight || 0;
2457
- const tddMethod = paymentShippingMethods.find(
2458
- ({ __mode, weight_high, weight_low }) => {
2459
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2460
- return __mode === "tdd" && fitWeight;
2461
- }
2462
- );
2463
- return tddMethod?.price || 0;
2464
- }, [variant?.weight, paymentShippingMethods]);
2465
- const freeShippingMethods = react.useMemo(() => {
2466
- const weight = variant?.weight || 0;
2467
- let methods = plus_shipping?.shipping_methods?.filter(
2468
- ({ __mode, __plus, weight_low, weight_high }) => {
2469
- if (__mode === "free" /* FREE */) {
2470
- return true;
2471
- }
2472
- if (isPlus) {
2473
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2474
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2475
- return hasCoupon && fitWeight && !__plus;
2476
- } else {
2477
- return __plus;
2478
- }
2479
- }
2480
- ) || [];
2481
- if (isPlus) {
2482
- methods = methods.sort((a, b) => {
2483
- if (b.__mode === "free" /* FREE */) return -1;
2484
- return 0;
2485
- });
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
+ }) {
2532
+ return {
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
+ })
2549
+ };
2550
+ }
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 "";
2486
2564
  }
2487
- return methods.map((method) => {
2488
- let price = 0;
2489
- let coupon;
2490
- let disabled;
2491
- if (method.__mode !== "free" /* FREE */) {
2492
- switch (method.__mode) {
2493
- case "tdd":
2494
- price = tddPrice;
2495
- coupon = tddCoupon || nddCoupon;
2496
- break;
2497
- case "ndd":
2498
- price = nddPrice;
2499
- coupon = nddCoupon;
2500
- break;
2501
- }
2502
- disabled = selectedPlusMemberMode === "free";
2503
- if (method.__mode === "ndd" /* NDD */) {
2504
- disabled = disabled || nddOverweight;
2505
- } else if (method.__mode === "tdd" /* TDD */) {
2506
- disabled = disabled || tddOverweight;
2507
- }
2508
- }
2509
- return {
2510
- ...method,
2511
- id: method.__mode + method.__code,
2512
- useCoupon: true,
2513
- disabled,
2514
- coupon,
2515
- price
2516
- };
2565
+ if (soldOutDescription && amount >= FAKE_PRICE) {
2566
+ return soldOutDescription;
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
2517
2583
  });
2518
2584
  }, [
2519
- variant?.weight,
2520
- plus_shipping?.shipping_methods,
2521
- isPlus,
2522
- nddCoupon,
2523
- tddCoupon,
2524
- selectedPlusMemberMode,
2525
- tddPrice,
2526
- nddPrice,
2527
- nddOverweight,
2528
- tddOverweight
2585
+ amount,
2586
+ baseAmount,
2587
+ currencyCode,
2588
+ locale,
2589
+ maximumFractionDigits,
2590
+ minimumFractionDigits,
2591
+ soldOutDescription,
2592
+ removeTrailingZeros
2529
2593
  ]);
2530
- return {
2531
- freeShippingMethods,
2532
- paymentShippingMethods,
2533
- nddOverweight,
2534
- tddOverweight
2535
- };
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;
2536
2599
  }
2537
- function useShippingMethodAvailableCheck() {
2538
- const {
2539
- zipCode,
2540
- allowNextDayDelivery,
2541
- allowThirdDayDelivery,
2542
- selectedShippingMethod,
2543
- setSelectedShippingMethod,
2544
- setShowTip,
2545
- shippingMethodsContext
2546
- } = usePlusMemberContext();
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({});
2547
2616
  react.useEffect(() => {
2548
- const freeShippingMethod = shippingMethodsContext.freeShippingMethods[0];
2549
- const standardShippingMethod = shippingMethodsContext.freeShippingMethods?.find(
2550
- (item) => item.__mode === "free" /* FREE */
2551
- );
2552
- const freeTDD = shippingMethodsContext.freeShippingMethods.find(
2553
- (item) => item.__mode === "tdd" /* TDD */
2554
- );
2555
- const paymentTDD = shippingMethodsContext.paymentShippingMethods.find(
2556
- (item) => item.__mode === "tdd" /* TDD */
2557
- );
2558
- if (zipCode) {
2559
- console.log(
2560
- "allowNextDayDelivery, allowThirdDayDelivery:",
2561
- allowNextDayDelivery,
2562
- allowThirdDayDelivery
2563
- );
2564
- if (!allowNextDayDelivery && !allowThirdDayDelivery) {
2565
- setShowTip(true);
2566
- setSelectedShippingMethod(standardShippingMethod);
2567
- } else {
2568
- if (selectedShippingMethod?.__mode === "ndd" /* NDD */ && !allowNextDayDelivery) {
2569
- setShowTip(true);
2570
- if (allowThirdDayDelivery) {
2571
- if (selectedShippingMethod.useCoupon) {
2572
- const method = freeTDD || freeShippingMethod;
2573
- if (method) setSelectedShippingMethod(method);
2574
- } else {
2575
- const method = paymentTDD || freeShippingMethod;
2576
- if (method) setSelectedShippingMethod(method);
2577
- }
2578
- } else {
2579
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2580
- }
2581
- } else if (
2582
- // TDD 无法使用
2583
- selectedShippingMethod?.__mode === "tdd" /* TDD */ && !allowThirdDayDelivery
2584
- ) {
2585
- setShowTip(true);
2586
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2617
+ if (!product || !product.variants.length) {
2618
+ setOptions({});
2619
+ return;
2620
+ }
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;
2587
2632
  }
2588
2633
  }
2589
2634
  }
2590
- }, [
2591
- allowNextDayDelivery,
2592
- allowThirdDayDelivery,
2593
- zipCode,
2594
- shippingMethodsContext,
2595
- selectedShippingMethod,
2596
- setSelectedShippingMethod,
2597
- setShowTip
2598
- ]);
2599
- }
2600
- var useReplaceCartPlusMember = () => {
2601
- const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
2602
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2603
- const { cart } = useCartContext();
2604
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2605
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2606
- const handler = react.useCallback(async () => {
2607
- const plusMonthlyInCart = cart?.lineItems.find(
2608
- (item) => item.variant?.sku === plusMonthly?.sku
2609
- );
2610
- const plusAnnualInCart = cart?.lineItems.find(
2611
- (item) => item.variant?.sku === plusAnnual?.sku
2612
- );
2613
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
2614
- await removeCartLines2({
2615
- lineIds: [plusMonthlyInCart.id]
2616
- });
2617
- } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
2618
- await removeCartLines2({
2619
- lineIds: [plusAnnualInCart.id]
2620
- });
2621
- }
2622
- }, [
2623
- cart?.lineItems,
2624
- selectedPlusMemberMode,
2625
- plusMonthly?.sku,
2626
- plusAnnual?.sku,
2627
- removeCartLines2
2628
- ]);
2629
- return handler;
2630
- };
2631
- var usePlusMemberDeliveryCodes = ({
2632
- deliveryData
2633
- }) => {
2634
- return react.useMemo(
2635
- () => deliveryData?.deliveryCustomData?.discount_code,
2636
- [deliveryData]
2637
- );
2638
- };
2639
- var usePlusMemberItemCustomAttributes = ({
2640
- deliveryData
2641
- }) => {
2642
- const { deliveryCustomData } = deliveryData || {};
2643
- return react.useMemo(() => {
2644
- const itemCustomAttributes = [];
2645
- if (deliveryCustomData?.is_presale) {
2646
- itemCustomAttributes.push({
2647
- key: "_is_presale",
2648
- value: "true"
2649
- });
2635
+ if (variant) {
2636
+ const newOptions = optionsConstructor(variant.selectedOptions);
2637
+ setOptions(newOptions);
2650
2638
  }
2651
- return itemCustomAttributes;
2652
- }, [deliveryCustomData]);
2653
- };
2654
- var usePlusMemberCheckoutCustomAttributes = ({
2655
- deliveryData,
2656
- product,
2657
- variant,
2658
- customer,
2659
- isShowShippingBenefits
2660
- }) => {
2661
- const { deliveryCustomData } = deliveryData || {};
2662
- const { profile } = usePlusMemberContext();
2663
- const userType = react.useMemo(() => {
2664
- const customerInfo = customer;
2665
- if (!customerInfo) {
2666
- return "new_user_unlogin";
2667
- }
2668
- if (customer) {
2669
- const { orders = {} } = customer;
2670
- const edgesLength = orders?.edges?.length;
2671
- if (edgesLength === 1) {
2672
- return "old_user_orders_once";
2673
- } else if (edgesLength && edgesLength > 1) {
2674
- return "old_user_orders_twice";
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
+ }
2675
2661
  }
2676
- }
2677
- return "new_user_login";
2678
- }, [customer]);
2679
- return react.useMemo(() => {
2680
- const checkoutCustomAttributes = [
2681
- {
2682
- key: "_token",
2683
- value: profile?.token || ""
2684
- },
2685
- {
2686
- key: "_last_url",
2687
- value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2688
- },
2689
- {
2690
- key: "_user_type",
2691
- value: userType
2662
+ if (otherQuery) {
2663
+ Object.entries(otherQuery).forEach(([key, value]) => {
2664
+ queryParams.set(key, value);
2665
+ });
2692
2666
  }
2693
- ];
2694
- if (profile) {
2695
- checkoutCustomAttributes.push({
2696
- key: "_login_user",
2697
- value: "1"
2698
- });
2699
- }
2700
- if (deliveryCustomData) {
2701
- checkoutCustomAttributes.push({
2702
- key: "_checkout_delivery_custom",
2703
- value: JSON.stringify({
2704
- ...deliveryCustomData,
2705
- is_prime: profile?.isPlus
2706
- })
2707
- });
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;
2708
2689
  }
2709
- if (variant?.metafields?.presell) {
2710
- checkoutCustomAttributes.push({
2711
- key: "_presale",
2712
- value: "true"
2713
- });
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);
2714
2697
  }
2715
- if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2716
- checkoutCustomAttributes.push({
2717
- key: "_hide_shipping",
2718
- 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;
2719
2718
  });
2719
+ return [...variantMedia, ...otherMedia];
2720
2720
  }
2721
- return checkoutCustomAttributes;
2722
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2723
- };
2724
- function useAutoRemovePlusMemberInCart({
2725
- cart,
2726
- profile,
2727
- memberSetting
2721
+ }
2722
+ return product.media;
2723
+ }
2724
+ function useVariantMedia({
2725
+ product,
2726
+ variant
2728
2727
  }) {
2729
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2730
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2728
+ const [imageList, setImageList] = react.useState([]);
2729
+ const [sceneList, setSceneList] = react.useState([]);
2730
+ const [videoList, setVideoList] = react.useState([]);
2731
2731
  react.useEffect(() => {
2732
- if (!cart || !plus_monthly_product || !plus_annual_product) return;
2733
- const removePlusProduct = async (productType) => {
2734
- if (!productType) return;
2735
- const product = cart.lineItems?.find(
2736
- (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2737
- );
2738
- if (product) {
2739
- await removeCartLines2({
2740
- lineIds: [product.id]
2741
- });
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
+ }
2742
2915
  }
2743
- };
2744
- if (profile?.isMonthlyPlus) {
2745
- removePlusProduct(plus_monthly_product);
2746
- }
2747
- if (profile?.isAnnualPlus) {
2748
- removePlusProduct(plus_annual_product);
2749
2916
  }
2750
- }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2751
- }
2752
- function useAddPlusMemberProductsToCart({
2753
- cart,
2754
- profile
2755
- }) {
2756
- const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2757
- const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2758
- memberSetting: plusMemberMetafields,
2759
- cart
2917
+ `
2918
+ );
2919
+ const data = await client.query(query, {
2920
+ query: searchQuery,
2921
+ first,
2922
+ types
2760
2923
  });
2761
- const plusMemberProduct = react.useMemo(() => {
2762
- if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2763
- return void 0;
2764
- }
2765
- if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2766
- return void 0;
2767
- }
2768
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2769
- return void 0;
2770
- }
2771
- if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2772
- return void 0;
2773
- }
2774
- if (!profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2775
- 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;
2776
2947
  }
2777
- return selectedPlusMemberProduct;
2778
- }, [
2779
- selectedPlusMemberMode,
2780
- selectedPlusMemberProduct?.variant,
2781
- selectedPlusMemberProduct?.product,
2782
- hasMonthlyPlus,
2783
- hasAnnualPlus
2784
- ]);
2785
- return plusMemberProduct;
2948
+ return item;
2949
+ }) || [];
2950
+ return {
2951
+ items,
2952
+ totalCount: data.search.totalCount || 0,
2953
+ pageInfo: data.search.pageInfo
2954
+ };
2786
2955
  }
2787
- var PlusMemberProvider = ({
2788
- variant,
2789
- product,
2790
- memberSetting,
2791
- initialSelectedPlusMemberMode = "free",
2792
- profile,
2793
- locale,
2794
- children
2795
- }) => {
2796
- const [zipCode, setZipCode] = react.useState("");
2797
- const [showTip, setShowTip] = react.useState(false);
2798
- const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2799
- 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
2800
2963
  );
2801
- const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2802
- const [allowNextDayDelivery, setAllowNextDayDelivery] = react.useState(false);
2803
- const [allowThirdDayDelivery, setAllowThirdDayDelivery] = react.useState(false);
2804
- const [showAreaCheckModal, setShowAreaCheckModal] = react.useState(false);
2805
- const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2806
- const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2807
- const [deleteMarginBottom, setDeleteMarginBottom] = react.useState(false);
2808
- const shippingMethodsContext = useShippingMethods({
2809
- variant,
2810
- plusMemberMetafields: memberSetting,
2811
- selectedPlusMemberMode});
2812
- const plusMemberHandles = react.useMemo(() => {
2813
- return [
2814
- memberSetting?.plus_monthly_product?.handle,
2815
- memberSetting?.plus_annual_product?.handle
2816
- ].filter(Boolean);
2817
- }, [memberSetting]);
2818
- const { data: plusMemberProducts = [] } = useProductsByHandles({
2819
- handles: plusMemberHandles
2820
- });
2821
- const selectedPlusMemberProduct = react.useMemo(() => {
2822
- if (selectedPlusMemberMode === "free" /* FREE */) {
2823
- 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
+ }
2824
2997
  }
2825
- const handle = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.handle : memberSetting?.plus_annual_product?.handle;
2826
- const sku = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.sku : memberSetting?.plus_annual_product?.sku;
2827
- const product2 = plusMemberProducts?.find((p) => p.handle === handle);
2828
- const variant2 = product2?.variants?.find((v) => v.sku === sku);
2829
- return product2 && variant2 ? { product: product2, variant: variant2 } : null;
2830
- }, [plusMemberProducts, memberSetting, selectedPlusMemberMode]);
2831
- return /* @__PURE__ */ jsxRuntime.jsx(
2832
- PlusMemberContext.Provider,
2833
- {
2834
- value: {
2835
- variant,
2836
- zipCode,
2837
- setZipCode,
2838
- allowNextDayDelivery,
2839
- setAllowNextDayDelivery,
2840
- allowThirdDayDelivery,
2841
- setAllowThirdDayDelivery,
2842
- plusMemberMetafields: memberSetting,
2843
- selectedPlusMemberMode,
2844
- setSelectedPlusMemberMode,
2845
- showAreaCheckModal,
2846
- setShowAreaCheckModal,
2847
- selectedShippingMethod,
2848
- setSelectedShippingMethod,
2849
- shippingMethodsContext,
2850
- showTip,
2851
- setShowTip,
2852
- showMoreShippingMethod,
2853
- setShowMoreShippingMethod,
2854
- selectedPlusMemberProduct,
2855
- plusMemberProducts,
2856
- product,
2857
- showPlusMemberBenefit,
2858
- setShowPlusMemberBenefit,
2859
- deleteMarginBottom,
2860
- setDeleteMarginBottom,
2861
- profile,
2862
- locale
2863
- },
2864
- 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;
2865
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
2866
3036
  );
2867
- };
3037
+ }
2868
3038
  function useIntersection(targetRef, options) {
2869
3039
  const {
2870
3040
  callback,
@@ -3058,7 +3228,7 @@ function CartProvider({
3058
3228
  }) {
3059
3229
  const { client, cartCookieAdapter } = useShopify();
3060
3230
  const [customAttributes, setCustomAttributes] = react.useState([]);
3061
- const [customAttributesNeedDelete, setCustomAttributesNeedDelete] = react.useState(
3231
+ const [customAttributesNeedRemove, setCustomAttributesNeedRemove] = react.useState(
3062
3232
  []
3063
3233
  );
3064
3234
  const [isCodeChanging, setIsCodeChanging] = react.useState(false);
@@ -3086,15 +3256,34 @@ function CartProvider({
3086
3256
  refreshDeps: [locale]
3087
3257
  }
3088
3258
  );
3089
- const { trigger: updateAttributes } = useUpdateCartAttributes(mutateCart, metafieldIdentifiers);
3090
- 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" : String(profile?.memberType ?? 0)
3273
+ });
3091
3274
  ahooks.useRequest(
3092
3275
  () => {
3093
- const newAttributes = [...attributes, ...customAttributes];
3094
- 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(
3095
3284
  cart.customAttributes,
3096
3285
  newAttributes,
3097
- customAttributesNeedDelete
3286
+ customAttributesNeedRemove
3098
3287
  );
3099
3288
  if (needUpdate) {
3100
3289
  return updateAttributes({ attributes: newAttributes });
@@ -3107,44 +3296,39 @@ function CartProvider({
3107
3296
  // 1 秒内只触发最后一次更新
3108
3297
  throttleTrailing: true,
3109
3298
  throttleLeading: false,
3110
- refreshDeps: [attributes, customAttributes]
3299
+ refreshDeps: [commonAttributes, customAttributes, customAttributesNeedRemove]
3111
3300
  }
3112
3301
  );
3113
3302
  useUpdateLineCodeAmountAttributes({
3114
3303
  cart,
3115
3304
  mutateCart,
3116
3305
  isCartLoading: isCartLoading || isCodeChanging,
3117
- setLoadingState
3306
+ setLoadingState,
3307
+ metafieldIdentifiers
3118
3308
  });
3119
3309
  const removeCustomAttributes = react.useCallback(
3120
- (attributes2) => {
3121
- setCustomAttributesNeedDelete(attributes2);
3310
+ (attributes) => {
3311
+ setCustomAttributesNeedRemove(attributes);
3122
3312
  },
3123
- [setCustomAttributesNeedDelete]
3313
+ [setCustomAttributesNeedRemove]
3124
3314
  );
3125
3315
  const addCustomAttributes = react.useCallback(
3126
- (attributes2) => {
3127
- const sameAttributes = attributes2.filter(
3128
- (attr) => customAttributes.some((a) => a.key === attr.key)
3129
- );
3130
- if (sameAttributes.length) {
3131
- setCustomAttributes((prev) => {
3132
- const removedAttributes = prev.filter(
3133
- (attr) => !sameAttributes.some((a) => a.key === attr.key)
3134
- );
3135
- return [...removedAttributes, ...attributes2];
3136
- });
3137
- } else {
3138
- setCustomAttributes((prev) => [...prev, ...attributes2]);
3139
- }
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
+ });
3140
3323
  },
3141
- [customAttributes]
3324
+ [setCustomAttributes]
3142
3325
  );
3143
3326
  const functionAutoFreeGiftResult = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer);
3144
3327
  const scriptAutoFreeGiftResult = useScriptAutoFreeGift({
3145
3328
  campaign: gradientGiftsConfig || null,
3146
3329
  _giveaway: CUSTOMER_SCRIPT_GIFT_KEY,
3147
- cart
3330
+ cart,
3331
+ profile
3148
3332
  });
3149
3333
  const formattedScriptGifts = react.useMemo(() => {
3150
3334
  return formatScriptAutoFreeGift({
@@ -3195,16 +3379,23 @@ function CartProvider({
3195
3379
  );
3196
3380
  return result;
3197
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]);
3198
3387
  const value = react.useMemo(
3199
3388
  () => ({
3389
+ totalQuantity,
3200
3390
  cart,
3201
3391
  isCartLoading,
3202
3392
  triggerFetch: fetchCart,
3203
3393
  mutateCart,
3204
3394
  addCustomAttributes,
3205
3395
  removeCustomAttributes,
3206
- setCustomAttributes,
3207
3396
  locale,
3397
+ profile,
3398
+ customer,
3208
3399
  isCodeChanging,
3209
3400
  setIsCodeChanging,
3210
3401
  autoFreeGiftConfig,
@@ -3220,10 +3411,12 @@ function CartProvider({
3220
3411
  scriptAutoFreeGiftResult,
3221
3412
  setScriptAutoFreeGift,
3222
3413
  giftNeedAddToCartLines,
3223
- metafieldIdentifiers
3414
+ metafieldIdentifiers,
3415
+ memberSetting
3224
3416
  }),
3225
3417
  [
3226
3418
  cart,
3419
+ totalQuantity,
3227
3420
  isCartLoading,
3228
3421
  fetchCart,
3229
3422
  mutateCart,
@@ -3243,43 +3436,23 @@ function CartProvider({
3243
3436
  scriptAutoFreeGiftResult,
3244
3437
  setScriptAutoFreeGift,
3245
3438
  giftNeedAddToCartLines,
3246
- metafieldIdentifiers
3439
+ metafieldIdentifiers,
3440
+ customer,
3441
+ profile,
3442
+ memberSetting
3247
3443
  ]
3248
3444
  );
3249
3445
  return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
3250
3446
  }
3251
- function useCartContext() {
3447
+ function useCartContext(options) {
3252
3448
  const context = react.useContext(CartContext);
3253
- if (!context) {
3449
+ if (!context && !options?.optional) {
3254
3450
  throw new Error("useCartContext must be used within a CartProvider");
3255
3451
  }
3256
3452
  return context;
3257
3453
  }
3258
3454
 
3259
- Object.defineProperty(exports, "ShopifyConfig", {
3260
- enumerable: true,
3261
- get: function () { return shopifySdk.ShopifyConfig; }
3262
- });
3263
- Object.defineProperty(exports, "clearLocalStorage", {
3264
- enumerable: true,
3265
- get: function () { return shopifySdk.clearLocalStorage; }
3266
- });
3267
- Object.defineProperty(exports, "createShopifyClient", {
3268
- enumerable: true,
3269
- get: function () { return shopifySdk.createShopifyClient; }
3270
- });
3271
- Object.defineProperty(exports, "getLocalStorage", {
3272
- enumerable: true,
3273
- get: function () { return shopifySdk.getLocalStorage; }
3274
- });
3275
- Object.defineProperty(exports, "removeLocalStorage", {
3276
- enumerable: true,
3277
- get: function () { return shopifySdk.removeLocalStorage; }
3278
- });
3279
- Object.defineProperty(exports, "setLocalStorage", {
3280
- enumerable: true,
3281
- get: function () { return shopifySdk.setLocalStorage; }
3282
- });
3455
+ exports.BrowserPerformanceAdapter = BrowserPerformanceAdapter;
3283
3456
  exports.BuyRuleType = BuyRuleType;
3284
3457
  exports.CODE_AMOUNT_KEY = CODE_AMOUNT_KEY;
3285
3458
  exports.CUSTOMER_ATTRIBUTE_KEY = CUSTOMER_ATTRIBUTE_KEY;
@@ -3287,6 +3460,7 @@ exports.CUSTOMER_SCRIPT_GIFT_KEY = CUSTOMER_SCRIPT_GIFT_KEY;
3287
3460
  exports.CartProvider = CartProvider;
3288
3461
  exports.DeliveryPlusType = DeliveryPlusType;
3289
3462
  exports.MAIN_PRODUCT_CODE = MAIN_PRODUCT_CODE;
3463
+ exports.MEMBER_PRICE_ATTRIBUTE_KEY = MEMBER_PRICE_ATTRIBUTE_KEY;
3290
3464
  exports.OrderBasePriceType = OrderBasePriceType;
3291
3465
  exports.OrderDiscountType = OrderDiscountType;
3292
3466
  exports.PLUS_MEMBER_TYPE = PLUS_MEMBER_TYPE;
@@ -3301,11 +3475,8 @@ exports.ShippingMethodMode = ShippingMethodMode;
3301
3475
  exports.ShopifyContext = ShopifyContext;
3302
3476
  exports.ShopifyProvider = ShopifyProvider;
3303
3477
  exports.SpendMoneyType = SpendMoneyType;
3304
- exports.atobID = atobID;
3305
3478
  exports.browserCartCookieAdapter = browserCartCookieAdapter;
3306
3479
  exports.browserCookieAdapter = browserCookieAdapter;
3307
- exports.btoaID = btoaID;
3308
- exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
3309
3480
  exports.clearGeoLocationCache = clearGeoLocationCache;
3310
3481
  exports.createMockCartFromLines = createMockCartFromLines;
3311
3482
  exports.currencyCodeMapping = currencyCodeMapping;
@@ -3314,10 +3485,14 @@ exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
3314
3485
  exports.formatScriptAutoFreeGift = formatScriptAutoFreeGift;
3315
3486
  exports.gaTrack = gaTrack;
3316
3487
  exports.getCachedGeoLocation = getCachedGeoLocation;
3488
+ exports.getCartAttributes = getCartAttributes;
3317
3489
  exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
3318
3490
  exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
3319
3491
  exports.getQuery = getQuery;
3320
3492
  exports.getReferralAttributes = getReferralAttributes;
3493
+ exports.getUserType = getUserType;
3494
+ exports.hasPlusMemberInCart = hasPlusMemberInCart;
3495
+ exports.hasPlusMemberInLines = hasPlusMemberInLines;
3321
3496
  exports.normalizeAddToCartLines = normalizeAddToCartLines;
3322
3497
  exports.preCheck = preCheck;
3323
3498
  exports.safeParse = safeParse;
@@ -3327,7 +3502,6 @@ exports.trackBeginCheckoutGA = trackBeginCheckoutGA;
3327
3502
  exports.trackBuyNowFBQ = trackBuyNowFBQ;
3328
3503
  exports.trackBuyNowGA = trackBuyNowGA;
3329
3504
  exports.useAddCartLines = useAddCartLines;
3330
- exports.useAddPlusMemberProductsToCart = useAddPlusMemberProductsToCart;
3331
3505
  exports.useAddToCart = useAddToCart;
3332
3506
  exports.useAllBlogs = useAllBlogs;
3333
3507
  exports.useAllCollections = useAllCollections;
@@ -3337,6 +3511,7 @@ exports.useArticle = useArticle;
3337
3511
  exports.useArticles = useArticles;
3338
3512
  exports.useArticlesInBlog = useArticlesInBlog;
3339
3513
  exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
3514
+ exports.useAvailableDeliveryCoupon = useAvailableDeliveryCoupon;
3340
3515
  exports.useBlog = useBlog;
3341
3516
  exports.useBuyNow = useBuyNow;
3342
3517
  exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
@@ -3351,13 +3526,12 @@ exports.useCreateCart = useCreateCart;
3351
3526
  exports.useExposure = useExposure;
3352
3527
  exports.useGeoLocation = useGeoLocation;
3353
3528
  exports.useHasPlusMemberInCart = useHasPlusMemberInCart;
3529
+ exports.useHasPlusMemberInLines = useHasPlusMemberInLines;
3354
3530
  exports.useIntersection = useIntersection;
3355
- exports.usePlusAnnualProductVariant = usePlusAnnualProductVariant;
3356
3531
  exports.usePlusMemberCheckoutCustomAttributes = usePlusMemberCheckoutCustomAttributes;
3357
3532
  exports.usePlusMemberContext = usePlusMemberContext;
3358
- exports.usePlusMemberDeliveryCodes = usePlusMemberDeliveryCodes;
3359
- exports.usePlusMemberItemCustomAttributes = usePlusMemberItemCustomAttributes;
3360
- exports.usePlusMonthlyProductVariant = usePlusMonthlyProductVariant;
3533
+ exports.usePlusMemberNeedAddToCart = usePlusMemberNeedAddToCart;
3534
+ exports.usePlusMemberVariants = usePlusMemberVariants;
3361
3535
  exports.usePrice = usePrice;
3362
3536
  exports.useProduct = useProduct;
3363
3537
  exports.useProductUrl = useProductUrl;
@@ -3368,7 +3542,6 @@ exports.useReplaceCartPlusMember = useReplaceCartPlusMember;
3368
3542
  exports.useScriptAutoFreeGift = useScriptAutoFreeGift;
3369
3543
  exports.useSearch = useSearch;
3370
3544
  exports.useSelectedOptions = useSelectedOptions;
3371
- exports.useShippingMethodAvailableCheck = useShippingMethodAvailableCheck;
3372
3545
  exports.useShippingMethods = useShippingMethods;
3373
3546
  exports.useShopify = useShopify;
3374
3547
  exports.useSite = useSite;
@@ -3378,5 +3551,11 @@ exports.useUpdateLineCodeAmountAttributes = useUpdateLineCodeAmountAttributes;
3378
3551
  exports.useUpdateVariantQuery = useUpdateVariantQuery;
3379
3552
  exports.useVariant = useVariant;
3380
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
+ });
3381
3560
  //# sourceMappingURL=index.js.map
3382
3561
  //# sourceMappingURL=index.js.map