@anker-in/shopify-react 0.1.1-beta.4 → 0.1.1-beta.40

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 });
@@ -148,9 +166,10 @@ function normalizeAddToCartLines(lines) {
148
166
  const variant = line.variant;
149
167
  const product = variant.product;
150
168
  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;
169
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
170
+ const finalPrice = variant.finalPrice?.amount === void 0 ? originalPrice : Number(variant.finalPrice?.amount);
171
+ const subtotalAmount = originalPrice * quantity;
172
+ const totalAmount = finalPrice * quantity;
154
173
  return {
155
174
  id: `temp-line-${index}-${variant.id}`,
156
175
  // Temporary ID for pre-cart lines
@@ -164,7 +183,7 @@ function normalizeAddToCartLines(lines) {
164
183
  customAttributes: line.attributes || [],
165
184
  variant: {
166
185
  id: variant.id,
167
- price,
186
+ price: finalPrice,
168
187
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
169
188
  sku: variant.sku || "",
170
189
  name: variant.title || "",
@@ -195,15 +214,16 @@ function createMockCartFromLines(lines, existingCart) {
195
214
  const normalizedLines = normalizeAddToCartLines(lines);
196
215
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
197
216
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
217
+ const currency = lines[0]?.variant?.price?.currencyCode;
198
218
  return {
199
219
  id: existingCart?.id || "temp-cart-id",
200
220
  customerId: existingCart?.customerId,
201
221
  email: existingCart?.email,
202
222
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
203
- currency: existingCart?.currency || { code: "USD" },
223
+ currency: existingCart?.currency || { code: currency },
204
224
  taxesIncluded: existingCart?.taxesIncluded,
205
225
  lineItems: normalizedLines,
206
- totallineItemsDiscount: 0,
226
+ totalLineItemsDiscount: 0,
207
227
  orderDiscounts: 0,
208
228
  lineItemsSubtotalPrice: subtotalPrice,
209
229
  subtotalPrice,
@@ -234,22 +254,12 @@ var getQuery = () => {
234
254
  }
235
255
  return theRequest;
236
256
  };
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
257
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
248
258
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
249
259
  const matchedList = cartData?.lineItems?.filter((line) => {
250
260
  const { is_gift } = getDiscountEnvAttributeValue(line.customAttributes);
251
261
  return isAllStoreVariant ? !is_gift : variant_list?.find((item) => {
252
- return !is_gift && atobID(line.variantId) === item;
262
+ return !is_gift && shopifyCore.atobID(line.variantId) === item;
253
263
  });
254
264
  });
255
265
  return matchedList?.reduce((acc, line) => {
@@ -475,43 +485,29 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
475
485
  }
476
486
  return { activeCampaign: null, subtotal: 0 };
477
487
  }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
478
- const { qualifyingGift, nextTierGoal } = react.useMemo(() => {
488
+ const { qualifyingTier, nextTierGoal, actualThreshold, currentCurrency } = react.useMemo(() => {
479
489
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
480
- return { qualifyingGift: null, nextTierGoal: null };
490
+ return { qualifyingTier: null, nextTierGoal: null, actualThreshold: 0, currentCurrency: "" };
481
491
  }
482
492
  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)
493
+ const currentCurrency2 = effectiveCart?.currency?.code || "";
494
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency2);
495
+ const getThresholdAmount = (tier) => {
496
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency2]?.value) {
497
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency2].value);
498
+ }
499
+ return Number(tier.spend_sum_money || 0);
512
500
  };
513
- return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
514
- }, [activeCampaign, subtotal]);
501
+ const qualifyingTier2 = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
502
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
503
+ const actualThreshold2 = qualifyingTier2 ? getThresholdAmount(qualifyingTier2) : 0;
504
+ return {
505
+ qualifyingTier: qualifyingTier2,
506
+ nextTierGoal: nextGoal || null,
507
+ actualThreshold: actualThreshold2,
508
+ currentCurrency: currentCurrency2
509
+ };
510
+ }, [activeCampaign, subtotal, effectiveCart]);
515
511
  const giftHandles = react.useMemo(() => {
516
512
  const giftVariant = autoFreeGiftConfig.map(
517
513
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -527,24 +523,82 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
527
523
  }
528
524
  return true;
529
525
  }, [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
- });
526
+ const { data: giftProductsResult } = useSWR__default.default(
527
+ shouldFetch ? giftHandles : null,
528
+ async () => {
529
+ const res = await shopifySdk.getProductsByHandles(client, {
530
+ handles: giftHandles,
531
+ locale
532
+ });
533
+ const result = Array.isArray(res) ? res : [];
534
+ giftProductsCache.current = {
535
+ data: result,
536
+ giftHandles: [...giftHandles]
537
+ };
538
+ return result;
539
+ },
540
+ {
541
+ revalidateOnFocus: false
542
+ }
543
+ );
542
544
  const finalGiftProductsResult = react.useMemo(() => {
543
545
  if (giftProductsCache.current && !shouldFetch) {
544
546
  return giftProductsCache.current.data || void 0;
545
547
  }
546
548
  return giftProductsResult;
547
549
  }, [giftProductsResult, shouldFetch]);
550
+ const qualifyingGift = react.useMemo(() => {
551
+ if (!qualifyingTier || !activeCampaign) {
552
+ return null;
553
+ }
554
+ const itemsToAdd = qualifyingTier.reward_list?.map((reward) => {
555
+ if (!reward.variant_list || reward.variant_list.length === 0) {
556
+ return null;
557
+ }
558
+ let selectedGiftProduct = null;
559
+ for (const giftVariant of reward.variant_list) {
560
+ const productInfo = finalGiftProductsResult?.find(
561
+ (p) => p.handle === giftVariant.handle
562
+ );
563
+ if (productInfo) {
564
+ const variantInfo = productInfo.variants?.find((v) => v.sku === giftVariant.sku);
565
+ if (variantInfo?.availableForSale) {
566
+ selectedGiftProduct = giftVariant;
567
+ break;
568
+ }
569
+ }
570
+ }
571
+ if (!selectedGiftProduct) {
572
+ selectedGiftProduct = reward.variant_list[0];
573
+ }
574
+ return {
575
+ variant: {
576
+ id: shopifyCore.btoaID(selectedGiftProduct.variant_id),
577
+ handle: selectedGiftProduct.handle,
578
+ sku: selectedGiftProduct.sku
579
+ },
580
+ quantity: reward?.get_unit || 1,
581
+ attributes: [
582
+ {
583
+ key: CUSTOMER_ATTRIBUTE_KEY,
584
+ value: JSON.stringify({
585
+ is_gift: true,
586
+ rule_id: activeCampaign.rule_id,
587
+ spend_sum_money: actualThreshold,
588
+ // 使用实际的门槛金额(多币种支持)
589
+ currency_code: currentCurrency
590
+ // 记录当前币种
591
+ })
592
+ }
593
+ ]
594
+ };
595
+ }).filter((item) => item !== null);
596
+ const formattedGift = {
597
+ tier: qualifyingTier,
598
+ itemsToAdd
599
+ };
600
+ return formattedGift;
601
+ }, [qualifyingTier, activeCampaign, finalGiftProductsResult, actualThreshold, currentCurrency]);
548
602
  return {
549
603
  qualifyingGift,
550
604
  nextTierGoal,
@@ -591,12 +645,14 @@ var useScriptAutoFreeGift = ({
591
645
  upgrade_multiple2 = 1.2;
592
646
  upgrade_value2 = 40;
593
647
  }
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
- });
648
+ effectiveCart?.lineItems?.forEach(
649
+ ({ customAttributes }) => {
650
+ customAttributes?.forEach(({ key, value }) => {
651
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
652
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
653
+ });
654
+ }
655
+ );
600
656
  return [upgrade_multiple2, upgrade_value2];
601
657
  }, [effectiveCart?.lineItems, points_subscribe]);
602
658
  const breakpoints = react.useMemo(() => {
@@ -661,18 +717,24 @@ var useScriptAutoFreeGift = ({
661
717
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
662
718
  return [currentLevel, nextLevel];
663
719
  }, [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
- });
720
+ const { data: giftProductsResult } = useSWR__default.default(
721
+ shouldFetch ? giftHandles : null,
722
+ async () => {
723
+ const res = await shopifySdk.getProductsByHandles(client, {
724
+ handles: giftHandles,
725
+ locale
726
+ });
727
+ const result = Array.isArray(res) ? res : [];
728
+ giftProductsCache.current = {
729
+ data: result,
730
+ giftHandles: [...giftHandles]
731
+ };
732
+ return result;
733
+ },
734
+ {
735
+ revalidateOnFocus: false
736
+ }
737
+ );
676
738
  const finalGiftProductsResult = react.useMemo(() => {
677
739
  if (giftProductsCache.current && !shouldFetch) {
678
740
  return giftProductsCache.current.data || void 0;
@@ -739,11 +801,23 @@ function useAddCartLines(options) {
739
801
  const { mutateCart, metafieldIdentifiers } = useCartContext();
740
802
  const addLines = react.useCallback(
741
803
  async (_key, { arg }) => {
742
- let updatedCart = await shopifySdk.addCartLines(client, {
743
- ...arg,
744
- metafieldIdentifiers,
745
- cookieAdapter: cartCookieAdapter
746
- });
804
+ const { cartId, lines } = arg;
805
+ const id = cartId || cartCookieAdapter?.getCartId(locale);
806
+ let updatedCart;
807
+ if (!id) {
808
+ updatedCart = await shopifySdk.createCart(client, {
809
+ lines,
810
+ metafieldIdentifiers,
811
+ cookieAdapter: cartCookieAdapter
812
+ });
813
+ } else {
814
+ updatedCart = await shopifySdk.addCartLines(client, {
815
+ cartId: id,
816
+ lines,
817
+ metafieldIdentifiers,
818
+ cookieAdapter: cartCookieAdapter
819
+ });
820
+ }
747
821
  if (updatedCart) {
748
822
  const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
749
823
  if (unApplicableCodes.length > 0) {
@@ -790,7 +864,7 @@ var trackAddToCartGA = ({
790
864
  const currencyCode = variant.product?.price?.currencyCode;
791
865
  const totalPrice = lineItems?.reduce(
792
866
  (prev, { variant: variant2 }) => prev.plus(
793
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
867
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
794
868
  ),
795
869
  new Decimal2__default.default(0)
796
870
  ).toNumber();
@@ -825,7 +899,7 @@ var trackBeginCheckoutGA = ({
825
899
  }
826
900
  const totalPrice = lineItems?.reduce(
827
901
  (prev, { variant }) => prev.plus(
828
- variant?.finalPrice?.amount ?? variant?.compareAtPrice?.amount ?? variant?.price?.amount ?? 0
902
+ variant?.finalPrice?.amount === void 0 ? Number(variant?.price?.amount) || 0 : Number(variant?.finalPrice?.amount) || 0
829
903
  ),
830
904
  new Decimal2__default.default(0)
831
905
  ).toNumber();
@@ -858,10 +932,10 @@ var trackBuyNowGA = ({
858
932
  return;
859
933
  }
860
934
  const { variant } = lineItems[0];
861
- const currencyCode = variant.price?.currencyCode;
935
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
862
936
  const totalPrice = lineItems?.reduce(
863
937
  (prev, { variant: variant2 }) => prev.plus(
864
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
938
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
865
939
  ),
866
940
  new Decimal2__default.default(0)
867
941
  ).toNumber();
@@ -935,7 +1009,7 @@ function useApplyCartCodes(options) {
935
1009
  if (!discountCodes?.length) {
936
1010
  throw new Error("Invalid input used for this operation: Miss discountCode");
937
1011
  }
938
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1012
+ const cartId = providedCartId || cart?.id;
939
1013
  if (!cartId) {
940
1014
  return void 0;
941
1015
  }
@@ -948,12 +1022,18 @@ function useApplyCartCodes(options) {
948
1022
  cookieAdapter: cartCookieAdapter,
949
1023
  metafieldIdentifiers
950
1024
  });
1025
+ const unApplicableCodes = discountCodes.filter(
1026
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
1027
+ );
1028
+ if (unApplicableCodes.length) {
1029
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
1030
+ }
951
1031
  if (updatedCart) {
952
1032
  mutateCart(updatedCart);
953
1033
  }
954
1034
  return updatedCart;
955
1035
  },
956
- [client, locale, cartCookieAdapter, mutateCart, cart]
1036
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
957
1037
  );
958
1038
  return useSWRMutation__default.default("apply-codes", applyCodes, options);
959
1039
  }
@@ -963,7 +1043,7 @@ function useRemoveCartCodes(options) {
963
1043
  const removeCodes = react.useCallback(
964
1044
  async (_key, { arg }) => {
965
1045
  const { cartId: providedCartId, discountCodes } = arg;
966
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1046
+ const cartId = providedCartId || cart?.id;
967
1047
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
968
1048
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
969
1049
  const updatedCart = await shopifySdk.updateCartCodes(client, {
@@ -977,18 +1057,74 @@ function useRemoveCartCodes(options) {
977
1057
  }
978
1058
  return updatedCart;
979
1059
  },
980
- [client, locale, cartCookieAdapter, mutateCart, cart]
1060
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
981
1061
  );
982
1062
  return useSWRMutation__default.default("remove-codes", removeCodes, options);
983
1063
  }
984
1064
 
1065
+ // src/hooks/cart/utils/add-to-cart.ts
1066
+ var getLinesWithAttributes = ({
1067
+ cart,
1068
+ lineItems
1069
+ }) => {
1070
+ return lineItems.map((line) => {
1071
+ const sameLineInCart = cart?.lineItems.find(
1072
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
1073
+ );
1074
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
1075
+ (attr) => attr.key === CODE_AMOUNT_KEY
1076
+ );
1077
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
1078
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
1079
+ );
1080
+ let functionAttribute = null;
1081
+ try {
1082
+ functionAttribute = sameLineInCart?.customAttributes?.find(
1083
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
1084
+ );
1085
+ } catch (error) {
1086
+ }
1087
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
1088
+ return {
1089
+ ...line,
1090
+ attributes: [
1091
+ ...line.attributes || [],
1092
+ codeAmountAttribute,
1093
+ functionAttribute,
1094
+ scriptCodeAmountAttribute
1095
+ ].filter(Boolean)
1096
+ };
1097
+ }
1098
+ return line;
1099
+ });
1100
+ };
1101
+ var getLinesWithFunctionAttributes = (lineItems) => {
1102
+ return lineItems.map((line) => {
1103
+ let itemAttributes = line.attributes || [];
1104
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
1105
+ if (!functionEnvAttribute) {
1106
+ itemAttributes = itemAttributes.concat([
1107
+ {
1108
+ key: CUSTOMER_ATTRIBUTE_KEY,
1109
+ value: JSON.stringify({
1110
+ is_gift: false,
1111
+ discounted_amount: line.variant?.finalPrice?.amount === void 0 ? Number(line.variant?.price?.amount) * (line.quantity || 1) : Number(line.variant?.finalPrice?.amount) * (line.quantity || 1)
1112
+ })
1113
+ }
1114
+ ]);
1115
+ }
1116
+ return { ...line, attributes: itemAttributes };
1117
+ });
1118
+ };
1119
+
985
1120
  // src/hooks/cart/use-add-to-cart.ts
986
1121
  function useAddToCart({ withTrack = true } = {}, swrOptions) {
987
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
988
- const { cart } = useCartContext();
1122
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
1123
+ const { cart, addCustomAttributes } = useCartContext();
989
1124
  const { trigger: applyCartCodes } = useApplyCartCodes();
990
1125
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
991
1126
  const { trigger: addCartLines2 } = useAddCartLines();
1127
+ const { trigger: createCart4 } = useCreateCart();
992
1128
  const addToCart = react.useCallback(
993
1129
  async (_key, { arg }) => {
994
1130
  const {
@@ -999,12 +1135,19 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
999
1135
  buyerIdentity,
1000
1136
  needCreateCart = false,
1001
1137
  onCodesInvalid,
1002
- replaceExistingCodes
1138
+ replaceExistingCodes,
1139
+ customAttributes
1003
1140
  } = arg;
1004
1141
  if (!lineItems || lineItems.length === 0) {
1005
1142
  return;
1006
1143
  }
1007
- const lines = lineItems.map((item) => ({
1144
+ performanceAdapter?.addToCartStart();
1145
+ const linesWithAttributes = getLinesWithAttributes({
1146
+ cart,
1147
+ lineItems
1148
+ });
1149
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(linesWithAttributes);
1150
+ const lines = linesWithFunctionAttributes.map((item) => ({
1008
1151
  merchandiseId: item.variant?.id || "",
1009
1152
  quantity: item.quantity || 1,
1010
1153
  attributes: item.attributes,
@@ -1013,36 +1156,45 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
1013
1156
  if (lines.length === 0) {
1014
1157
  return;
1015
1158
  }
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;
1159
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
1160
+ let resultCart = null;
1161
+ if (!cartId) {
1162
+ resultCart = await createCart4({
1163
+ lines,
1164
+ buyerIdentity,
1165
+ discountCodes,
1166
+ customAttributes
1167
+ });
1168
+ } else {
1169
+ resultCart = await addCartLines2({
1170
+ cartId,
1171
+ lines
1172
+ });
1173
+ console.log("npm addCartLines resultCart", resultCart);
1174
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
1175
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1176
+ if (unapplicableCodes.length > 0) {
1177
+ if (onCodesInvalid) {
1178
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
1179
+ if (handledCart) {
1180
+ resultCart = handledCart;
1181
+ }
1182
+ } else {
1183
+ await removeInvalidCodes({
1184
+ discountCodes: unapplicableCodes
1185
+ });
1033
1186
  }
1034
- } else {
1035
- await removeInvalidCodes({
1036
- discountCodes: unapplicableCodes
1037
- });
1038
1187
  }
1039
1188
  }
1040
- }
1041
- if (discountCodes && discountCodes.length > 0) {
1042
- applyCartCodes({
1043
- replaceExistingCodes,
1044
- discountCodes
1045
- });
1189
+ if (resultCart && discountCodes && discountCodes.length > 0) {
1190
+ applyCartCodes({
1191
+ replaceExistingCodes,
1192
+ discountCodes
1193
+ });
1194
+ }
1195
+ if (customAttributes && customAttributes.length > 0) {
1196
+ addCustomAttributes(customAttributes);
1197
+ }
1046
1198
  }
1047
1199
  if (withTrack) {
1048
1200
  trackAddToCartGA({
@@ -1051,9 +1203,24 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
1051
1203
  });
1052
1204
  trackAddToCartFBQ({ lineItems });
1053
1205
  }
1206
+ performanceAdapter?.addToCartEnd();
1054
1207
  return resultCart;
1055
1208
  },
1056
- [client, locale, cartCookieAdapter, userAdapter, cart, withTrack]
1209
+ [
1210
+ client,
1211
+ locale,
1212
+ cartCookieAdapter,
1213
+ userAdapter,
1214
+ cart,
1215
+ withTrack,
1216
+ performanceAdapter,
1217
+ createCart4,
1218
+ addCartLines2,
1219
+ applyCartCodes,
1220
+ removeInvalidCodes,
1221
+ addCustomAttributes,
1222
+ config
1223
+ ]
1057
1224
  );
1058
1225
  return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
1059
1226
  }
@@ -1070,9 +1237,10 @@ function useUpdateCartLines(options) {
1070
1237
  if (updatedCart) {
1071
1238
  mutateCart(updatedCart);
1072
1239
  }
1240
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
1073
1241
  return updatedCart;
1074
1242
  },
1075
- [client, locale, cartCookieAdapter, mutateCart]
1243
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1076
1244
  );
1077
1245
  return useSWRMutation__default.default("update-cart-lines", updateLines, options);
1078
1246
  }
@@ -1111,7 +1279,7 @@ function useRemoveCartLines(options) {
1111
1279
  }
1112
1280
  return updatedCart;
1113
1281
  },
1114
- [client, locale, cartCookieAdapter, mutateCart]
1282
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1115
1283
  );
1116
1284
  return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1117
1285
  }
@@ -1130,7 +1298,7 @@ function useUpdateCartAttributes(mutate, metafieldIdentifiers, options) {
1130
1298
  }
1131
1299
  return updatedCart;
1132
1300
  },
1133
- [client, locale, cartCookieAdapter, mutate]
1301
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers]
1134
1302
  );
1135
1303
  return useSWRMutation__default.default("update-cart-attributes", updateAttributes, options);
1136
1304
  }
@@ -1152,7 +1320,8 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1152
1320
  if (!lineItems || lineItems.length === 0) {
1153
1321
  return;
1154
1322
  }
1155
- const lines = lineItems.map((item) => ({
1323
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(lineItems);
1324
+ const lines = linesWithFunctionAttributes.map((item) => ({
1156
1325
  merchandiseId: item.variant?.id || "",
1157
1326
  quantity: item.quantity || 1,
1158
1327
  attributes: item.attributes,
@@ -1270,7 +1439,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1270
1439
  const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
1271
1440
  const dealsType = "";
1272
1441
  const { activeCampaign, subtotal } = react.useMemo(() => {
1273
- for (const campaign of orderDiscountConfig) {
1442
+ for (const campaign of orderDiscountConfig || []) {
1274
1443
  const { rule_conditions = [], result_detail } = campaign;
1275
1444
  const { main_product, order_discount_conf } = result_detail || {};
1276
1445
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
@@ -1300,9 +1469,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1300
1469
  discountAmount: 0
1301
1470
  };
1302
1471
  }
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));
1472
+ const currentCurrency = cart?.currency?.code || "";
1473
+ console.log("currentCurrency", cart, currentCurrency);
1474
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1475
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1476
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1477
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1306
1478
  if (!qualifyingTier) {
1307
1479
  return {
1308
1480
  qualifyingDiscount: null,
@@ -1370,12 +1542,10 @@ function useHasPlusMemberInCart({
1370
1542
  };
1371
1543
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1372
1544
  }
1373
-
1374
- // src/hooks/cart/feature/use-cart-attributes.ts
1375
1545
  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");
1546
+ const inviteCode = shopifySdk.getLocalStorage("inviteCode") || Cookies5__default.default.get("inviteCode");
1547
+ const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
1548
+ const popup = shopifySdk.getLocalStorage("_popup") || Cookies5__default.default.get("_popup");
1379
1549
  if (inviteCode && playModeId) {
1380
1550
  return popup ? [
1381
1551
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1399,8 +1569,6 @@ var useCartAttributes = ({
1399
1569
  memberSetting,
1400
1570
  cart
1401
1571
  });
1402
- console.log("memberSetting", memberSetting);
1403
- console.log("hasPlusMember", hasPlusMember);
1404
1572
  react.useEffect(() => {
1405
1573
  setCurrentUrl(window.location.href);
1406
1574
  }, []);
@@ -1426,7 +1594,7 @@ var useCartAttributes = ({
1426
1594
  return "new_user_login";
1427
1595
  }, [customer]);
1428
1596
  const memberAttributes = react.useMemo(() => {
1429
- return [
1597
+ const attributes = [
1430
1598
  {
1431
1599
  key: "_token",
1432
1600
  value: profile?.token
@@ -1447,17 +1615,28 @@ var useCartAttributes = ({
1447
1615
  value: profile?.token ? "true" : "false"
1448
1616
  }
1449
1617
  ];
1618
+ if (profile?.token) {
1619
+ attributes.push({
1620
+ key: "_login_user",
1621
+ value: "1"
1622
+ });
1623
+ }
1624
+ return attributes;
1450
1625
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1451
1626
  const functionAttributes = react.useMemo(() => {
1452
- return [
1453
- cart?.discountCodes && {
1627
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1628
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1629
+ );
1630
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1631
+ return hasFunctionEnvAttribute ? [
1632
+ {
1454
1633
  key: "_discounts_function_env",
1455
1634
  value: JSON.stringify({
1456
- discount_code: cart?.discountCodes.map((item) => item.code),
1635
+ discount_code: discountCodes,
1457
1636
  user_tags: customer?.tags || []
1458
1637
  })
1459
1638
  }
1460
- ];
1639
+ ] : [];
1461
1640
  }, [cart]);
1462
1641
  const presellAttributes = react.useMemo(() => {
1463
1642
  return [
@@ -1489,18 +1668,50 @@ var useCartAttributes = ({
1489
1668
  }
1490
1669
  ];
1491
1670
  }, [currentUrl]);
1671
+ const commonAttributes = react.useMemo(
1672
+ () => [
1673
+ ...memberAttributes,
1674
+ ...functionAttributes,
1675
+ ...presellAttributes,
1676
+ ...weightAttributes,
1677
+ ...trackingAttributes,
1678
+ ...getReferralAttributes()
1679
+ ].filter((item) => item?.value),
1680
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1681
+ );
1682
+ const extraAttributesInCart = react.useMemo(() => {
1683
+ const commonAttributeKeys = [
1684
+ // member attributes
1685
+ "_token",
1686
+ "_member_type",
1687
+ "_user_type",
1688
+ "_is_login",
1689
+ "_login_user",
1690
+ // function attributes
1691
+ "_discounts_function_env",
1692
+ // presell attributes
1693
+ "_presale",
1694
+ // weight attributes
1695
+ "_weight",
1696
+ "_app_source_name",
1697
+ // tracking attributes
1698
+ "utm_params",
1699
+ // referral attributes
1700
+ "_invite_code",
1701
+ "_play_mode_id",
1702
+ "_popup"
1703
+ ];
1704
+ return cart?.customAttributes?.filter(
1705
+ (item) => !commonAttributeKeys.includes(item.key)
1706
+ ) || [];
1707
+ }, [cart]);
1492
1708
  return react.useMemo(
1493
1709
  () => ({
1494
- attributes: [
1495
- ...memberAttributes,
1496
- ...functionAttributes,
1497
- ...presellAttributes,
1498
- ...weightAttributes,
1499
- ...trackingAttributes,
1500
- ...getReferralAttributes()
1501
- ].filter((item) => item?.value)
1710
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1711
+ (item) => item?.value
1712
+ )
1502
1713
  }),
1503
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1714
+ [commonAttributes, extraAttributesInCart]
1504
1715
  );
1505
1716
  };
1506
1717
  var DEFAULT_MIN = 1;
@@ -1563,7 +1774,7 @@ var useUpdateLineCodeAmountAttributes = ({
1563
1774
  );
1564
1775
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1565
1776
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1566
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1777
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1567
1778
  attrNeedUpdate.push({
1568
1779
  key: CUSTOMER_ATTRIBUTE_KEY,
1569
1780
  value: JSON.stringify({
@@ -1602,29 +1813,22 @@ var useUpdateLineCodeAmountAttributes = ({
1602
1813
  }).filter(
1603
1814
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1604
1815
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1816
+ let lineId = line.id;
1817
+ let attributes = line.customAttributes || [];
1818
+ if (attrNeedDelete.length) {
1819
+ attributes = attributes.filter(
1820
+ (attr) => !attrNeedDelete.includes(attr.key)
1821
+ );
1822
+ }
1605
1823
  if (attrNeedUpdate.length) {
1606
- return {
1607
- id: line.id,
1608
- attributes: [
1609
- ...line.customAttributes?.filter(
1610
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1611
- ) || [],
1612
- ...attrNeedUpdate
1613
- ]
1614
- };
1615
- } else if (attrNeedDelete.length) {
1616
- return {
1617
- id: line.id,
1618
- attributes: line.customAttributes?.filter(
1619
- (attr) => !attrNeedDelete.includes(attr.key)
1620
- ) || []
1621
- };
1622
- } else {
1623
- return {
1624
- id: line.id,
1625
- attributes: line.customAttributes || []
1626
- };
1824
+ attributes = attributes.filter(
1825
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1826
+ ).concat(attrNeedUpdate);
1627
1827
  }
1828
+ return {
1829
+ id: lineId,
1830
+ attributes
1831
+ };
1628
1832
  }),
1629
1833
  [cart?.lineItems, mainProductDiscountCodes]
1630
1834
  );
@@ -1717,8 +1921,9 @@ function useProductsByHandles(options = {}) {
1717
1921
  metafieldIdentifiers
1718
1922
  });
1719
1923
  },
1720
- swrOptions || {
1721
- revalidateOnFocus: false
1924
+ {
1925
+ revalidateOnFocus: false,
1926
+ ...swrOptions
1722
1927
  }
1723
1928
  );
1724
1929
  }
@@ -2347,7 +2552,10 @@ var createInitialValue = () => ({
2347
2552
  freeShippingMethods: [],
2348
2553
  paymentShippingMethods: [],
2349
2554
  nddOverweight: false,
2350
- tddOverweight: false
2555
+ tddOverweight: false,
2556
+ nddCoupon: void 0,
2557
+ tddCoupon: void 0,
2558
+ isLoadingCoupon: false
2351
2559
  },
2352
2560
  selectedPlusMemberProduct: null,
2353
2561
  plusMemberProducts: [],
@@ -2392,15 +2600,29 @@ function usePlusAnnualProductVariant() {
2392
2600
  }, [plusMemberProducts, plusAnnual]);
2393
2601
  return plusAnnualProductVariant;
2394
2602
  }
2395
- function useShippingMethods(options) {
2396
- const {
2397
- variant,
2398
- plusMemberMetafields,
2399
- selectedPlusMemberMode,
2400
- isPlus = false,
2603
+ var useAvailableDeliveryCoupon = ({
2604
+ profile
2605
+ }) => {
2606
+ const { data: availableDeliveryCoupon, isLoading } = useSWR__default.default(
2607
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
2608
+ async ([apiPath]) => {
2609
+ return fetch(apiPath).then((res) => res.json());
2610
+ }
2611
+ );
2612
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
2613
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
2614
+ return {
2401
2615
  nddCoupon,
2402
- tddCoupon
2403
- } = options;
2616
+ tddCoupon,
2617
+ isLoading
2618
+ };
2619
+ };
2620
+
2621
+ // src/hooks/member/plus/use-shipping-methods.ts
2622
+ function useShippingMethods(options) {
2623
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, isPlus = false, profile } = options;
2624
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
2625
+ console.log("nddCoupon", nddCoupon);
2404
2626
  const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2405
2627
  const nddOverweight = react.useMemo(() => {
2406
2628
  return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
@@ -2410,12 +2632,10 @@ function useShippingMethods(options) {
2410
2632
  }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2411
2633
  const paymentShippingMethods = react.useMemo(() => {
2412
2634
  const weight = variant?.weight || 0;
2413
- const methods = plus_shipping?.shipping_methods?.filter(
2414
- ({ weight_low, weight_high, __mode, __plus }) => {
2415
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2416
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2417
- }
2418
- ) || [];
2635
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
2636
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2637
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2638
+ }) || [];
2419
2639
  return methods.map((method) => {
2420
2640
  let disabled = false;
2421
2641
  const selectedFreeMember = selectedPlusMemberMode === "free";
@@ -2442,40 +2662,34 @@ function useShippingMethods(options) {
2442
2662
  ]);
2443
2663
  const nddPrice = react.useMemo(() => {
2444
2664
  const weight = variant?.weight || 0;
2445
- const nddMethod = paymentShippingMethods.find(
2446
- ({ __mode, weight_high, weight_low }) => {
2447
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2448
- return __mode === "ndd" && fitWeight;
2449
- }
2450
- );
2665
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2666
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2667
+ return __mode === "ndd" && fitWeight;
2668
+ });
2451
2669
  return nddMethod?.price || 0;
2452
2670
  }, [variant?.weight, paymentShippingMethods]);
2453
2671
  const tddPrice = react.useMemo(() => {
2454
2672
  const weight = variant?.weight || 0;
2455
- const tddMethod = paymentShippingMethods.find(
2456
- ({ __mode, weight_high, weight_low }) => {
2457
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2458
- return __mode === "tdd" && fitWeight;
2459
- }
2460
- );
2673
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2674
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2675
+ return __mode === "tdd" && fitWeight;
2676
+ });
2461
2677
  return tddMethod?.price || 0;
2462
2678
  }, [variant?.weight, paymentShippingMethods]);
2463
2679
  const freeShippingMethods = react.useMemo(() => {
2464
2680
  const weight = variant?.weight || 0;
2465
- let methods = plus_shipping?.shipping_methods?.filter(
2466
- ({ __mode, __plus, weight_low, weight_high }) => {
2467
- if (__mode === "free" /* FREE */) {
2468
- return true;
2469
- }
2470
- if (isPlus) {
2471
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2472
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2473
- return hasCoupon && fitWeight && !__plus;
2474
- } else {
2475
- return __plus;
2476
- }
2681
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
2682
+ if (__mode === "free" /* FREE */) {
2683
+ return true;
2477
2684
  }
2478
- ) || [];
2685
+ if (isPlus) {
2686
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2687
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2688
+ return hasCoupon && fitWeight && !__plus;
2689
+ } else {
2690
+ return __plus;
2691
+ }
2692
+ }) || [];
2479
2693
  if (isPlus) {
2480
2694
  methods = methods.sort((a, b) => {
2481
2695
  if (b.__mode === "free" /* FREE */) return -1;
@@ -2529,7 +2743,10 @@ function useShippingMethods(options) {
2529
2743
  freeShippingMethods,
2530
2744
  paymentShippingMethods,
2531
2745
  nddOverweight,
2532
- tddOverweight
2746
+ tddOverweight,
2747
+ nddCoupon,
2748
+ tddCoupon,
2749
+ isLoadingCoupon: isLoading
2533
2750
  };
2534
2751
  }
2535
2752
  function useShippingMethodAvailableCheck() {
@@ -2634,6 +2851,73 @@ var usePlusMemberDeliveryCodes = ({
2634
2851
  [deliveryData]
2635
2852
  );
2636
2853
  };
2854
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2855
+ const { client, locale, cartCookieAdapter } = useShopify();
2856
+ const updateDeliveryOptions = react.useCallback(
2857
+ async (_key, { arg }) => {
2858
+ const updatedCart = await shopifySdk.updateCartDeliveryOptions(client, {
2859
+ ...arg,
2860
+ metafieldIdentifiers,
2861
+ cookieAdapter: cartCookieAdapter
2862
+ });
2863
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2864
+ if (updatedCart) {
2865
+ mutate(updatedCart);
2866
+ }
2867
+ return updatedCart;
2868
+ },
2869
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers]
2870
+ );
2871
+ return useSWRMutation__default.default("update-cart-delivery-options", updateDeliveryOptions, options);
2872
+ }
2873
+
2874
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2875
+ var useUpdatePlusMemberDeliveryOptions = ({
2876
+ options
2877
+ } = {}) => {
2878
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2879
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2880
+ mutateCart,
2881
+ metafieldIdentifiers
2882
+ );
2883
+ const handler = react.useCallback(
2884
+ async (_, { arg }) => {
2885
+ const currentCart = arg?.cart || cartContextData;
2886
+ const { deliveryData } = arg;
2887
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2888
+ const deliveryGroupId = firstDeliveryGroup?.id;
2889
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2890
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2891
+ return null;
2892
+ }
2893
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2894
+ (group) => group?.id === deliveryGroupId
2895
+ );
2896
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2897
+ (option) => option?.code === selectedOptionCode
2898
+ );
2899
+ if (!matchedOption?.handle) {
2900
+ return null;
2901
+ }
2902
+ const deliveryOptions = [
2903
+ {
2904
+ deliveryGroupId,
2905
+ deliveryOptionHandle: matchedOption.handle
2906
+ }
2907
+ ];
2908
+ const updatedCart = await updateCartDeliveryOptions2({
2909
+ selectedDeliveryOptions: deliveryOptions,
2910
+ cartId: currentCart?.id
2911
+ });
2912
+ if (updatedCart && mutateCart) {
2913
+ mutateCart(updatedCart);
2914
+ }
2915
+ return updatedCart;
2916
+ },
2917
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2918
+ );
2919
+ return useSWRMutation__default.default("update-cart-delivery-options", handler, options);
2920
+ };
2637
2921
  var usePlusMemberItemCustomAttributes = ({
2638
2922
  deliveryData
2639
2923
  }) => {
@@ -2653,48 +2937,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2653
2937
  deliveryData,
2654
2938
  product,
2655
2939
  variant,
2656
- customer,
2657
2940
  isShowShippingBenefits
2658
2941
  }) => {
2659
2942
  const { deliveryCustomData } = deliveryData || {};
2660
2943
  const { profile } = usePlusMemberContext();
2661
- const userType = react.useMemo(() => {
2662
- const customerInfo = customer;
2663
- if (!customerInfo) {
2664
- return "new_user_unlogin";
2665
- }
2666
- if (customer) {
2667
- const { orders = {} } = customer;
2668
- const edgesLength = orders?.edges?.length;
2669
- if (edgesLength === 1) {
2670
- return "old_user_orders_once";
2671
- } else if (edgesLength && edgesLength > 1) {
2672
- return "old_user_orders_twice";
2673
- }
2674
- }
2675
- return "new_user_login";
2676
- }, [customer]);
2677
2944
  return react.useMemo(() => {
2678
2945
  const checkoutCustomAttributes = [
2679
- {
2680
- key: "_token",
2681
- value: profile?.token || ""
2682
- },
2946
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2683
2947
  {
2684
2948
  key: "_last_url",
2685
2949
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2686
- },
2687
- {
2688
- key: "_user_type",
2689
- value: userType
2690
2950
  }
2691
2951
  ];
2692
- if (profile) {
2693
- checkoutCustomAttributes.push({
2694
- key: "_login_user",
2695
- value: "1"
2696
- });
2697
- }
2698
2952
  if (deliveryCustomData) {
2699
2953
  checkoutCustomAttributes.push({
2700
2954
  key: "_checkout_delivery_custom",
@@ -2704,12 +2958,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2704
2958
  })
2705
2959
  });
2706
2960
  }
2707
- if (variant?.metafields?.presell) {
2708
- checkoutCustomAttributes.push({
2709
- key: "_presale",
2710
- value: "true"
2711
- });
2712
- }
2713
2961
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2714
2962
  checkoutCustomAttributes.push({
2715
2963
  key: "_hide_shipping",
@@ -2717,18 +2965,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2717
2965
  });
2718
2966
  }
2719
2967
  return checkoutCustomAttributes;
2720
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2968
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2721
2969
  };
2722
2970
  function useAutoRemovePlusMemberInCart({
2723
- metafields,
2724
- isMonthlyPlus,
2725
- isAnnualPlus
2971
+ cart,
2972
+ profile,
2973
+ memberSetting
2726
2974
  }) {
2727
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2728
- const { cart } = useCartContext();
2975
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2729
2976
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2730
2977
  react.useEffect(() => {
2731
- if (!cart) return;
2978
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2732
2979
  const removePlusProduct = async (productType) => {
2733
2980
  if (!productType) return;
2734
2981
  const product = cart.lineItems?.find(
@@ -2740,33 +2987,25 @@ function useAutoRemovePlusMemberInCart({
2740
2987
  });
2741
2988
  }
2742
2989
  };
2743
- if (isMonthlyPlus) {
2990
+ if (profile?.isMonthlyPlus) {
2744
2991
  removePlusProduct(plus_monthly_product);
2745
2992
  }
2746
- if (isAnnualPlus) {
2993
+ if (profile?.isAnnualPlus) {
2747
2994
  removePlusProduct(plus_annual_product);
2748
2995
  }
2749
- }, [
2750
- cart,
2751
- plus_annual_product,
2752
- plus_monthly_product,
2753
- isAnnualPlus,
2754
- isMonthlyPlus,
2755
- removeCartLines2
2756
- ]);
2996
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2757
2997
  }
2758
- function useAddPlusMemberProductsToCart({
2998
+ function usePlusMemberNeedAddToCart({
2759
2999
  cart,
2760
- memberSetting,
2761
- selectedPlusMemberMode,
2762
- selectedPlusMemberProduct
3000
+ profile
2763
3001
  }) {
3002
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2764
3003
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2765
- cart,
2766
- memberSetting
3004
+ memberSetting: plusMemberMetafields,
3005
+ cart
2767
3006
  });
2768
3007
  const plusMemberProduct = react.useMemo(() => {
2769
- if (selectedPlusMemberMode === "free" /* FREE */) {
3008
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2770
3009
  return void 0;
2771
3010
  }
2772
3011
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2775,7 +3014,10 @@ function useAddPlusMemberProductsToCart({
2775
3014
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2776
3015
  return void 0;
2777
3016
  }
2778
- if (!selectedPlusMemberProduct) {
3017
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
3018
+ return void 0;
3019
+ }
3020
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2779
3021
  return void 0;
2780
3022
  }
2781
3023
  return selectedPlusMemberProduct;
@@ -2794,9 +3036,9 @@ var PlusMemberProvider = ({
2794
3036
  memberSetting,
2795
3037
  initialSelectedPlusMemberMode = "free",
2796
3038
  profile,
2797
- locale,
2798
3039
  children
2799
3040
  }) => {
3041
+ const { locale } = useShopify();
2800
3042
  const [zipCode, setZipCode] = react.useState("");
2801
3043
  const [showTip, setShowTip] = react.useState(false);
2802
3044
  const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
@@ -2812,7 +3054,11 @@ var PlusMemberProvider = ({
2812
3054
  const shippingMethodsContext = useShippingMethods({
2813
3055
  variant,
2814
3056
  plusMemberMetafields: memberSetting,
2815
- selectedPlusMemberMode});
3057
+ selectedPlusMemberMode,
3058
+ profile,
3059
+ isPlus: profile?.isPlus || false
3060
+ });
3061
+ console.log("shippingMethodsContext", shippingMethodsContext);
2816
3062
  const plusMemberHandles = react.useMemo(() => {
2817
3063
  return [
2818
3064
  memberSetting?.plus_monthly_product?.handle,
@@ -3094,8 +3340,13 @@ function CartProvider({
3094
3340
  const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
3095
3341
  ahooks.useRequest(
3096
3342
  () => {
3097
- const newAttributes = [...attributes, ...customAttributes];
3098
- const needUpdate = cart && !checkAttributesUpdateNeeded(
3343
+ const newAttributes = [...attributes];
3344
+ customAttributes.forEach((item) => {
3345
+ if (item.value && !newAttributes.some((attr) => attr.key === item.key)) {
3346
+ newAttributes.push(item);
3347
+ }
3348
+ });
3349
+ const needUpdate = cart && checkAttributesUpdateNeeded(
3099
3350
  cart.customAttributes,
3100
3351
  newAttributes,
3101
3352
  customAttributesNeedDelete
@@ -3118,7 +3369,8 @@ function CartProvider({
3118
3369
  cart,
3119
3370
  mutateCart,
3120
3371
  isCartLoading: isCartLoading || isCodeChanging,
3121
- setLoadingState
3372
+ setLoadingState,
3373
+ metafieldIdentifiers
3122
3374
  });
3123
3375
  const removeCustomAttributes = react.useCallback(
3124
3376
  (attributes2) => {
@@ -3199,8 +3451,14 @@ function CartProvider({
3199
3451
  );
3200
3452
  return result;
3201
3453
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
3454
+ const totalQuantity = react.useMemo(() => {
3455
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
3456
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3457
+ return cartLinesCount + giftLinesCount;
3458
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
3202
3459
  const value = react.useMemo(
3203
3460
  () => ({
3461
+ totalQuantity,
3204
3462
  cart,
3205
3463
  isCartLoading,
3206
3464
  triggerFetch: fetchCart,
@@ -3228,6 +3486,7 @@ function CartProvider({
3228
3486
  }),
3229
3487
  [
3230
3488
  cart,
3489
+ totalQuantity,
3231
3490
  isCartLoading,
3232
3491
  fetchCart,
3233
3492
  mutateCart,
@@ -3252,38 +3511,15 @@ function CartProvider({
3252
3511
  );
3253
3512
  return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
3254
3513
  }
3255
- function useCartContext() {
3514
+ function useCartContext(options) {
3256
3515
  const context = react.useContext(CartContext);
3257
- if (!context) {
3516
+ if (!context && !options?.optional) {
3258
3517
  throw new Error("useCartContext must be used within a CartProvider");
3259
3518
  }
3260
3519
  return context;
3261
3520
  }
3262
3521
 
3263
- Object.defineProperty(exports, "ShopifyConfig", {
3264
- enumerable: true,
3265
- get: function () { return shopifySdk.ShopifyConfig; }
3266
- });
3267
- Object.defineProperty(exports, "clearLocalStorage", {
3268
- enumerable: true,
3269
- get: function () { return shopifySdk.clearLocalStorage; }
3270
- });
3271
- Object.defineProperty(exports, "createShopifyClient", {
3272
- enumerable: true,
3273
- get: function () { return shopifySdk.createShopifyClient; }
3274
- });
3275
- Object.defineProperty(exports, "getLocalStorage", {
3276
- enumerable: true,
3277
- get: function () { return shopifySdk.getLocalStorage; }
3278
- });
3279
- Object.defineProperty(exports, "removeLocalStorage", {
3280
- enumerable: true,
3281
- get: function () { return shopifySdk.removeLocalStorage; }
3282
- });
3283
- Object.defineProperty(exports, "setLocalStorage", {
3284
- enumerable: true,
3285
- get: function () { return shopifySdk.setLocalStorage; }
3286
- });
3522
+ exports.BrowserPerformanceAdapter = BrowserPerformanceAdapter;
3287
3523
  exports.BuyRuleType = BuyRuleType;
3288
3524
  exports.CODE_AMOUNT_KEY = CODE_AMOUNT_KEY;
3289
3525
  exports.CUSTOMER_ATTRIBUTE_KEY = CUSTOMER_ATTRIBUTE_KEY;
@@ -3305,10 +3541,8 @@ exports.ShippingMethodMode = ShippingMethodMode;
3305
3541
  exports.ShopifyContext = ShopifyContext;
3306
3542
  exports.ShopifyProvider = ShopifyProvider;
3307
3543
  exports.SpendMoneyType = SpendMoneyType;
3308
- exports.atobID = atobID;
3309
3544
  exports.browserCartCookieAdapter = browserCartCookieAdapter;
3310
3545
  exports.browserCookieAdapter = browserCookieAdapter;
3311
- exports.btoaID = btoaID;
3312
3546
  exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
3313
3547
  exports.clearGeoLocationCache = clearGeoLocationCache;
3314
3548
  exports.createMockCartFromLines = createMockCartFromLines;
@@ -3331,7 +3565,6 @@ exports.trackBeginCheckoutGA = trackBeginCheckoutGA;
3331
3565
  exports.trackBuyNowFBQ = trackBuyNowFBQ;
3332
3566
  exports.trackBuyNowGA = trackBuyNowGA;
3333
3567
  exports.useAddCartLines = useAddCartLines;
3334
- exports.useAddPlusMemberProductsToCart = useAddPlusMemberProductsToCart;
3335
3568
  exports.useAddToCart = useAddToCart;
3336
3569
  exports.useAllBlogs = useAllBlogs;
3337
3570
  exports.useAllCollections = useAllCollections;
@@ -3341,6 +3574,7 @@ exports.useArticle = useArticle;
3341
3574
  exports.useArticles = useArticles;
3342
3575
  exports.useArticlesInBlog = useArticlesInBlog;
3343
3576
  exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
3577
+ exports.useAvailableDeliveryCoupon = useAvailableDeliveryCoupon;
3344
3578
  exports.useBlog = useBlog;
3345
3579
  exports.useBuyNow = useBuyNow;
3346
3580
  exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
@@ -3361,6 +3595,7 @@ exports.usePlusMemberCheckoutCustomAttributes = usePlusMemberCheckoutCustomAttri
3361
3595
  exports.usePlusMemberContext = usePlusMemberContext;
3362
3596
  exports.usePlusMemberDeliveryCodes = usePlusMemberDeliveryCodes;
3363
3597
  exports.usePlusMemberItemCustomAttributes = usePlusMemberItemCustomAttributes;
3598
+ exports.usePlusMemberNeedAddToCart = usePlusMemberNeedAddToCart;
3364
3599
  exports.usePlusMonthlyProductVariant = usePlusMonthlyProductVariant;
3365
3600
  exports.usePrice = usePrice;
3366
3601
  exports.useProduct = useProduct;
@@ -3379,8 +3614,15 @@ exports.useSite = useSite;
3379
3614
  exports.useUpdateCartAttributes = useUpdateCartAttributes;
3380
3615
  exports.useUpdateCartLines = useUpdateCartLines;
3381
3616
  exports.useUpdateLineCodeAmountAttributes = useUpdateLineCodeAmountAttributes;
3617
+ exports.useUpdatePlusMemberDeliveryOptions = useUpdatePlusMemberDeliveryOptions;
3382
3618
  exports.useUpdateVariantQuery = useUpdateVariantQuery;
3383
3619
  exports.useVariant = useVariant;
3384
3620
  exports.useVariantMedia = useVariantMedia;
3621
+ Object.keys(shopifySdk).forEach(function (k) {
3622
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
3623
+ enumerable: true,
3624
+ get: function () { return shopifySdk[k]; }
3625
+ });
3626
+ });
3385
3627
  //# sourceMappingURL=index.js.map
3386
3628
  //# sourceMappingURL=index.js.map