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

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;
@@ -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,6 +864,12 @@ 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
  }
@@ -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, {
@@ -877,10 +904,65 @@ function useRemoveCartCodes(options) {
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,
@@ -1047,7 +1138,8 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1047
1138
  if (!lineItems || lineItems.length === 0) {
1048
1139
  return;
1049
1140
  }
1050
- const lines = lineItems.map((item) => ({
1141
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(lineItems);
1142
+ const lines = linesWithFunctionAttributes.map((item) => ({
1051
1143
  merchandiseId: item.variant?.id || "",
1052
1144
  quantity: item.quantity || 1,
1053
1145
  attributes: item.attributes,
@@ -1195,9 +1287,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1195
1287
  discountAmount: 0
1196
1288
  };
1197
1289
  }
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));
1290
+ const currentCurrency = cart?.currency?.code || "";
1291
+ console.log("currentCurrency", cart, currentCurrency);
1292
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1293
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1294
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1295
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1201
1296
  if (!qualifyingTier) {
1202
1297
  return {
1203
1298
  qualifyingDiscount: null,
@@ -1265,12 +1360,10 @@ function useHasPlusMemberInCart({
1265
1360
  };
1266
1361
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1267
1362
  }
1268
-
1269
- // src/hooks/cart/feature/use-cart-attributes.ts
1270
1363
  var getReferralAttributes = () => {
1271
- const inviteCode = Cookies5.get("invite_code");
1272
- const playModeId = Cookies5.get("playModeId");
1273
- const popup = Cookies5.get("_popup");
1364
+ const inviteCode = getLocalStorage("invite_code") || Cookies5.get("invite_code");
1365
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
1366
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
1274
1367
  if (inviteCode && playModeId) {
1275
1368
  return popup ? [
1276
1369
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1294,8 +1387,6 @@ var useCartAttributes = ({
1294
1387
  memberSetting,
1295
1388
  cart
1296
1389
  });
1297
- console.log("memberSetting", memberSetting);
1298
- console.log("hasPlusMember", hasPlusMember);
1299
1390
  useEffect(() => {
1300
1391
  setCurrentUrl(window.location.href);
1301
1392
  }, []);
@@ -1321,7 +1412,7 @@ var useCartAttributes = ({
1321
1412
  return "new_user_login";
1322
1413
  }, [customer]);
1323
1414
  const memberAttributes = useMemo(() => {
1324
- return [
1415
+ const attributes = [
1325
1416
  {
1326
1417
  key: "_token",
1327
1418
  value: profile?.token
@@ -1342,17 +1433,28 @@ var useCartAttributes = ({
1342
1433
  value: profile?.token ? "true" : "false"
1343
1434
  }
1344
1435
  ];
1436
+ if (profile?.token) {
1437
+ attributes.push({
1438
+ key: "_login_user",
1439
+ value: "1"
1440
+ });
1441
+ }
1442
+ return attributes;
1345
1443
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1346
1444
  const functionAttributes = useMemo(() => {
1347
- return [
1348
- cart?.discountCodes && {
1445
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1446
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1447
+ );
1448
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1449
+ return hasFunctionEnvAttribute ? [
1450
+ {
1349
1451
  key: "_discounts_function_env",
1350
1452
  value: JSON.stringify({
1351
- discount_code: cart?.discountCodes.map((item) => item.code),
1453
+ discount_code: discountCodes,
1352
1454
  user_tags: customer?.tags || []
1353
1455
  })
1354
1456
  }
1355
- ];
1457
+ ] : [];
1356
1458
  }, [cart]);
1357
1459
  const presellAttributes = useMemo(() => {
1358
1460
  return [
@@ -1384,18 +1486,50 @@ var useCartAttributes = ({
1384
1486
  }
1385
1487
  ];
1386
1488
  }, [currentUrl]);
1489
+ const commonAttributes = useMemo(
1490
+ () => [
1491
+ ...memberAttributes,
1492
+ ...functionAttributes,
1493
+ ...presellAttributes,
1494
+ ...weightAttributes,
1495
+ ...trackingAttributes,
1496
+ ...getReferralAttributes()
1497
+ ].filter((item) => item?.value),
1498
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1499
+ );
1500
+ const extraAttributesInCart = useMemo(() => {
1501
+ const commonAttributeKeys = [
1502
+ // member attributes
1503
+ "_token",
1504
+ "_member_type",
1505
+ "_user_type",
1506
+ "_is_login",
1507
+ "_login_user",
1508
+ // function attributes
1509
+ "_discounts_function_env",
1510
+ // presell attributes
1511
+ "_presale",
1512
+ // weight attributes
1513
+ "_weight",
1514
+ "_app_source_name",
1515
+ // tracking attributes
1516
+ "utm_params",
1517
+ // referral attributes
1518
+ "_invite_code",
1519
+ "_play_mode_id",
1520
+ "_popup"
1521
+ ];
1522
+ return cart?.customAttributes?.filter(
1523
+ (item) => !commonAttributeKeys.includes(item.key)
1524
+ ) || [];
1525
+ }, [cart]);
1387
1526
  return useMemo(
1388
1527
  () => ({
1389
- attributes: [
1390
- ...memberAttributes,
1391
- ...functionAttributes,
1392
- ...presellAttributes,
1393
- ...weightAttributes,
1394
- ...trackingAttributes,
1395
- ...getReferralAttributes()
1396
- ].filter((item) => item?.value)
1528
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1529
+ (item) => item?.value
1530
+ )
1397
1531
  }),
1398
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1532
+ [commonAttributes, extraAttributesInCart]
1399
1533
  );
1400
1534
  };
1401
1535
  var DEFAULT_MIN = 1;
@@ -1458,7 +1592,7 @@ var useUpdateLineCodeAmountAttributes = ({
1458
1592
  );
1459
1593
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1460
1594
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1461
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1595
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1462
1596
  attrNeedUpdate.push({
1463
1597
  key: CUSTOMER_ATTRIBUTE_KEY,
1464
1598
  value: JSON.stringify({
@@ -1497,29 +1631,22 @@ var useUpdateLineCodeAmountAttributes = ({
1497
1631
  }).filter(
1498
1632
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1499
1633
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1634
+ let lineId = line.id;
1635
+ let attributes = line.customAttributes || [];
1636
+ if (attrNeedDelete.length) {
1637
+ attributes = attributes.filter(
1638
+ (attr) => !attrNeedDelete.includes(attr.key)
1639
+ );
1640
+ }
1500
1641
  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
- };
1642
+ attributes = attributes.filter(
1643
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1644
+ ).concat(attrNeedUpdate);
1522
1645
  }
1646
+ return {
1647
+ id: lineId,
1648
+ attributes
1649
+ };
1523
1650
  }),
1524
1651
  [cart?.lineItems, mainProductDiscountCodes]
1525
1652
  );
@@ -1612,8 +1739,9 @@ function useProductsByHandles(options = {}) {
1612
1739
  metafieldIdentifiers
1613
1740
  });
1614
1741
  },
1615
- swrOptions || {
1616
- revalidateOnFocus: false
1742
+ {
1743
+ revalidateOnFocus: false,
1744
+ ...swrOptions
1617
1745
  }
1618
1746
  );
1619
1747
  }
@@ -2529,6 +2657,73 @@ var usePlusMemberDeliveryCodes = ({
2529
2657
  [deliveryData]
2530
2658
  );
2531
2659
  };
2660
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2661
+ const { client, locale, cartCookieAdapter } = useShopify();
2662
+ const updateDeliveryOptions = useCallback(
2663
+ async (_key, { arg }) => {
2664
+ const updatedCart = await updateCartDeliveryOptions(client, {
2665
+ ...arg,
2666
+ metafieldIdentifiers,
2667
+ cookieAdapter: cartCookieAdapter
2668
+ });
2669
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2670
+ if (updatedCart) {
2671
+ mutate(updatedCart);
2672
+ }
2673
+ return updatedCart;
2674
+ },
2675
+ [client, locale, cartCookieAdapter, mutate]
2676
+ );
2677
+ return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2678
+ }
2679
+
2680
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2681
+ var useUpdatePlusMemberDeliveryOptions = ({
2682
+ options
2683
+ } = {}) => {
2684
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2685
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2686
+ mutateCart,
2687
+ metafieldIdentifiers
2688
+ );
2689
+ const handler = useCallback(
2690
+ async (_, { arg }) => {
2691
+ const currentCart = arg?.cart || cartContextData;
2692
+ const { deliveryData } = arg;
2693
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2694
+ const deliveryGroupId = firstDeliveryGroup?.id;
2695
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2696
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2697
+ return null;
2698
+ }
2699
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2700
+ (group) => group?.id === deliveryGroupId
2701
+ );
2702
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2703
+ (option) => option?.code === selectedOptionCode
2704
+ );
2705
+ if (!matchedOption?.handle) {
2706
+ return null;
2707
+ }
2708
+ const deliveryOptions = [
2709
+ {
2710
+ deliveryGroupId,
2711
+ deliveryOptionHandle: matchedOption.handle
2712
+ }
2713
+ ];
2714
+ const updatedCart = await updateCartDeliveryOptions2({
2715
+ selectedDeliveryOptions: deliveryOptions,
2716
+ cartId: currentCart?.id
2717
+ });
2718
+ if (updatedCart && mutateCart) {
2719
+ mutateCart(updatedCart);
2720
+ }
2721
+ return updatedCart;
2722
+ },
2723
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2724
+ );
2725
+ return useSWRMutation("update-cart-delivery-options", handler, options);
2726
+ };
2532
2727
  var usePlusMemberItemCustomAttributes = ({
2533
2728
  deliveryData
2534
2729
  }) => {
@@ -2548,48 +2743,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2548
2743
  deliveryData,
2549
2744
  product,
2550
2745
  variant,
2551
- customer,
2552
2746
  isShowShippingBenefits
2553
2747
  }) => {
2554
2748
  const { deliveryCustomData } = deliveryData || {};
2555
2749
  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
2750
  return useMemo(() => {
2573
2751
  const checkoutCustomAttributes = [
2574
- {
2575
- key: "_token",
2576
- value: profile?.token || ""
2577
- },
2752
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2578
2753
  {
2579
2754
  key: "_last_url",
2580
2755
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2581
- },
2582
- {
2583
- key: "_user_type",
2584
- value: userType
2585
2756
  }
2586
2757
  ];
2587
- if (profile) {
2588
- checkoutCustomAttributes.push({
2589
- key: "_login_user",
2590
- value: "1"
2591
- });
2592
- }
2593
2758
  if (deliveryCustomData) {
2594
2759
  checkoutCustomAttributes.push({
2595
2760
  key: "_checkout_delivery_custom",
@@ -2599,12 +2764,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2599
2764
  })
2600
2765
  });
2601
2766
  }
2602
- if (variant?.metafields?.presell) {
2603
- checkoutCustomAttributes.push({
2604
- key: "_presale",
2605
- value: "true"
2606
- });
2607
- }
2608
2767
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2609
2768
  checkoutCustomAttributes.push({
2610
2769
  key: "_hide_shipping",
@@ -2612,18 +2771,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2612
2771
  });
2613
2772
  }
2614
2773
  return checkoutCustomAttributes;
2615
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2774
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2616
2775
  };
2617
2776
  function useAutoRemovePlusMemberInCart({
2618
- metafields,
2619
- isMonthlyPlus,
2620
- isAnnualPlus
2777
+ cart,
2778
+ profile,
2779
+ memberSetting
2621
2780
  }) {
2622
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2623
- const { cart } = useCartContext();
2781
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2624
2782
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2625
2783
  useEffect(() => {
2626
- if (!cart) return;
2784
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2627
2785
  const removePlusProduct = async (productType) => {
2628
2786
  if (!productType) return;
2629
2787
  const product = cart.lineItems?.find(
@@ -2635,33 +2793,25 @@ function useAutoRemovePlusMemberInCart({
2635
2793
  });
2636
2794
  }
2637
2795
  };
2638
- if (isMonthlyPlus) {
2796
+ if (profile?.isMonthlyPlus) {
2639
2797
  removePlusProduct(plus_monthly_product);
2640
2798
  }
2641
- if (isAnnualPlus) {
2799
+ if (profile?.isAnnualPlus) {
2642
2800
  removePlusProduct(plus_annual_product);
2643
2801
  }
2644
- }, [
2645
- cart,
2646
- plus_annual_product,
2647
- plus_monthly_product,
2648
- isAnnualPlus,
2649
- isMonthlyPlus,
2650
- removeCartLines2
2651
- ]);
2802
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2652
2803
  }
2653
2804
  function useAddPlusMemberProductsToCart({
2654
2805
  cart,
2655
- memberSetting,
2656
- selectedPlusMemberMode,
2657
- selectedPlusMemberProduct
2806
+ profile
2658
2807
  }) {
2808
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2659
2809
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2660
- cart,
2661
- memberSetting
2810
+ memberSetting: plusMemberMetafields,
2811
+ cart
2662
2812
  });
2663
2813
  const plusMemberProduct = useMemo(() => {
2664
- if (selectedPlusMemberMode === "free" /* FREE */) {
2814
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2665
2815
  return void 0;
2666
2816
  }
2667
2817
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2670,7 +2820,10 @@ function useAddPlusMemberProductsToCart({
2670
2820
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2671
2821
  return void 0;
2672
2822
  }
2673
- if (!selectedPlusMemberProduct) {
2823
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2824
+ return void 0;
2825
+ }
2826
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2674
2827
  return void 0;
2675
2828
  }
2676
2829
  return selectedPlusMemberProduct;
@@ -2944,6 +3097,6 @@ function clearGeoLocationCache(cacheKey = "geoLocation") {
2944
3097
  }
2945
3098
  }
2946
3099
 
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 };
3100
+ 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
3101
  //# sourceMappingURL=index.mjs.map
2949
3102
  //# sourceMappingURL=index.mjs.map