@anker-in/shopify-react 0.1.1-beta.3 → 0.1.1-beta.31

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.
@@ -1,9 +1,10 @@
1
1
  import { createContext, useMemo, useRef, useState, useEffect, useCallback, useContext } from 'react';
2
2
  import useSWRMutation from 'swr/mutation';
3
- import { getProductsByHandles, createCart, updateCartCodes, addCartLines, updateCartLines, removeCartLines, updateCartAttributes, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getLocalStorage, setLocalStorage } from '@anker-in/shopify-sdk';
3
+ import { getProductsByHandles, createCart, updateCartCodes, addCartLines, updateCartLines, removeCartLines, updateCartAttributes, getLocalStorage, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, setLocalStorage, updateCartDeliveryOptions } from '@anker-in/shopify-sdk';
4
4
  import Cookies5 from 'js-cookie';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
  import Decimal2 from 'decimal.js';
7
+ import { atobID, btoaID } from '@anker-in/shopify-core';
7
8
  import useSWR from 'swr';
8
9
  import { useRequest } from 'ahooks';
9
10
 
@@ -68,9 +69,10 @@ function normalizeAddToCartLines(lines) {
68
69
  const variant = line.variant;
69
70
  const product = variant.product;
70
71
  const quantity = line.quantity || 1;
71
- const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
72
- const subtotalAmount = price * quantity;
73
- const totalAmount = subtotalAmount;
72
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
73
+ const finalPrice = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : originalPrice;
74
+ const subtotalAmount = originalPrice * quantity;
75
+ const totalAmount = finalPrice * quantity;
74
76
  return {
75
77
  id: `temp-line-${index}-${variant.id}`,
76
78
  // Temporary ID for pre-cart lines
@@ -84,7 +86,7 @@ function normalizeAddToCartLines(lines) {
84
86
  customAttributes: line.attributes || [],
85
87
  variant: {
86
88
  id: variant.id,
87
- price,
89
+ price: finalPrice,
88
90
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
89
91
  sku: variant.sku || "",
90
92
  name: variant.title || "",
@@ -115,15 +117,16 @@ function createMockCartFromLines(lines, existingCart) {
115
117
  const normalizedLines = normalizeAddToCartLines(lines);
116
118
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
117
119
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
120
+ const currency = lines[0]?.variant?.price?.currencyCode;
118
121
  return {
119
122
  id: existingCart?.id || "temp-cart-id",
120
123
  customerId: existingCart?.customerId,
121
124
  email: existingCart?.email,
122
125
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
123
- currency: existingCart?.currency || { code: "USD" },
126
+ currency: existingCart?.currency || { code: currency },
124
127
  taxesIncluded: existingCart?.taxesIncluded,
125
128
  lineItems: normalizedLines,
126
- totallineItemsDiscount: 0,
129
+ totalLineItemsDiscount: 0,
127
130
  orderDiscounts: 0,
128
131
  lineItemsSubtotalPrice: subtotalPrice,
129
132
  subtotalPrice,
@@ -154,16 +157,6 @@ var getQuery = () => {
154
157
  }
155
158
  return theRequest;
156
159
  };
157
- function atobID(id) {
158
- if (id && typeof id === "string" && id.includes("/")) {
159
- return id.split("/").pop()?.split("?")?.shift();
160
- } else {
161
- return id;
162
- }
163
- }
164
- function btoaID(id, type = "ProductVariant") {
165
- return `gid://shopify/${type}/${id}`;
166
- }
167
160
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
168
161
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
169
162
  const matchedList = cartData?.lineItems?.filter((line) => {
@@ -373,6 +366,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
373
366
  }
374
367
  return cart;
375
368
  }, [lines, cart]);
369
+ console.log("effectiveCart useCalcAutoFreeGift", effectiveCart);
376
370
  const { activeCampaign, subtotal } = useMemo(() => {
377
371
  for (const campaign of autoFreeGiftConfig) {
378
372
  const { rule_conditions = [], rule_result } = campaign;
@@ -388,6 +382,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
388
382
  all_store_variant: spend_get_reward.main_product?.all_store_variant || false
389
383
  }
390
384
  );
385
+ console.log("matchedSubtotal useCalcAutoFreeGift", matchedSubtotal);
391
386
  if (matchedSubtotal > 0) {
392
387
  return { activeCampaign: campaign, subtotal: matchedSubtotal };
393
388
  }
@@ -400,11 +395,20 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
400
395
  return { qualifyingGift: null, nextTierGoal: null };
401
396
  }
402
397
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
403
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
404
- const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
398
+ const currentCurrency = effectiveCart?.currency?.code || "";
399
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency);
400
+ const getThresholdAmount = (tier) => {
401
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency]?.value) {
402
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency].value);
403
+ }
404
+ return Number(tier.spend_sum_money || 0);
405
+ };
406
+ const qualifyingTier = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
407
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
405
408
  if (!qualifyingTier) {
406
409
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
407
410
  }
411
+ const actualThreshold = getThresholdAmount(qualifyingTier);
408
412
  const formattedGift = {
409
413
  tier: qualifyingTier,
410
414
  itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
@@ -423,7 +427,10 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
423
427
  value: JSON.stringify({
424
428
  is_gift: true,
425
429
  rule_id: activeCampaign.rule_id,
426
- spend_sum_money: qualifyingTier.spend_sum_money
430
+ spend_sum_money: actualThreshold,
431
+ // 使用实际的门槛金额(多币种支持)
432
+ currency_code: currentCurrency
433
+ // 记录当前币种
427
434
  })
428
435
  }
429
436
  ]
@@ -431,7 +438,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
431
438
  }).filter((item) => item !== null)
432
439
  };
433
440
  return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
434
- }, [activeCampaign, subtotal]);
441
+ }, [activeCampaign, subtotal, effectiveCart]);
435
442
  const giftHandles = useMemo(() => {
436
443
  const giftVariant = autoFreeGiftConfig.map(
437
444
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -447,18 +454,24 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
447
454
  }
448
455
  return true;
449
456
  }, [giftHandles]);
450
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
451
- const res = await getProductsByHandles(client, {
452
- handles: giftHandles,
453
- locale
454
- });
455
- const result = Array.isArray(res) ? res : [];
456
- giftProductsCache.current = {
457
- data: result,
458
- giftHandles: [...giftHandles]
459
- };
460
- return result;
461
- });
457
+ const { data: giftProductsResult } = useSWR(
458
+ shouldFetch ? giftHandles : null,
459
+ async () => {
460
+ const res = await getProductsByHandles(client, {
461
+ handles: giftHandles,
462
+ locale
463
+ });
464
+ const result = Array.isArray(res) ? res : [];
465
+ giftProductsCache.current = {
466
+ data: result,
467
+ giftHandles: [...giftHandles]
468
+ };
469
+ return result;
470
+ },
471
+ {
472
+ revalidateOnFocus: false
473
+ }
474
+ );
462
475
  const finalGiftProductsResult = useMemo(() => {
463
476
  if (giftProductsCache.current && !shouldFetch) {
464
477
  return giftProductsCache.current.data || void 0;
@@ -511,12 +524,14 @@ var useScriptAutoFreeGift = ({
511
524
  upgrade_multiple2 = 1.2;
512
525
  upgrade_value2 = 40;
513
526
  }
514
- effectiveCart?.lineItems?.forEach(({ customAttributes }) => {
515
- customAttributes?.forEach(({ key, value }) => {
516
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
517
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
518
- });
519
- });
527
+ effectiveCart?.lineItems?.forEach(
528
+ ({ customAttributes }) => {
529
+ customAttributes?.forEach(({ key, value }) => {
530
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
531
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
532
+ });
533
+ }
534
+ );
520
535
  return [upgrade_multiple2, upgrade_value2];
521
536
  }, [effectiveCart?.lineItems, points_subscribe]);
522
537
  const breakpoints = useMemo(() => {
@@ -581,18 +596,24 @@ var useScriptAutoFreeGift = ({
581
596
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
582
597
  return [currentLevel, nextLevel];
583
598
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
584
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
585
- const res = await getProductsByHandles(client, {
586
- handles: giftHandles,
587
- locale
588
- });
589
- const result = Array.isArray(res) ? res : [];
590
- giftProductsCache.current = {
591
- data: result,
592
- giftHandles: [...giftHandles]
593
- };
594
- return result;
595
- });
599
+ const { data: giftProductsResult } = useSWR(
600
+ shouldFetch ? giftHandles : null,
601
+ async () => {
602
+ const res = await getProductsByHandles(client, {
603
+ handles: giftHandles,
604
+ locale
605
+ });
606
+ const result = Array.isArray(res) ? res : [];
607
+ giftProductsCache.current = {
608
+ data: result,
609
+ giftHandles: [...giftHandles]
610
+ };
611
+ return result;
612
+ },
613
+ {
614
+ revalidateOnFocus: false
615
+ }
616
+ );
596
617
  const finalGiftProductsResult = useMemo(() => {
597
618
  if (giftProductsCache.current && !shouldFetch) {
598
619
  return giftProductsCache.current.data || void 0;
@@ -625,9 +646,9 @@ var useScriptAutoFreeGift = ({
625
646
  };
626
647
  };
627
648
  var CartContext = createContext(null);
628
- function useCartContext() {
649
+ function useCartContext(options) {
629
650
  const context = useContext(CartContext);
630
- if (!context) {
651
+ if (!context && true) {
631
652
  throw new Error("useCartContext must be used within a CartProvider");
632
653
  }
633
654
  return context;
@@ -753,10 +774,10 @@ var trackBuyNowGA = ({
753
774
  return;
754
775
  }
755
776
  const { variant } = lineItems[0];
756
- const currencyCode = variant.price?.currencyCode;
777
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
757
778
  const totalPrice = lineItems?.reduce(
758
779
  (prev, { variant: variant2 }) => prev.plus(
759
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
780
+ variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
760
781
  ),
761
782
  new Decimal2(0)
762
783
  ).toNumber();
@@ -830,7 +851,7 @@ function useApplyCartCodes(options) {
830
851
  if (!discountCodes?.length) {
831
852
  throw new Error("Invalid input used for this operation: Miss discountCode");
832
853
  }
833
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
854
+ const cartId = providedCartId || cart?.id;
834
855
  if (!cartId) {
835
856
  return void 0;
836
857
  }
@@ -843,12 +864,18 @@ function useApplyCartCodes(options) {
843
864
  cookieAdapter: cartCookieAdapter,
844
865
  metafieldIdentifiers
845
866
  });
867
+ const unApplicableCodes = discountCodes.filter(
868
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
869
+ );
870
+ if (unApplicableCodes.length) {
871
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
872
+ }
846
873
  if (updatedCart) {
847
874
  mutateCart(updatedCart);
848
875
  }
849
876
  return updatedCart;
850
877
  },
851
- [client, locale, cartCookieAdapter, mutateCart, cart]
878
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
852
879
  );
853
880
  return useSWRMutation("apply-codes", applyCodes, options);
854
881
  }
@@ -858,7 +885,7 @@ function useRemoveCartCodes(options) {
858
885
  const removeCodes = useCallback(
859
886
  async (_key, { arg }) => {
860
887
  const { cartId: providedCartId, discountCodes } = arg;
861
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
888
+ const cartId = providedCartId || cart?.id;
862
889
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
863
890
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
864
891
  const updatedCart = await updateCartCodes(client, {
@@ -872,15 +899,70 @@ function useRemoveCartCodes(options) {
872
899
  }
873
900
  return updatedCart;
874
901
  },
875
- [client, locale, cartCookieAdapter, mutateCart, cart]
902
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
876
903
  );
877
904
  return useSWRMutation("remove-codes", removeCodes, options);
878
905
  }
879
906
 
907
+ // src/hooks/cart/utils/add-to-cart.ts
908
+ var getLinesWithAttributes = ({
909
+ cart,
910
+ lineItems
911
+ }) => {
912
+ return lineItems.map((line) => {
913
+ const sameLineInCart = cart?.lineItems.find(
914
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
915
+ );
916
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
917
+ (attr) => attr.key === CODE_AMOUNT_KEY
918
+ );
919
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
920
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
921
+ );
922
+ let functionAttribute = null;
923
+ try {
924
+ functionAttribute = sameLineInCart?.customAttributes?.find(
925
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
926
+ );
927
+ } catch (error) {
928
+ }
929
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
930
+ return {
931
+ ...line,
932
+ attributes: [
933
+ ...line.attributes || [],
934
+ codeAmountAttribute,
935
+ functionAttribute,
936
+ scriptCodeAmountAttribute
937
+ ].filter(Boolean)
938
+ };
939
+ }
940
+ return line;
941
+ });
942
+ };
943
+ var getLinesWithFunctionAttributes = (lineItems) => {
944
+ return lineItems.map((line) => {
945
+ let itemAttributes = line.attributes || [];
946
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
947
+ if (!functionEnvAttribute) {
948
+ itemAttributes = itemAttributes.concat([
949
+ {
950
+ key: CUSTOMER_ATTRIBUTE_KEY,
951
+ value: JSON.stringify({
952
+ is_gift: false,
953
+ discounted_amount: Number(line.variant?.finalPrice?.amount || line.variant?.price?.amount) * (line.quantity || 1)
954
+ })
955
+ }
956
+ ]);
957
+ }
958
+ return { ...line, attributes: itemAttributes };
959
+ });
960
+ };
961
+
880
962
  // src/hooks/cart/use-add-to-cart.ts
881
963
  function useAddToCart({ withTrack = true } = {}, swrOptions) {
882
964
  const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
883
- const { cart } = useCartContext();
965
+ const { cart, addCustomAttributes } = useCartContext();
884
966
  const { trigger: applyCartCodes } = useApplyCartCodes();
885
967
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
886
968
  const { trigger: addCartLines2 } = useAddCartLines();
@@ -894,12 +976,18 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
894
976
  buyerIdentity,
895
977
  needCreateCart = false,
896
978
  onCodesInvalid,
897
- replaceExistingCodes
979
+ replaceExistingCodes,
980
+ customAttributes
898
981
  } = arg;
899
982
  if (!lineItems || lineItems.length === 0) {
900
983
  return;
901
984
  }
902
- const lines = lineItems.map((item) => ({
985
+ const linesWithAttributes = getLinesWithAttributes({
986
+ cart,
987
+ lineItems
988
+ });
989
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(linesWithAttributes);
990
+ const lines = linesWithFunctionAttributes.map((item) => ({
903
991
  merchandiseId: item.variant?.id || "",
904
992
  quantity: item.quantity || 1,
905
993
  attributes: item.attributes,
@@ -939,6 +1027,9 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
939
1027
  discountCodes
940
1028
  });
941
1029
  }
1030
+ if (customAttributes && customAttributes.length > 0) {
1031
+ addCustomAttributes(customAttributes);
1032
+ }
942
1033
  if (withTrack) {
943
1034
  trackAddToCartGA({
944
1035
  lineItems,
@@ -965,9 +1056,10 @@ function useUpdateCartLines(options) {
965
1056
  if (updatedCart) {
966
1057
  mutateCart(updatedCart);
967
1058
  }
1059
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
968
1060
  return updatedCart;
969
1061
  },
970
- [client, locale, cartCookieAdapter, mutateCart]
1062
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
971
1063
  );
972
1064
  return useSWRMutation("update-cart-lines", updateLines, options);
973
1065
  }
@@ -1006,7 +1098,7 @@ function useRemoveCartLines(options) {
1006
1098
  }
1007
1099
  return updatedCart;
1008
1100
  },
1009
- [client, locale, cartCookieAdapter, mutateCart]
1101
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1010
1102
  );
1011
1103
  return useSWRMutation("remove-cart-lines", removeLines, options);
1012
1104
  }
@@ -1025,7 +1117,7 @@ function useUpdateCartAttributes(mutate, metafieldIdentifiers, options) {
1025
1117
  }
1026
1118
  return updatedCart;
1027
1119
  },
1028
- [client, locale, cartCookieAdapter, mutate]
1120
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers]
1029
1121
  );
1030
1122
  return useSWRMutation("update-cart-attributes", updateAttributes, options);
1031
1123
  }
@@ -1047,7 +1139,8 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1047
1139
  if (!lineItems || lineItems.length === 0) {
1048
1140
  return;
1049
1141
  }
1050
- const lines = lineItems.map((item) => ({
1142
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(lineItems);
1143
+ const lines = linesWithFunctionAttributes.map((item) => ({
1051
1144
  merchandiseId: item.variant?.id || "",
1052
1145
  quantity: item.quantity || 1,
1053
1146
  attributes: item.attributes,
@@ -1165,7 +1258,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1165
1258
  const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
1166
1259
  const dealsType = "";
1167
1260
  const { activeCampaign, subtotal } = useMemo(() => {
1168
- for (const campaign of orderDiscountConfig) {
1261
+ for (const campaign of orderDiscountConfig || []) {
1169
1262
  const { rule_conditions = [], result_detail } = campaign;
1170
1263
  const { main_product, order_discount_conf } = result_detail || {};
1171
1264
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
@@ -1195,9 +1288,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1195
1288
  discountAmount: 0
1196
1289
  };
1197
1290
  }
1198
- const tieredDiscounts = activeCampaign.result_detail.order_discount_conf.tiered_discounts;
1199
- const qualifyingTier = [...tieredDiscounts].reverse().find((tier) => subtotal >= Number(tier.amount));
1200
- const nextGoal = tieredDiscounts.find((tier) => subtotal < Number(tier.amount));
1291
+ const currentCurrency = cart?.currency?.code || "";
1292
+ console.log("currentCurrency", cart, currentCurrency);
1293
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1294
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1295
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1296
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1201
1297
  if (!qualifyingTier) {
1202
1298
  return {
1203
1299
  qualifyingDiscount: null,
@@ -1265,12 +1361,10 @@ function useHasPlusMemberInCart({
1265
1361
  };
1266
1362
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1267
1363
  }
1268
-
1269
- // src/hooks/cart/feature/use-cart-attributes.ts
1270
1364
  var getReferralAttributes = () => {
1271
- const inviteCode = Cookies5.get("invite_code");
1272
- const playModeId = Cookies5.get("playModeId");
1273
- const popup = Cookies5.get("_popup");
1365
+ const inviteCode = getLocalStorage("inviteCode") || Cookies5.get("inviteCode");
1366
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
1367
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
1274
1368
  if (inviteCode && playModeId) {
1275
1369
  return popup ? [
1276
1370
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1294,8 +1388,6 @@ var useCartAttributes = ({
1294
1388
  memberSetting,
1295
1389
  cart
1296
1390
  });
1297
- console.log("memberSetting", memberSetting);
1298
- console.log("hasPlusMember", hasPlusMember);
1299
1391
  useEffect(() => {
1300
1392
  setCurrentUrl(window.location.href);
1301
1393
  }, []);
@@ -1321,7 +1413,7 @@ var useCartAttributes = ({
1321
1413
  return "new_user_login";
1322
1414
  }, [customer]);
1323
1415
  const memberAttributes = useMemo(() => {
1324
- return [
1416
+ const attributes = [
1325
1417
  {
1326
1418
  key: "_token",
1327
1419
  value: profile?.token
@@ -1342,17 +1434,28 @@ var useCartAttributes = ({
1342
1434
  value: profile?.token ? "true" : "false"
1343
1435
  }
1344
1436
  ];
1437
+ if (profile?.token) {
1438
+ attributes.push({
1439
+ key: "_login_user",
1440
+ value: "1"
1441
+ });
1442
+ }
1443
+ return attributes;
1345
1444
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1346
1445
  const functionAttributes = useMemo(() => {
1347
- return [
1348
- cart?.discountCodes && {
1446
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1447
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1448
+ );
1449
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1450
+ return hasFunctionEnvAttribute ? [
1451
+ {
1349
1452
  key: "_discounts_function_env",
1350
1453
  value: JSON.stringify({
1351
- discount_code: cart?.discountCodes.map((item) => item.code),
1454
+ discount_code: discountCodes,
1352
1455
  user_tags: customer?.tags || []
1353
1456
  })
1354
1457
  }
1355
- ];
1458
+ ] : [];
1356
1459
  }, [cart]);
1357
1460
  const presellAttributes = useMemo(() => {
1358
1461
  return [
@@ -1384,18 +1487,50 @@ var useCartAttributes = ({
1384
1487
  }
1385
1488
  ];
1386
1489
  }, [currentUrl]);
1490
+ const commonAttributes = useMemo(
1491
+ () => [
1492
+ ...memberAttributes,
1493
+ ...functionAttributes,
1494
+ ...presellAttributes,
1495
+ ...weightAttributes,
1496
+ ...trackingAttributes,
1497
+ ...getReferralAttributes()
1498
+ ].filter((item) => item?.value),
1499
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1500
+ );
1501
+ const extraAttributesInCart = useMemo(() => {
1502
+ const commonAttributeKeys = [
1503
+ // member attributes
1504
+ "_token",
1505
+ "_member_type",
1506
+ "_user_type",
1507
+ "_is_login",
1508
+ "_login_user",
1509
+ // function attributes
1510
+ "_discounts_function_env",
1511
+ // presell attributes
1512
+ "_presale",
1513
+ // weight attributes
1514
+ "_weight",
1515
+ "_app_source_name",
1516
+ // tracking attributes
1517
+ "utm_params",
1518
+ // referral attributes
1519
+ "_invite_code",
1520
+ "_play_mode_id",
1521
+ "_popup"
1522
+ ];
1523
+ return cart?.customAttributes?.filter(
1524
+ (item) => !commonAttributeKeys.includes(item.key)
1525
+ ) || [];
1526
+ }, [cart]);
1387
1527
  return useMemo(
1388
1528
  () => ({
1389
- attributes: [
1390
- ...memberAttributes,
1391
- ...functionAttributes,
1392
- ...presellAttributes,
1393
- ...weightAttributes,
1394
- ...trackingAttributes,
1395
- ...getReferralAttributes()
1396
- ].filter((item) => item?.value)
1529
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1530
+ (item) => item?.value
1531
+ )
1397
1532
  }),
1398
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1533
+ [commonAttributes, extraAttributesInCart]
1399
1534
  );
1400
1535
  };
1401
1536
  var DEFAULT_MIN = 1;
@@ -1458,7 +1593,7 @@ var useUpdateLineCodeAmountAttributes = ({
1458
1593
  );
1459
1594
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1460
1595
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1461
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1596
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1462
1597
  attrNeedUpdate.push({
1463
1598
  key: CUSTOMER_ATTRIBUTE_KEY,
1464
1599
  value: JSON.stringify({
@@ -1497,29 +1632,22 @@ var useUpdateLineCodeAmountAttributes = ({
1497
1632
  }).filter(
1498
1633
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1499
1634
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1635
+ let lineId = line.id;
1636
+ let attributes = line.customAttributes || [];
1637
+ if (attrNeedDelete.length) {
1638
+ attributes = attributes.filter(
1639
+ (attr) => !attrNeedDelete.includes(attr.key)
1640
+ );
1641
+ }
1500
1642
  if (attrNeedUpdate.length) {
1501
- return {
1502
- id: line.id,
1503
- attributes: [
1504
- ...line.customAttributes?.filter(
1505
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1506
- ) || [],
1507
- ...attrNeedUpdate
1508
- ]
1509
- };
1510
- } else if (attrNeedDelete.length) {
1511
- return {
1512
- id: line.id,
1513
- attributes: line.customAttributes?.filter(
1514
- (attr) => !attrNeedDelete.includes(attr.key)
1515
- ) || []
1516
- };
1517
- } else {
1518
- return {
1519
- id: line.id,
1520
- attributes: line.customAttributes || []
1521
- };
1643
+ attributes = attributes.filter(
1644
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1645
+ ).concat(attrNeedUpdate);
1522
1646
  }
1647
+ return {
1648
+ id: lineId,
1649
+ attributes
1650
+ };
1523
1651
  }),
1524
1652
  [cart?.lineItems, mainProductDiscountCodes]
1525
1653
  );
@@ -1612,8 +1740,9 @@ function useProductsByHandles(options = {}) {
1612
1740
  metafieldIdentifiers
1613
1741
  });
1614
1742
  },
1615
- swrOptions || {
1616
- revalidateOnFocus: false
1743
+ {
1744
+ revalidateOnFocus: false,
1745
+ ...swrOptions
1617
1746
  }
1618
1747
  );
1619
1748
  }
@@ -2529,6 +2658,73 @@ var usePlusMemberDeliveryCodes = ({
2529
2658
  [deliveryData]
2530
2659
  );
2531
2660
  };
2661
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2662
+ const { client, locale, cartCookieAdapter } = useShopify();
2663
+ const updateDeliveryOptions = useCallback(
2664
+ async (_key, { arg }) => {
2665
+ const updatedCart = await updateCartDeliveryOptions(client, {
2666
+ ...arg,
2667
+ metafieldIdentifiers,
2668
+ cookieAdapter: cartCookieAdapter
2669
+ });
2670
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2671
+ if (updatedCart) {
2672
+ mutate(updatedCart);
2673
+ }
2674
+ return updatedCart;
2675
+ },
2676
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers]
2677
+ );
2678
+ return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2679
+ }
2680
+
2681
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2682
+ var useUpdatePlusMemberDeliveryOptions = ({
2683
+ options
2684
+ } = {}) => {
2685
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2686
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2687
+ mutateCart,
2688
+ metafieldIdentifiers
2689
+ );
2690
+ const handler = useCallback(
2691
+ async (_, { arg }) => {
2692
+ const currentCart = arg?.cart || cartContextData;
2693
+ const { deliveryData } = arg;
2694
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2695
+ const deliveryGroupId = firstDeliveryGroup?.id;
2696
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2697
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2698
+ return null;
2699
+ }
2700
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2701
+ (group) => group?.id === deliveryGroupId
2702
+ );
2703
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2704
+ (option) => option?.code === selectedOptionCode
2705
+ );
2706
+ if (!matchedOption?.handle) {
2707
+ return null;
2708
+ }
2709
+ const deliveryOptions = [
2710
+ {
2711
+ deliveryGroupId,
2712
+ deliveryOptionHandle: matchedOption.handle
2713
+ }
2714
+ ];
2715
+ const updatedCart = await updateCartDeliveryOptions2({
2716
+ selectedDeliveryOptions: deliveryOptions,
2717
+ cartId: currentCart?.id
2718
+ });
2719
+ if (updatedCart && mutateCart) {
2720
+ mutateCart(updatedCart);
2721
+ }
2722
+ return updatedCart;
2723
+ },
2724
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2725
+ );
2726
+ return useSWRMutation("update-cart-delivery-options", handler, options);
2727
+ };
2532
2728
  var usePlusMemberItemCustomAttributes = ({
2533
2729
  deliveryData
2534
2730
  }) => {
@@ -2548,48 +2744,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2548
2744
  deliveryData,
2549
2745
  product,
2550
2746
  variant,
2551
- customer,
2552
2747
  isShowShippingBenefits
2553
2748
  }) => {
2554
2749
  const { deliveryCustomData } = deliveryData || {};
2555
2750
  const { profile } = usePlusMemberContext();
2556
- const userType = useMemo(() => {
2557
- const customerInfo = customer;
2558
- if (!customerInfo) {
2559
- return "new_user_unlogin";
2560
- }
2561
- if (customer) {
2562
- const { orders = {} } = customer;
2563
- const edgesLength = orders?.edges?.length;
2564
- if (edgesLength === 1) {
2565
- return "old_user_orders_once";
2566
- } else if (edgesLength && edgesLength > 1) {
2567
- return "old_user_orders_twice";
2568
- }
2569
- }
2570
- return "new_user_login";
2571
- }, [customer]);
2572
2751
  return useMemo(() => {
2573
2752
  const checkoutCustomAttributes = [
2574
- {
2575
- key: "_token",
2576
- value: profile?.token || ""
2577
- },
2753
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2578
2754
  {
2579
2755
  key: "_last_url",
2580
2756
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2581
- },
2582
- {
2583
- key: "_user_type",
2584
- value: userType
2585
2757
  }
2586
2758
  ];
2587
- if (profile) {
2588
- checkoutCustomAttributes.push({
2589
- key: "_login_user",
2590
- value: "1"
2591
- });
2592
- }
2593
2759
  if (deliveryCustomData) {
2594
2760
  checkoutCustomAttributes.push({
2595
2761
  key: "_checkout_delivery_custom",
@@ -2599,12 +2765,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2599
2765
  })
2600
2766
  });
2601
2767
  }
2602
- if (variant?.metafields?.presell) {
2603
- checkoutCustomAttributes.push({
2604
- key: "_presale",
2605
- value: "true"
2606
- });
2607
- }
2608
2768
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2609
2769
  checkoutCustomAttributes.push({
2610
2770
  key: "_hide_shipping",
@@ -2612,18 +2772,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2612
2772
  });
2613
2773
  }
2614
2774
  return checkoutCustomAttributes;
2615
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2775
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2616
2776
  };
2617
2777
  function useAutoRemovePlusMemberInCart({
2618
- metafields,
2619
- isMonthlyPlus,
2620
- isAnnualPlus
2778
+ cart,
2779
+ profile,
2780
+ memberSetting
2621
2781
  }) {
2622
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2623
- const { cart } = useCartContext();
2782
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2624
2783
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2625
2784
  useEffect(() => {
2626
- if (!cart) return;
2785
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2627
2786
  const removePlusProduct = async (productType) => {
2628
2787
  if (!productType) return;
2629
2788
  const product = cart.lineItems?.find(
@@ -2635,33 +2794,25 @@ function useAutoRemovePlusMemberInCart({
2635
2794
  });
2636
2795
  }
2637
2796
  };
2638
- if (isMonthlyPlus) {
2797
+ if (profile?.isMonthlyPlus) {
2639
2798
  removePlusProduct(plus_monthly_product);
2640
2799
  }
2641
- if (isAnnualPlus) {
2800
+ if (profile?.isAnnualPlus) {
2642
2801
  removePlusProduct(plus_annual_product);
2643
2802
  }
2644
- }, [
2645
- cart,
2646
- plus_annual_product,
2647
- plus_monthly_product,
2648
- isAnnualPlus,
2649
- isMonthlyPlus,
2650
- removeCartLines2
2651
- ]);
2803
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2652
2804
  }
2653
2805
  function useAddPlusMemberProductsToCart({
2654
2806
  cart,
2655
- memberSetting,
2656
- selectedPlusMemberMode,
2657
- selectedPlusMemberProduct
2807
+ profile
2658
2808
  }) {
2809
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2659
2810
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2660
- cart,
2661
- memberSetting
2811
+ memberSetting: plusMemberMetafields,
2812
+ cart
2662
2813
  });
2663
2814
  const plusMemberProduct = useMemo(() => {
2664
- if (selectedPlusMemberMode === "free" /* FREE */) {
2815
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2665
2816
  return void 0;
2666
2817
  }
2667
2818
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2670,7 +2821,10 @@ function useAddPlusMemberProductsToCart({
2670
2821
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2671
2822
  return void 0;
2672
2823
  }
2673
- if (!selectedPlusMemberProduct) {
2824
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2825
+ return void 0;
2826
+ }
2827
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2674
2828
  return void 0;
2675
2829
  }
2676
2830
  return selectedPlusMemberProduct;
@@ -2944,6 +3098,6 @@ function clearGeoLocationCache(cacheKey = "geoLocation") {
2944
3098
  }
2945
3099
  }
2946
3100
 
2947
- export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, DeliveryPlusType, MAIN_PRODUCT_CODE, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, SpendMoneyType, atobID, btoaID, checkAttributesUpdateNeeded, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, normalizeAddToCartLines, preCheck, safeParse, useAddCartLines, useAddPlusMemberProductsToCart, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useIntersection, usePlusAnnualProductVariant, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberDeliveryCodes, usePlusMemberItemCustomAttributes, usePlusMonthlyProductVariant, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethodAvailableCheck, useShippingMethods, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3101
+ export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, DeliveryPlusType, MAIN_PRODUCT_CODE, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, SpendMoneyType, checkAttributesUpdateNeeded, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, normalizeAddToCartLines, preCheck, safeParse, useAddCartLines, useAddPlusMemberProductsToCart, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useIntersection, usePlusAnnualProductVariant, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberDeliveryCodes, usePlusMemberItemCustomAttributes, usePlusMonthlyProductVariant, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethodAvailableCheck, useShippingMethods, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdatePlusMemberDeliveryOptions, useUpdateVariantQuery, useVariant, useVariantMedia };
2948
3102
  //# sourceMappingURL=index.mjs.map
2949
3103
  //# sourceMappingURL=index.mjs.map