@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.
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
1
  import { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
2
- import { createShopifyClient, getProductsByHandles, createCart, updateCartCodes, addCartLines, updateCartLines, removeCartLines, updateCartAttributes, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getLocalStorage, getCart, setLocalStorage } from '@anker-in/shopify-sdk';
3
- export { ShopifyConfig, clearLocalStorage, createShopifyClient, getLocalStorage, removeLocalStorage, setLocalStorage } from '@anker-in/shopify-sdk';
2
+ import { createShopifyClient, getProductsByHandles, createCart, updateCartCodes, addCartLines, updateCartLines, removeCartLines, updateCartAttributes, getLocalStorage, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getCart, setLocalStorage, updateCartDeliveryOptions } from '@anker-in/shopify-sdk';
3
+ export * 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 useSWRMutation from 'swr/mutation';
9
10
  import { useRequest } from 'ahooks';
@@ -140,9 +141,10 @@ function normalizeAddToCartLines(lines) {
140
141
  const variant = line.variant;
141
142
  const product = variant.product;
142
143
  const quantity = line.quantity || 1;
143
- const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
144
- const subtotalAmount = price * quantity;
145
- const totalAmount = subtotalAmount;
144
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
145
+ const finalPrice = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : originalPrice;
146
+ const subtotalAmount = originalPrice * quantity;
147
+ const totalAmount = finalPrice * quantity;
146
148
  return {
147
149
  id: `temp-line-${index}-${variant.id}`,
148
150
  // Temporary ID for pre-cart lines
@@ -156,7 +158,7 @@ function normalizeAddToCartLines(lines) {
156
158
  customAttributes: line.attributes || [],
157
159
  variant: {
158
160
  id: variant.id,
159
- price,
161
+ price: finalPrice,
160
162
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
161
163
  sku: variant.sku || "",
162
164
  name: variant.title || "",
@@ -187,15 +189,16 @@ function createMockCartFromLines(lines, existingCart) {
187
189
  const normalizedLines = normalizeAddToCartLines(lines);
188
190
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
189
191
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
192
+ const currency = lines[0]?.variant?.price?.currencyCode;
190
193
  return {
191
194
  id: existingCart?.id || "temp-cart-id",
192
195
  customerId: existingCart?.customerId,
193
196
  email: existingCart?.email,
194
197
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
195
- currency: existingCart?.currency || { code: "USD" },
198
+ currency: existingCart?.currency || { code: currency },
196
199
  taxesIncluded: existingCart?.taxesIncluded,
197
200
  lineItems: normalizedLines,
198
- totallineItemsDiscount: 0,
201
+ totalLineItemsDiscount: 0,
199
202
  orderDiscounts: 0,
200
203
  lineItemsSubtotalPrice: subtotalPrice,
201
204
  subtotalPrice,
@@ -226,16 +229,6 @@ var getQuery = () => {
226
229
  }
227
230
  return theRequest;
228
231
  };
229
- function atobID(id) {
230
- if (id && typeof id === "string" && id.includes("/")) {
231
- return id.split("/").pop()?.split("?")?.shift();
232
- } else {
233
- return id;
234
- }
235
- }
236
- function btoaID(id, type = "ProductVariant") {
237
- return `gid://shopify/${type}/${id}`;
238
- }
239
232
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
240
233
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
241
234
  const matchedList = cartData?.lineItems?.filter((line) => {
@@ -445,6 +438,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
445
438
  }
446
439
  return cart;
447
440
  }, [lines, cart]);
441
+ console.log("effectiveCart useCalcAutoFreeGift", effectiveCart);
448
442
  const { activeCampaign, subtotal } = useMemo(() => {
449
443
  for (const campaign of autoFreeGiftConfig) {
450
444
  const { rule_conditions = [], rule_result } = campaign;
@@ -460,6 +454,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
460
454
  all_store_variant: spend_get_reward.main_product?.all_store_variant || false
461
455
  }
462
456
  );
457
+ console.log("matchedSubtotal useCalcAutoFreeGift", matchedSubtotal);
463
458
  if (matchedSubtotal > 0) {
464
459
  return { activeCampaign: campaign, subtotal: matchedSubtotal };
465
460
  }
@@ -472,11 +467,20 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
472
467
  return { qualifyingGift: null, nextTierGoal: null };
473
468
  }
474
469
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
475
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
476
- const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
470
+ const currentCurrency = effectiveCart?.currency?.code || "";
471
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency);
472
+ const getThresholdAmount = (tier) => {
473
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency]?.value) {
474
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency].value);
475
+ }
476
+ return Number(tier.spend_sum_money || 0);
477
+ };
478
+ const qualifyingTier = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
479
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
477
480
  if (!qualifyingTier) {
478
481
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
479
482
  }
483
+ const actualThreshold = getThresholdAmount(qualifyingTier);
480
484
  const formattedGift = {
481
485
  tier: qualifyingTier,
482
486
  itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
@@ -495,7 +499,10 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
495
499
  value: JSON.stringify({
496
500
  is_gift: true,
497
501
  rule_id: activeCampaign.rule_id,
498
- spend_sum_money: qualifyingTier.spend_sum_money
502
+ spend_sum_money: actualThreshold,
503
+ // 使用实际的门槛金额(多币种支持)
504
+ currency_code: currentCurrency
505
+ // 记录当前币种
499
506
  })
500
507
  }
501
508
  ]
@@ -503,7 +510,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
503
510
  }).filter((item) => item !== null)
504
511
  };
505
512
  return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
506
- }, [activeCampaign, subtotal]);
513
+ }, [activeCampaign, subtotal, effectiveCart]);
507
514
  const giftHandles = useMemo(() => {
508
515
  const giftVariant = autoFreeGiftConfig.map(
509
516
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -519,18 +526,24 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
519
526
  }
520
527
  return true;
521
528
  }, [giftHandles]);
522
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
523
- const res = await getProductsByHandles(client, {
524
- handles: giftHandles,
525
- locale
526
- });
527
- const result = Array.isArray(res) ? res : [];
528
- giftProductsCache.current = {
529
- data: result,
530
- giftHandles: [...giftHandles]
531
- };
532
- return result;
533
- });
529
+ const { data: giftProductsResult } = useSWR(
530
+ shouldFetch ? giftHandles : null,
531
+ async () => {
532
+ const res = await getProductsByHandles(client, {
533
+ handles: giftHandles,
534
+ locale
535
+ });
536
+ const result = Array.isArray(res) ? res : [];
537
+ giftProductsCache.current = {
538
+ data: result,
539
+ giftHandles: [...giftHandles]
540
+ };
541
+ return result;
542
+ },
543
+ {
544
+ revalidateOnFocus: false
545
+ }
546
+ );
534
547
  const finalGiftProductsResult = useMemo(() => {
535
548
  if (giftProductsCache.current && !shouldFetch) {
536
549
  return giftProductsCache.current.data || void 0;
@@ -583,12 +596,14 @@ var useScriptAutoFreeGift = ({
583
596
  upgrade_multiple2 = 1.2;
584
597
  upgrade_value2 = 40;
585
598
  }
586
- effectiveCart?.lineItems?.forEach(({ customAttributes }) => {
587
- customAttributes?.forEach(({ key, value }) => {
588
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
589
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
590
- });
591
- });
599
+ effectiveCart?.lineItems?.forEach(
600
+ ({ customAttributes }) => {
601
+ customAttributes?.forEach(({ key, value }) => {
602
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
603
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
604
+ });
605
+ }
606
+ );
592
607
  return [upgrade_multiple2, upgrade_value2];
593
608
  }, [effectiveCart?.lineItems, points_subscribe]);
594
609
  const breakpoints = useMemo(() => {
@@ -653,18 +668,24 @@ var useScriptAutoFreeGift = ({
653
668
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
654
669
  return [currentLevel, nextLevel];
655
670
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
656
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
657
- const res = await getProductsByHandles(client, {
658
- handles: giftHandles,
659
- locale
660
- });
661
- const result = Array.isArray(res) ? res : [];
662
- giftProductsCache.current = {
663
- data: result,
664
- giftHandles: [...giftHandles]
665
- };
666
- return result;
667
- });
671
+ const { data: giftProductsResult } = useSWR(
672
+ shouldFetch ? giftHandles : null,
673
+ async () => {
674
+ const res = await getProductsByHandles(client, {
675
+ handles: giftHandles,
676
+ locale
677
+ });
678
+ const result = Array.isArray(res) ? res : [];
679
+ giftProductsCache.current = {
680
+ data: result,
681
+ giftHandles: [...giftHandles]
682
+ };
683
+ return result;
684
+ },
685
+ {
686
+ revalidateOnFocus: false
687
+ }
688
+ );
668
689
  const finalGiftProductsResult = useMemo(() => {
669
690
  if (giftProductsCache.current && !shouldFetch) {
670
691
  return giftProductsCache.current.data || void 0;
@@ -850,10 +871,10 @@ var trackBuyNowGA = ({
850
871
  return;
851
872
  }
852
873
  const { variant } = lineItems[0];
853
- const currencyCode = variant.price?.currencyCode;
874
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
854
875
  const totalPrice = lineItems?.reduce(
855
876
  (prev, { variant: variant2 }) => prev.plus(
856
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
877
+ variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
857
878
  ),
858
879
  new Decimal2(0)
859
880
  ).toNumber();
@@ -927,7 +948,7 @@ function useApplyCartCodes(options) {
927
948
  if (!discountCodes?.length) {
928
949
  throw new Error("Invalid input used for this operation: Miss discountCode");
929
950
  }
930
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
951
+ const cartId = providedCartId || cart?.id;
931
952
  if (!cartId) {
932
953
  return void 0;
933
954
  }
@@ -940,6 +961,12 @@ function useApplyCartCodes(options) {
940
961
  cookieAdapter: cartCookieAdapter,
941
962
  metafieldIdentifiers
942
963
  });
964
+ const unApplicableCodes = discountCodes.filter(
965
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
966
+ );
967
+ if (unApplicableCodes.length) {
968
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
969
+ }
943
970
  if (updatedCart) {
944
971
  mutateCart(updatedCart);
945
972
  }
@@ -955,7 +982,7 @@ function useRemoveCartCodes(options) {
955
982
  const removeCodes = useCallback(
956
983
  async (_key, { arg }) => {
957
984
  const { cartId: providedCartId, discountCodes } = arg;
958
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
985
+ const cartId = providedCartId || cart?.id;
959
986
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
960
987
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
961
988
  const updatedCart = await updateCartCodes(client, {
@@ -974,10 +1001,65 @@ function useRemoveCartCodes(options) {
974
1001
  return useSWRMutation("remove-codes", removeCodes, options);
975
1002
  }
976
1003
 
1004
+ // src/hooks/cart/utils/add-to-cart.ts
1005
+ var getLinesWithAttributes = ({
1006
+ cart,
1007
+ lineItems
1008
+ }) => {
1009
+ return lineItems.map((line) => {
1010
+ const sameLineInCart = cart?.lineItems.find(
1011
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
1012
+ );
1013
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
1014
+ (attr) => attr.key === CODE_AMOUNT_KEY
1015
+ );
1016
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
1017
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
1018
+ );
1019
+ let functionAttribute = null;
1020
+ try {
1021
+ functionAttribute = sameLineInCart?.customAttributes?.find(
1022
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
1023
+ );
1024
+ } catch (error) {
1025
+ }
1026
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
1027
+ return {
1028
+ ...line,
1029
+ attributes: [
1030
+ ...line.attributes || [],
1031
+ codeAmountAttribute,
1032
+ functionAttribute,
1033
+ scriptCodeAmountAttribute
1034
+ ].filter(Boolean)
1035
+ };
1036
+ }
1037
+ return line;
1038
+ });
1039
+ };
1040
+ var getLinesWithFunctionAttributes = (lineItems) => {
1041
+ return lineItems.map((line) => {
1042
+ let itemAttributes = line.attributes || [];
1043
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
1044
+ if (!functionEnvAttribute) {
1045
+ itemAttributes = itemAttributes.concat([
1046
+ {
1047
+ key: CUSTOMER_ATTRIBUTE_KEY,
1048
+ value: JSON.stringify({
1049
+ is_gift: false,
1050
+ discounted_amount: Number(line.variant?.finalPrice?.amount || line.variant?.price?.amount) * (line.quantity || 1)
1051
+ })
1052
+ }
1053
+ ]);
1054
+ }
1055
+ return { ...line, attributes: itemAttributes };
1056
+ });
1057
+ };
1058
+
977
1059
  // src/hooks/cart/use-add-to-cart.ts
978
1060
  function useAddToCart({ withTrack = true } = {}, swrOptions) {
979
1061
  const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
980
- const { cart } = useCartContext();
1062
+ const { cart, addCustomAttributes } = useCartContext();
981
1063
  const { trigger: applyCartCodes } = useApplyCartCodes();
982
1064
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
983
1065
  const { trigger: addCartLines2 } = useAddCartLines();
@@ -991,12 +1073,18 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
991
1073
  buyerIdentity,
992
1074
  needCreateCart = false,
993
1075
  onCodesInvalid,
994
- replaceExistingCodes
1076
+ replaceExistingCodes,
1077
+ customAttributes
995
1078
  } = arg;
996
1079
  if (!lineItems || lineItems.length === 0) {
997
1080
  return;
998
1081
  }
999
- const lines = lineItems.map((item) => ({
1082
+ const linesWithAttributes = getLinesWithAttributes({
1083
+ cart,
1084
+ lineItems
1085
+ });
1086
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(linesWithAttributes);
1087
+ const lines = linesWithFunctionAttributes.map((item) => ({
1000
1088
  merchandiseId: item.variant?.id || "",
1001
1089
  quantity: item.quantity || 1,
1002
1090
  attributes: item.attributes,
@@ -1036,6 +1124,9 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
1036
1124
  discountCodes
1037
1125
  });
1038
1126
  }
1127
+ if (customAttributes && customAttributes.length > 0) {
1128
+ addCustomAttributes(customAttributes);
1129
+ }
1039
1130
  if (withTrack) {
1040
1131
  trackAddToCartGA({
1041
1132
  lineItems,
@@ -1144,7 +1235,8 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1144
1235
  if (!lineItems || lineItems.length === 0) {
1145
1236
  return;
1146
1237
  }
1147
- const lines = lineItems.map((item) => ({
1238
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(lineItems);
1239
+ const lines = linesWithFunctionAttributes.map((item) => ({
1148
1240
  merchandiseId: item.variant?.id || "",
1149
1241
  quantity: item.quantity || 1,
1150
1242
  attributes: item.attributes,
@@ -1292,9 +1384,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1292
1384
  discountAmount: 0
1293
1385
  };
1294
1386
  }
1295
- const tieredDiscounts = activeCampaign.result_detail.order_discount_conf.tiered_discounts;
1296
- const qualifyingTier = [...tieredDiscounts].reverse().find((tier) => subtotal >= Number(tier.amount));
1297
- const nextGoal = tieredDiscounts.find((tier) => subtotal < Number(tier.amount));
1387
+ const currentCurrency = cart?.currency?.code || "";
1388
+ console.log("currentCurrency", cart, currentCurrency);
1389
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1390
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1391
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1392
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1298
1393
  if (!qualifyingTier) {
1299
1394
  return {
1300
1395
  qualifyingDiscount: null,
@@ -1362,12 +1457,10 @@ function useHasPlusMemberInCart({
1362
1457
  };
1363
1458
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1364
1459
  }
1365
-
1366
- // src/hooks/cart/feature/use-cart-attributes.ts
1367
1460
  var getReferralAttributes = () => {
1368
- const inviteCode = Cookies5.get("invite_code");
1369
- const playModeId = Cookies5.get("playModeId");
1370
- const popup = Cookies5.get("_popup");
1461
+ const inviteCode = getLocalStorage("invite_code") || Cookies5.get("invite_code");
1462
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
1463
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
1371
1464
  if (inviteCode && playModeId) {
1372
1465
  return popup ? [
1373
1466
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1391,8 +1484,6 @@ var useCartAttributes = ({
1391
1484
  memberSetting,
1392
1485
  cart
1393
1486
  });
1394
- console.log("memberSetting", memberSetting);
1395
- console.log("hasPlusMember", hasPlusMember);
1396
1487
  useEffect(() => {
1397
1488
  setCurrentUrl(window.location.href);
1398
1489
  }, []);
@@ -1418,7 +1509,7 @@ var useCartAttributes = ({
1418
1509
  return "new_user_login";
1419
1510
  }, [customer]);
1420
1511
  const memberAttributes = useMemo(() => {
1421
- return [
1512
+ const attributes = [
1422
1513
  {
1423
1514
  key: "_token",
1424
1515
  value: profile?.token
@@ -1439,17 +1530,28 @@ var useCartAttributes = ({
1439
1530
  value: profile?.token ? "true" : "false"
1440
1531
  }
1441
1532
  ];
1533
+ if (profile?.token) {
1534
+ attributes.push({
1535
+ key: "_login_user",
1536
+ value: "1"
1537
+ });
1538
+ }
1539
+ return attributes;
1442
1540
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1443
1541
  const functionAttributes = useMemo(() => {
1444
- return [
1445
- cart?.discountCodes && {
1542
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1543
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1544
+ );
1545
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1546
+ return hasFunctionEnvAttribute ? [
1547
+ {
1446
1548
  key: "_discounts_function_env",
1447
1549
  value: JSON.stringify({
1448
- discount_code: cart?.discountCodes.map((item) => item.code),
1550
+ discount_code: discountCodes,
1449
1551
  user_tags: customer?.tags || []
1450
1552
  })
1451
1553
  }
1452
- ];
1554
+ ] : [];
1453
1555
  }, [cart]);
1454
1556
  const presellAttributes = useMemo(() => {
1455
1557
  return [
@@ -1481,18 +1583,50 @@ var useCartAttributes = ({
1481
1583
  }
1482
1584
  ];
1483
1585
  }, [currentUrl]);
1586
+ const commonAttributes = useMemo(
1587
+ () => [
1588
+ ...memberAttributes,
1589
+ ...functionAttributes,
1590
+ ...presellAttributes,
1591
+ ...weightAttributes,
1592
+ ...trackingAttributes,
1593
+ ...getReferralAttributes()
1594
+ ].filter((item) => item?.value),
1595
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1596
+ );
1597
+ const extraAttributesInCart = useMemo(() => {
1598
+ const commonAttributeKeys = [
1599
+ // member attributes
1600
+ "_token",
1601
+ "_member_type",
1602
+ "_user_type",
1603
+ "_is_login",
1604
+ "_login_user",
1605
+ // function attributes
1606
+ "_discounts_function_env",
1607
+ // presell attributes
1608
+ "_presale",
1609
+ // weight attributes
1610
+ "_weight",
1611
+ "_app_source_name",
1612
+ // tracking attributes
1613
+ "utm_params",
1614
+ // referral attributes
1615
+ "_invite_code",
1616
+ "_play_mode_id",
1617
+ "_popup"
1618
+ ];
1619
+ return cart?.customAttributes?.filter(
1620
+ (item) => !commonAttributeKeys.includes(item.key)
1621
+ ) || [];
1622
+ }, [cart]);
1484
1623
  return useMemo(
1485
1624
  () => ({
1486
- attributes: [
1487
- ...memberAttributes,
1488
- ...functionAttributes,
1489
- ...presellAttributes,
1490
- ...weightAttributes,
1491
- ...trackingAttributes,
1492
- ...getReferralAttributes()
1493
- ].filter((item) => item?.value)
1625
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1626
+ (item) => item?.value
1627
+ )
1494
1628
  }),
1495
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1629
+ [commonAttributes, extraAttributesInCart]
1496
1630
  );
1497
1631
  };
1498
1632
  var DEFAULT_MIN = 1;
@@ -1555,7 +1689,7 @@ var useUpdateLineCodeAmountAttributes = ({
1555
1689
  );
1556
1690
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1557
1691
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1558
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1692
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1559
1693
  attrNeedUpdate.push({
1560
1694
  key: CUSTOMER_ATTRIBUTE_KEY,
1561
1695
  value: JSON.stringify({
@@ -1594,29 +1728,22 @@ var useUpdateLineCodeAmountAttributes = ({
1594
1728
  }).filter(
1595
1729
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1596
1730
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1731
+ let lineId = line.id;
1732
+ let attributes = line.customAttributes || [];
1733
+ if (attrNeedDelete.length) {
1734
+ attributes = attributes.filter(
1735
+ (attr) => !attrNeedDelete.includes(attr.key)
1736
+ );
1737
+ }
1597
1738
  if (attrNeedUpdate.length) {
1598
- return {
1599
- id: line.id,
1600
- attributes: [
1601
- ...line.customAttributes?.filter(
1602
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1603
- ) || [],
1604
- ...attrNeedUpdate
1605
- ]
1606
- };
1607
- } else if (attrNeedDelete.length) {
1608
- return {
1609
- id: line.id,
1610
- attributes: line.customAttributes?.filter(
1611
- (attr) => !attrNeedDelete.includes(attr.key)
1612
- ) || []
1613
- };
1614
- } else {
1615
- return {
1616
- id: line.id,
1617
- attributes: line.customAttributes || []
1618
- };
1739
+ attributes = attributes.filter(
1740
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1741
+ ).concat(attrNeedUpdate);
1619
1742
  }
1743
+ return {
1744
+ id: lineId,
1745
+ attributes
1746
+ };
1620
1747
  }),
1621
1748
  [cart?.lineItems, mainProductDiscountCodes]
1622
1749
  );
@@ -1709,8 +1836,9 @@ function useProductsByHandles(options = {}) {
1709
1836
  metafieldIdentifiers
1710
1837
  });
1711
1838
  },
1712
- swrOptions || {
1713
- revalidateOnFocus: false
1839
+ {
1840
+ revalidateOnFocus: false,
1841
+ ...swrOptions
1714
1842
  }
1715
1843
  );
1716
1844
  }
@@ -2626,6 +2754,73 @@ var usePlusMemberDeliveryCodes = ({
2626
2754
  [deliveryData]
2627
2755
  );
2628
2756
  };
2757
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2758
+ const { client, locale, cartCookieAdapter } = useShopify();
2759
+ const updateDeliveryOptions = useCallback(
2760
+ async (_key, { arg }) => {
2761
+ const updatedCart = await updateCartDeliveryOptions(client, {
2762
+ ...arg,
2763
+ metafieldIdentifiers,
2764
+ cookieAdapter: cartCookieAdapter
2765
+ });
2766
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2767
+ if (updatedCart) {
2768
+ mutate(updatedCart);
2769
+ }
2770
+ return updatedCart;
2771
+ },
2772
+ [client, locale, cartCookieAdapter, mutate]
2773
+ );
2774
+ return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2775
+ }
2776
+
2777
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2778
+ var useUpdatePlusMemberDeliveryOptions = ({
2779
+ options
2780
+ } = {}) => {
2781
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2782
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2783
+ mutateCart,
2784
+ metafieldIdentifiers
2785
+ );
2786
+ const handler = useCallback(
2787
+ async (_, { arg }) => {
2788
+ const currentCart = arg?.cart || cartContextData;
2789
+ const { deliveryData } = arg;
2790
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2791
+ const deliveryGroupId = firstDeliveryGroup?.id;
2792
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2793
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2794
+ return null;
2795
+ }
2796
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2797
+ (group) => group?.id === deliveryGroupId
2798
+ );
2799
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2800
+ (option) => option?.code === selectedOptionCode
2801
+ );
2802
+ if (!matchedOption?.handle) {
2803
+ return null;
2804
+ }
2805
+ const deliveryOptions = [
2806
+ {
2807
+ deliveryGroupId,
2808
+ deliveryOptionHandle: matchedOption.handle
2809
+ }
2810
+ ];
2811
+ const updatedCart = await updateCartDeliveryOptions2({
2812
+ selectedDeliveryOptions: deliveryOptions,
2813
+ cartId: currentCart?.id
2814
+ });
2815
+ if (updatedCart && mutateCart) {
2816
+ mutateCart(updatedCart);
2817
+ }
2818
+ return updatedCart;
2819
+ },
2820
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2821
+ );
2822
+ return useSWRMutation("update-cart-delivery-options", handler, options);
2823
+ };
2629
2824
  var usePlusMemberItemCustomAttributes = ({
2630
2825
  deliveryData
2631
2826
  }) => {
@@ -2645,48 +2840,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2645
2840
  deliveryData,
2646
2841
  product,
2647
2842
  variant,
2648
- customer,
2649
2843
  isShowShippingBenefits
2650
2844
  }) => {
2651
2845
  const { deliveryCustomData } = deliveryData || {};
2652
2846
  const { profile } = usePlusMemberContext();
2653
- const userType = useMemo(() => {
2654
- const customerInfo = customer;
2655
- if (!customerInfo) {
2656
- return "new_user_unlogin";
2657
- }
2658
- if (customer) {
2659
- const { orders = {} } = customer;
2660
- const edgesLength = orders?.edges?.length;
2661
- if (edgesLength === 1) {
2662
- return "old_user_orders_once";
2663
- } else if (edgesLength && edgesLength > 1) {
2664
- return "old_user_orders_twice";
2665
- }
2666
- }
2667
- return "new_user_login";
2668
- }, [customer]);
2669
2847
  return useMemo(() => {
2670
2848
  const checkoutCustomAttributes = [
2671
- {
2672
- key: "_token",
2673
- value: profile?.token || ""
2674
- },
2849
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2675
2850
  {
2676
2851
  key: "_last_url",
2677
2852
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2678
- },
2679
- {
2680
- key: "_user_type",
2681
- value: userType
2682
2853
  }
2683
2854
  ];
2684
- if (profile) {
2685
- checkoutCustomAttributes.push({
2686
- key: "_login_user",
2687
- value: "1"
2688
- });
2689
- }
2690
2855
  if (deliveryCustomData) {
2691
2856
  checkoutCustomAttributes.push({
2692
2857
  key: "_checkout_delivery_custom",
@@ -2696,12 +2861,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2696
2861
  })
2697
2862
  });
2698
2863
  }
2699
- if (variant?.metafields?.presell) {
2700
- checkoutCustomAttributes.push({
2701
- key: "_presale",
2702
- value: "true"
2703
- });
2704
- }
2705
2864
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2706
2865
  checkoutCustomAttributes.push({
2707
2866
  key: "_hide_shipping",
@@ -2709,18 +2868,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2709
2868
  });
2710
2869
  }
2711
2870
  return checkoutCustomAttributes;
2712
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2871
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2713
2872
  };
2714
2873
  function useAutoRemovePlusMemberInCart({
2715
- metafields,
2716
- isMonthlyPlus,
2717
- isAnnualPlus
2874
+ cart,
2875
+ profile,
2876
+ memberSetting
2718
2877
  }) {
2719
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2720
- const { cart } = useCartContext();
2878
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2721
2879
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2722
2880
  useEffect(() => {
2723
- if (!cart) return;
2881
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2724
2882
  const removePlusProduct = async (productType) => {
2725
2883
  if (!productType) return;
2726
2884
  const product = cart.lineItems?.find(
@@ -2732,33 +2890,25 @@ function useAutoRemovePlusMemberInCart({
2732
2890
  });
2733
2891
  }
2734
2892
  };
2735
- if (isMonthlyPlus) {
2893
+ if (profile?.isMonthlyPlus) {
2736
2894
  removePlusProduct(plus_monthly_product);
2737
2895
  }
2738
- if (isAnnualPlus) {
2896
+ if (profile?.isAnnualPlus) {
2739
2897
  removePlusProduct(plus_annual_product);
2740
2898
  }
2741
- }, [
2742
- cart,
2743
- plus_annual_product,
2744
- plus_monthly_product,
2745
- isAnnualPlus,
2746
- isMonthlyPlus,
2747
- removeCartLines2
2748
- ]);
2899
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2749
2900
  }
2750
2901
  function useAddPlusMemberProductsToCart({
2751
2902
  cart,
2752
- memberSetting,
2753
- selectedPlusMemberMode,
2754
- selectedPlusMemberProduct
2903
+ profile
2755
2904
  }) {
2905
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2756
2906
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2757
- cart,
2758
- memberSetting
2907
+ memberSetting: plusMemberMetafields,
2908
+ cart
2759
2909
  });
2760
2910
  const plusMemberProduct = useMemo(() => {
2761
- if (selectedPlusMemberMode === "free" /* FREE */) {
2911
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2762
2912
  return void 0;
2763
2913
  }
2764
2914
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2767,7 +2917,10 @@ function useAddPlusMemberProductsToCart({
2767
2917
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2768
2918
  return void 0;
2769
2919
  }
2770
- if (!selectedPlusMemberProduct) {
2920
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2921
+ return void 0;
2922
+ }
2923
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2771
2924
  return void 0;
2772
2925
  }
2773
2926
  return selectedPlusMemberProduct;
@@ -3086,8 +3239,13 @@ function CartProvider({
3086
3239
  const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
3087
3240
  useRequest(
3088
3241
  () => {
3089
- const newAttributes = [...attributes, ...customAttributes];
3090
- const needUpdate = cart && !checkAttributesUpdateNeeded(
3242
+ const newAttributes = [...attributes];
3243
+ customAttributes.forEach((item) => {
3244
+ if (item.value && !newAttributes.some((attr) => attr.key === item.key)) {
3245
+ newAttributes.push(item);
3246
+ }
3247
+ });
3248
+ const needUpdate = cart && checkAttributesUpdateNeeded(
3091
3249
  cart.customAttributes,
3092
3250
  newAttributes,
3093
3251
  customAttributesNeedDelete
@@ -3191,8 +3349,14 @@ function CartProvider({
3191
3349
  );
3192
3350
  return result;
3193
3351
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
3352
+ const totalQuantity = useMemo(() => {
3353
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
3354
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3355
+ return cartLinesCount + giftLinesCount;
3356
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
3194
3357
  const value = useMemo(
3195
3358
  () => ({
3359
+ totalQuantity,
3196
3360
  cart,
3197
3361
  isCartLoading,
3198
3362
  triggerFetch: fetchCart,
@@ -3220,6 +3384,7 @@ function CartProvider({
3220
3384
  }),
3221
3385
  [
3222
3386
  cart,
3387
+ totalQuantity,
3223
3388
  isCartLoading,
3224
3389
  fetchCart,
3225
3390
  mutateCart,
@@ -3252,6 +3417,6 @@ function useCartContext() {
3252
3417
  return context;
3253
3418
  }
3254
3419
 
3255
- export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, CartProvider, DeliveryPlusType, MAIN_PRODUCT_CODE, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, ShopifyContext, ShopifyProvider, SpendMoneyType, atobID, browserCartCookieAdapter, browserCookieAdapter, btoaID, checkAttributesUpdateNeeded, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, gaTrack, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, normalizeAddToCartLines, preCheck, safeParse, trackAddToCartFBQ, trackAddToCartGA, trackBeginCheckoutGA, trackBuyNowFBQ, trackBuyNowGA, useAddCartLines, useAddPlusMemberProductsToCart, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartContext, 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, useShopify, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3420
+ export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, CartProvider, DeliveryPlusType, MAIN_PRODUCT_CODE, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, ShopifyContext, ShopifyProvider, SpendMoneyType, browserCartCookieAdapter, browserCookieAdapter, checkAttributesUpdateNeeded, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, gaTrack, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, normalizeAddToCartLines, preCheck, safeParse, trackAddToCartFBQ, trackAddToCartGA, trackBeginCheckoutGA, trackBuyNowFBQ, trackBuyNowGA, useAddCartLines, useAddPlusMemberProductsToCart, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartContext, 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, useShopify, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdatePlusMemberDeliveryOptions, useUpdateVariantQuery, useVariant, useVariantMedia };
3256
3421
  //# sourceMappingURL=index.mjs.map
3257
3422
  //# sourceMappingURL=index.mjs.map