@anker-in/shopify-react 0.1.1-beta.2 → 0.1.1-beta.21

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,6 +1,6 @@
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 { atobID, btoaID, 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';
@@ -62,6 +62,83 @@ var CODE_AMOUNT_KEY = "_sku_code_money";
62
62
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
63
63
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
64
64
 
65
+ // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
66
+ function normalizeAddToCartLines(lines) {
67
+ return lines.filter((line) => line.variant?.id).map((line, index) => {
68
+ const variant = line.variant;
69
+ const product = variant.product;
70
+ 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;
74
+ return {
75
+ id: `temp-line-${index}-${variant.id}`,
76
+ // Temporary ID for pre-cart lines
77
+ name: product?.title || variant.title || "",
78
+ quantity,
79
+ variantId: variant.id,
80
+ productId: product?.id || variant.id.split("/").slice(0, -2).join("/"),
81
+ totalAmount,
82
+ subtotalAmount,
83
+ discountAllocations: [],
84
+ customAttributes: line.attributes || [],
85
+ variant: {
86
+ id: variant.id,
87
+ price,
88
+ listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
89
+ sku: variant.sku || "",
90
+ name: variant.title || "",
91
+ image: variant.image ? {
92
+ url: variant.image.url,
93
+ altText: variant.image.altText || void 0
94
+ } : void 0,
95
+ requiresShipping: false,
96
+ // Default value, not available in NormalizedProductVariant
97
+ availableForSale: variant.availableForSale ?? true,
98
+ quantityAvailable: variant.quantityAvailable ?? 0,
99
+ currentlyNotInStock: false,
100
+ // Default value, will be updated when added to cart
101
+ weight: variant.weight,
102
+ metafields: variant.metafields
103
+ },
104
+ product,
105
+ path: product?.handle ? `/products/${product.handle}` : "",
106
+ discounts: [],
107
+ options: variant.selectedOptions?.map((opt) => ({
108
+ name: opt.name,
109
+ value: opt.value
110
+ }))
111
+ };
112
+ });
113
+ }
114
+ function createMockCartFromLines(lines, existingCart) {
115
+ const normalizedLines = normalizeAddToCartLines(lines);
116
+ const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
117
+ const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
118
+ console.log("lines createMockCartFromLines", lines);
119
+ const currency = lines[0]?.variant?.price?.currencyCode;
120
+ return {
121
+ id: existingCart?.id || "temp-cart-id",
122
+ customerId: existingCart?.customerId,
123
+ email: existingCart?.email,
124
+ createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
125
+ currency: existingCart?.currency?.code || { code: currency },
126
+ taxesIncluded: existingCart?.taxesIncluded,
127
+ lineItems: normalizedLines,
128
+ totalLineItemsDiscount: 0,
129
+ orderDiscounts: 0,
130
+ lineItemsSubtotalPrice: subtotalPrice,
131
+ subtotalPrice,
132
+ totalPrice,
133
+ totalTaxAmount: 0,
134
+ discountCodes: existingCart?.discountCodes || [],
135
+ discountAllocations: [],
136
+ url: existingCart?.url || "",
137
+ ready: true,
138
+ customAttributes: existingCart?.customAttributes
139
+ };
140
+ }
141
+
65
142
  // src/hooks/cart/utils/index.ts
66
143
  var getQuery = () => {
67
144
  const url = typeof window !== "undefined" ? window.location.search : "";
@@ -79,16 +156,6 @@ var getQuery = () => {
79
156
  }
80
157
  return theRequest;
81
158
  };
82
- function atobID(id) {
83
- if (id && typeof id === "string" && id.includes("/")) {
84
- return id.split("/").pop()?.split("?")?.shift();
85
- } else {
86
- return id;
87
- }
88
- }
89
- function btoaID(id, type = "ProductVariant") {
90
- return `gid://shopify/${type}/${id}`;
91
- }
92
159
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
93
160
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
94
161
  const matchedList = cartData?.lineItems?.filter((line) => {
@@ -286,12 +353,18 @@ var formatFunctionAutoFreeGift = ({
286
353
  };
287
354
  return result;
288
355
  };
289
- var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
356
+ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
290
357
  const tags = useMemo(() => customer?.tags || [], [customer?.tags]);
291
358
  const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
292
359
  const dealsType = "";
293
360
  const { client, locale } = useShopify();
294
361
  const giftProductsCache = useRef(null);
362
+ const effectiveCart = useMemo(() => {
363
+ if (lines && lines.length > 0) {
364
+ return createMockCartFromLines(lines, cart);
365
+ }
366
+ return cart;
367
+ }, [lines, cart]);
295
368
  const { activeCampaign, subtotal } = useMemo(() => {
296
369
  for (const campaign of autoFreeGiftConfig) {
297
370
  const { rule_conditions = [], rule_result } = campaign;
@@ -299,7 +372,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
299
372
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
300
373
  if (isPreCheckPassed && spend_get_reward) {
301
374
  const matchedSubtotal = getMatchedMainProductSubTotal(
302
- cart,
375
+ effectiveCart,
303
376
  spend_get_reward.main_product?.variant_list?.map((v) => v.variant_id) || [],
304
377
  {
305
378
  spend_money_type: spend_get_reward.main_product?.spend_money_type || 1,
@@ -313,17 +386,26 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
313
386
  }
314
387
  }
315
388
  return { activeCampaign: null, subtotal: 0 };
316
- }, [autoFreeGiftConfig, cart, tags, dealsType]);
389
+ }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
317
390
  const { qualifyingGift, nextTierGoal } = useMemo(() => {
318
391
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
319
392
  return { qualifyingGift: null, nextTierGoal: null };
320
393
  }
321
394
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
322
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
323
- const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
395
+ const currentCurrency = effectiveCart?.currency?.code || "";
396
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency);
397
+ const getThresholdAmount = (tier) => {
398
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency]?.value) {
399
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency].value);
400
+ }
401
+ return Number(tier.spend_sum_money || 0);
402
+ };
403
+ const qualifyingTier = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
404
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
324
405
  if (!qualifyingTier) {
325
406
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
326
407
  }
408
+ const actualThreshold = getThresholdAmount(qualifyingTier);
327
409
  const formattedGift = {
328
410
  tier: qualifyingTier,
329
411
  itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
@@ -342,7 +424,10 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
342
424
  value: JSON.stringify({
343
425
  is_gift: true,
344
426
  rule_id: activeCampaign.rule_id,
345
- spend_sum_money: qualifyingTier.spend_sum_money
427
+ spend_sum_money: actualThreshold,
428
+ // 使用实际的门槛金额(多币种支持)
429
+ currency_code: currentCurrency
430
+ // 记录当前币种
346
431
  })
347
432
  }
348
433
  ]
@@ -350,7 +435,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
350
435
  }).filter((item) => item !== null)
351
436
  };
352
437
  return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
353
- }, [activeCampaign, subtotal]);
438
+ }, [activeCampaign, subtotal, effectiveCart]);
354
439
  const giftHandles = useMemo(() => {
355
440
  const giftVariant = autoFreeGiftConfig.map(
356
441
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -366,18 +451,24 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
366
451
  }
367
452
  return true;
368
453
  }, [giftHandles]);
369
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
370
- const res = await getProductsByHandles(client, {
371
- handles: giftHandles,
372
- locale
373
- });
374
- const result = Array.isArray(res) ? res : [];
375
- giftProductsCache.current = {
376
- data: result,
377
- giftHandles: [...giftHandles]
378
- };
379
- return result;
380
- });
454
+ const { data: giftProductsResult } = useSWR(
455
+ shouldFetch ? giftHandles : null,
456
+ async () => {
457
+ const res = await getProductsByHandles(client, {
458
+ handles: giftHandles,
459
+ locale
460
+ });
461
+ const result = Array.isArray(res) ? res : [];
462
+ giftProductsCache.current = {
463
+ data: result,
464
+ giftHandles: [...giftHandles]
465
+ };
466
+ return result;
467
+ },
468
+ {
469
+ revalidateOnFocus: false
470
+ }
471
+ );
381
472
  const finalGiftProductsResult = useMemo(() => {
382
473
  if (giftProductsCache.current && !shouldFetch) {
383
474
  return giftProductsCache.current.data || void 0;
@@ -396,12 +487,19 @@ var useScriptAutoFreeGift = ({
396
487
  campaign,
397
488
  _giveaway,
398
489
  cart,
399
- locale: providedLocale
490
+ locale: providedLocale,
491
+ lines
400
492
  }) => {
401
493
  const { client, locale: contextLocale } = useShopify();
402
494
  const locale = providedLocale || contextLocale;
403
495
  const [points_subscribe, set_points_subscribe] = useState(false);
404
496
  const giftProductsCache = useRef(null);
497
+ const effectiveCart = useMemo(() => {
498
+ if (lines && lines.length > 0) {
499
+ return createMockCartFromLines(lines, cart);
500
+ }
501
+ return cart;
502
+ }, [lines, cart]);
405
503
  useEffect(() => {
406
504
  if (locale === "au") {
407
505
  const isPointsSubscribe = Cookies5.get("points_subscribe");
@@ -423,14 +521,16 @@ var useScriptAutoFreeGift = ({
423
521
  upgrade_multiple2 = 1.2;
424
522
  upgrade_value2 = 40;
425
523
  }
426
- cart?.lineItems?.forEach(({ customAttributes }) => {
427
- customAttributes?.forEach(({ key, value }) => {
428
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
429
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
430
- });
431
- });
524
+ effectiveCart?.lineItems?.forEach(
525
+ ({ customAttributes }) => {
526
+ customAttributes?.forEach(({ key, value }) => {
527
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
528
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
529
+ });
530
+ }
531
+ );
432
532
  return [upgrade_multiple2, upgrade_value2];
433
- }, [cart?.lineItems, points_subscribe]);
533
+ }, [effectiveCart?.lineItems, points_subscribe]);
434
534
  const breakpoints = useMemo(() => {
435
535
  if (!isActivityAvailable) return [];
436
536
  return (campaign?.breakpoints || []).map((item) => ({
@@ -458,7 +558,7 @@ var useScriptAutoFreeGift = ({
458
558
  }, [giftHandles]);
459
559
  const involvedLines = useMemo(() => {
460
560
  if (!isActivityAvailable) return [];
461
- return (cart?.lineItems || []).filter((line) => {
561
+ return (effectiveCart?.lineItems || []).filter((line) => {
462
562
  const isNotGift = line?.totalAmount && Number(line.totalAmount) > 0 && line.customAttributes?.every(
463
563
  (item) => item.key !== _giveaway
464
564
  );
@@ -467,7 +567,7 @@ var useScriptAutoFreeGift = ({
467
567
  );
468
568
  return isNotGift && hasCampaignTag;
469
569
  });
470
- }, [cart?.lineItems, isActivityAvailable, _giveaway]);
570
+ }, [effectiveCart?.lineItems, isActivityAvailable, _giveaway]);
471
571
  const involvedSubTotal = useMemo(() => {
472
572
  if (!isActivityAvailable) return new Decimal2(0);
473
573
  return involvedLines.reduce((prev, item) => {
@@ -493,18 +593,24 @@ var useScriptAutoFreeGift = ({
493
593
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
494
594
  return [currentLevel, nextLevel];
495
595
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
496
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
497
- const res = await getProductsByHandles(client, {
498
- handles: giftHandles,
499
- locale
500
- });
501
- const result = Array.isArray(res) ? res : [];
502
- giftProductsCache.current = {
503
- data: result,
504
- giftHandles: [...giftHandles]
505
- };
506
- return result;
507
- });
596
+ const { data: giftProductsResult } = useSWR(
597
+ shouldFetch ? giftHandles : null,
598
+ async () => {
599
+ const res = await getProductsByHandles(client, {
600
+ handles: giftHandles,
601
+ locale
602
+ });
603
+ const result = Array.isArray(res) ? res : [];
604
+ giftProductsCache.current = {
605
+ data: result,
606
+ giftHandles: [...giftHandles]
607
+ };
608
+ return result;
609
+ },
610
+ {
611
+ revalidateOnFocus: false
612
+ }
613
+ );
508
614
  const finalGiftProductsResult = useMemo(() => {
509
615
  if (giftProductsCache.current && !shouldFetch) {
510
616
  return giftProductsCache.current.data || void 0;
@@ -742,7 +848,7 @@ function useApplyCartCodes(options) {
742
848
  if (!discountCodes?.length) {
743
849
  throw new Error("Invalid input used for this operation: Miss discountCode");
744
850
  }
745
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
851
+ const cartId = providedCartId || cart?.id;
746
852
  if (!cartId) {
747
853
  return void 0;
748
854
  }
@@ -755,6 +861,12 @@ function useApplyCartCodes(options) {
755
861
  cookieAdapter: cartCookieAdapter,
756
862
  metafieldIdentifiers
757
863
  });
864
+ const unApplicableCodes = discountCodes.filter(
865
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
866
+ );
867
+ if (unApplicableCodes.length) {
868
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
869
+ }
758
870
  if (updatedCart) {
759
871
  mutateCart(updatedCart);
760
872
  }
@@ -770,7 +882,7 @@ function useRemoveCartCodes(options) {
770
882
  const removeCodes = useCallback(
771
883
  async (_key, { arg }) => {
772
884
  const { cartId: providedCartId, discountCodes } = arg;
773
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
885
+ const cartId = providedCartId || cart?.id;
774
886
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
775
887
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
776
888
  const updatedCart = await updateCartCodes(client, {
@@ -792,7 +904,7 @@ function useRemoveCartCodes(options) {
792
904
  // src/hooks/cart/use-add-to-cart.ts
793
905
  function useAddToCart({ withTrack = true } = {}, swrOptions) {
794
906
  const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
795
- const { cart } = useCartContext();
907
+ const { cart, addCustomAttributes } = useCartContext();
796
908
  const { trigger: applyCartCodes } = useApplyCartCodes();
797
909
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
798
910
  const { trigger: addCartLines2 } = useAddCartLines();
@@ -806,7 +918,8 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
806
918
  buyerIdentity,
807
919
  needCreateCart = false,
808
920
  onCodesInvalid,
809
- replaceExistingCodes
921
+ replaceExistingCodes,
922
+ customAttributes
810
923
  } = arg;
811
924
  if (!lineItems || lineItems.length === 0) {
812
925
  return;
@@ -829,6 +942,7 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
829
942
  if (!resultCart) {
830
943
  return void 0;
831
944
  }
945
+ console.log("npm addCartLines resultCart", resultCart);
832
946
  if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
833
947
  const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
834
948
  if (unapplicableCodes.length > 0) {
@@ -850,6 +964,9 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
850
964
  discountCodes
851
965
  });
852
966
  }
967
+ if (customAttributes && customAttributes.length > 0) {
968
+ addCustomAttributes(customAttributes);
969
+ }
853
970
  if (withTrack) {
854
971
  trackAddToCartGA({
855
972
  lineItems,
@@ -1002,6 +1119,60 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1002
1119
  );
1003
1120
  return useSWRMutation("buy-now", buyNow, swrOptions);
1004
1121
  }
1122
+ function useCalcGiftsFromLines({
1123
+ lines,
1124
+ customer,
1125
+ scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
1126
+ }) {
1127
+ const { locale } = useShopify();
1128
+ const { cart, autoFreeGiftConfig, gradientGiftsConfig } = useCartContext();
1129
+ const functionGift = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer, lines);
1130
+ const scriptGift = useScriptAutoFreeGift({
1131
+ campaign: gradientGiftsConfig || null,
1132
+ _giveaway: scriptGiveawayKey,
1133
+ cart,
1134
+ locale,
1135
+ lines
1136
+ });
1137
+ const allGiftLines = useMemo(() => {
1138
+ const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || [];
1139
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((product) => {
1140
+ const giftProduct = scriptGift.giftProductsResult?.find(
1141
+ (p) => p.handle === product.handle
1142
+ );
1143
+ const variant = giftProduct?.variants?.[0];
1144
+ return {
1145
+ variant: {
1146
+ id: variant?.id || "",
1147
+ handle: product.handle,
1148
+ sku: product.sku
1149
+ },
1150
+ quantity: 1,
1151
+ attributes: [
1152
+ {
1153
+ key: scriptGiveawayKey,
1154
+ value: "true"
1155
+ }
1156
+ ]
1157
+ };
1158
+ }).filter((item) => item.variant.id) : [];
1159
+ return [...functionGiftLines, ...scriptGiftLines];
1160
+ }, [
1161
+ functionGift.qualifyingGift,
1162
+ scriptGift.freeGiftLevel,
1163
+ scriptGift.giftProductsResult,
1164
+ scriptGiveawayKey
1165
+ ]);
1166
+ const hasGifts = useMemo(() => {
1167
+ return allGiftLines.length > 0;
1168
+ }, [allGiftLines]);
1169
+ return {
1170
+ functionGift,
1171
+ scriptGift,
1172
+ allGiftLines,
1173
+ hasGifts
1174
+ };
1175
+ }
1005
1176
 
1006
1177
  // src/hooks/cart/types/order-discount.ts
1007
1178
  var OrderDiscountType = /* @__PURE__ */ ((OrderDiscountType2) => {
@@ -1052,9 +1223,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1052
1223
  discountAmount: 0
1053
1224
  };
1054
1225
  }
1055
- const tieredDiscounts = activeCampaign.result_detail.order_discount_conf.tiered_discounts;
1056
- const qualifyingTier = [...tieredDiscounts].reverse().find((tier) => subtotal >= Number(tier.amount));
1057
- const nextGoal = tieredDiscounts.find((tier) => subtotal < Number(tier.amount));
1226
+ const currentCurrency = cart?.currency?.code || "";
1227
+ console.log("currentCurrency", cart, currentCurrency);
1228
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1229
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1230
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1231
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1058
1232
  if (!qualifyingTier) {
1059
1233
  return {
1060
1234
  qualifyingDiscount: null,
@@ -1122,12 +1296,10 @@ function useHasPlusMemberInCart({
1122
1296
  };
1123
1297
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1124
1298
  }
1125
-
1126
- // src/hooks/cart/feature/use-cart-attributes.ts
1127
1299
  var getReferralAttributes = () => {
1128
- const inviteCode = Cookies5.get("invite_code");
1129
- const playModeId = Cookies5.get("playModeId");
1130
- const popup = Cookies5.get("_popup");
1300
+ const inviteCode = getLocalStorage("invite_code") || Cookies5.get("invite_code");
1301
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
1302
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
1131
1303
  if (inviteCode && playModeId) {
1132
1304
  return popup ? [
1133
1305
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1151,8 +1323,6 @@ var useCartAttributes = ({
1151
1323
  memberSetting,
1152
1324
  cart
1153
1325
  });
1154
- console.log("memberSetting", memberSetting);
1155
- console.log("hasPlusMember", hasPlusMember);
1156
1326
  useEffect(() => {
1157
1327
  setCurrentUrl(window.location.href);
1158
1328
  }, []);
@@ -1178,7 +1348,7 @@ var useCartAttributes = ({
1178
1348
  return "new_user_login";
1179
1349
  }, [customer]);
1180
1350
  const memberAttributes = useMemo(() => {
1181
- return [
1351
+ const attributes = [
1182
1352
  {
1183
1353
  key: "_token",
1184
1354
  value: profile?.token
@@ -1199,17 +1369,28 @@ var useCartAttributes = ({
1199
1369
  value: profile?.token ? "true" : "false"
1200
1370
  }
1201
1371
  ];
1372
+ if (profile?.token) {
1373
+ attributes.push({
1374
+ key: "_login_user",
1375
+ value: "1"
1376
+ });
1377
+ }
1378
+ return attributes;
1202
1379
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1203
1380
  const functionAttributes = useMemo(() => {
1204
- return [
1205
- cart?.discountCodes && {
1381
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1382
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1383
+ );
1384
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1385
+ return hasFunctionEnvAttribute ? [
1386
+ {
1206
1387
  key: "_discounts_function_env",
1207
1388
  value: JSON.stringify({
1208
- discount_code: cart?.discountCodes.map((item) => item.code),
1389
+ discount_code: discountCodes,
1209
1390
  user_tags: customer?.tags || []
1210
1391
  })
1211
1392
  }
1212
- ];
1393
+ ] : [];
1213
1394
  }, [cart]);
1214
1395
  const presellAttributes = useMemo(() => {
1215
1396
  return [
@@ -1241,18 +1422,50 @@ var useCartAttributes = ({
1241
1422
  }
1242
1423
  ];
1243
1424
  }, [currentUrl]);
1425
+ const commonAttributes = useMemo(
1426
+ () => [
1427
+ ...memberAttributes,
1428
+ ...functionAttributes,
1429
+ ...presellAttributes,
1430
+ ...weightAttributes,
1431
+ ...trackingAttributes,
1432
+ ...getReferralAttributes()
1433
+ ].filter((item) => item?.value),
1434
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1435
+ );
1436
+ const extraAttributesInCart = useMemo(() => {
1437
+ const commonAttributeKeys = [
1438
+ // member attributes
1439
+ "_token",
1440
+ "_member_type",
1441
+ "_user_type",
1442
+ "_is_login",
1443
+ "_login_user",
1444
+ // function attributes
1445
+ "_discounts_function_env",
1446
+ // presell attributes
1447
+ "_presale",
1448
+ // weight attributes
1449
+ "_weight",
1450
+ "_app_source_name",
1451
+ // tracking attributes
1452
+ "utm_params",
1453
+ // referral attributes
1454
+ "_invite_code",
1455
+ "_play_mode_id",
1456
+ "_popup"
1457
+ ];
1458
+ return cart?.customAttributes?.filter(
1459
+ (item) => !commonAttributeKeys.includes(item.key)
1460
+ ) || [];
1461
+ }, [cart]);
1244
1462
  return useMemo(
1245
1463
  () => ({
1246
- attributes: [
1247
- ...memberAttributes,
1248
- ...functionAttributes,
1249
- ...presellAttributes,
1250
- ...weightAttributes,
1251
- ...trackingAttributes,
1252
- ...getReferralAttributes()
1253
- ].filter((item) => item?.value)
1464
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1465
+ (item) => item?.value
1466
+ )
1254
1467
  }),
1255
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1468
+ [commonAttributes, extraAttributesInCart]
1256
1469
  );
1257
1470
  };
1258
1471
  var DEFAULT_MIN = 1;
@@ -1469,8 +1682,9 @@ function useProductsByHandles(options = {}) {
1469
1682
  metafieldIdentifiers
1470
1683
  });
1471
1684
  },
1472
- swrOptions || {
1473
- revalidateOnFocus: false
1685
+ {
1686
+ revalidateOnFocus: false,
1687
+ ...swrOptions
1474
1688
  }
1475
1689
  );
1476
1690
  }
@@ -2386,6 +2600,73 @@ var usePlusMemberDeliveryCodes = ({
2386
2600
  [deliveryData]
2387
2601
  );
2388
2602
  };
2603
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2604
+ const { client, locale, cartCookieAdapter } = useShopify();
2605
+ const updateDeliveryOptions = useCallback(
2606
+ async (_key, { arg }) => {
2607
+ const updatedCart = await updateCartDeliveryOptions(client, {
2608
+ ...arg,
2609
+ metafieldIdentifiers,
2610
+ cookieAdapter: cartCookieAdapter
2611
+ });
2612
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2613
+ if (updatedCart) {
2614
+ mutate(updatedCart);
2615
+ }
2616
+ return updatedCart;
2617
+ },
2618
+ [client, locale, cartCookieAdapter, mutate]
2619
+ );
2620
+ return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2621
+ }
2622
+
2623
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2624
+ var useUpdatePlusMemberDeliveryOptions = ({
2625
+ options
2626
+ } = {}) => {
2627
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2628
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2629
+ mutateCart,
2630
+ metafieldIdentifiers
2631
+ );
2632
+ const handler = useCallback(
2633
+ async (_, { arg }) => {
2634
+ const currentCart = arg?.cart || cartContextData;
2635
+ const { deliveryData } = arg;
2636
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2637
+ const deliveryGroupId = firstDeliveryGroup?.id;
2638
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2639
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2640
+ return null;
2641
+ }
2642
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2643
+ (group) => group?.id === deliveryGroupId
2644
+ );
2645
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2646
+ (option) => option?.code === selectedOptionCode
2647
+ );
2648
+ if (!matchedOption?.handle) {
2649
+ return null;
2650
+ }
2651
+ const deliveryOptions = [
2652
+ {
2653
+ deliveryGroupId,
2654
+ deliveryOptionHandle: matchedOption.handle
2655
+ }
2656
+ ];
2657
+ const updatedCart = await updateCartDeliveryOptions2({
2658
+ selectedDeliveryOptions: deliveryOptions,
2659
+ cartId: currentCart?.id
2660
+ });
2661
+ if (updatedCart && mutateCart) {
2662
+ mutateCart(updatedCart);
2663
+ }
2664
+ return updatedCart;
2665
+ },
2666
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2667
+ );
2668
+ return useSWRMutation("update-cart-delivery-options", handler, options);
2669
+ };
2389
2670
  var usePlusMemberItemCustomAttributes = ({
2390
2671
  deliveryData
2391
2672
  }) => {
@@ -2405,48 +2686,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2405
2686
  deliveryData,
2406
2687
  product,
2407
2688
  variant,
2408
- customer,
2409
2689
  isShowShippingBenefits
2410
2690
  }) => {
2411
2691
  const { deliveryCustomData } = deliveryData || {};
2412
2692
  const { profile } = usePlusMemberContext();
2413
- const userType = useMemo(() => {
2414
- const customerInfo = customer;
2415
- if (!customerInfo) {
2416
- return "new_user_unlogin";
2417
- }
2418
- if (customer) {
2419
- const { orders = {} } = customer;
2420
- const edgesLength = orders?.edges?.length;
2421
- if (edgesLength === 1) {
2422
- return "old_user_orders_once";
2423
- } else if (edgesLength && edgesLength > 1) {
2424
- return "old_user_orders_twice";
2425
- }
2426
- }
2427
- return "new_user_login";
2428
- }, [customer]);
2429
2693
  return useMemo(() => {
2430
2694
  const checkoutCustomAttributes = [
2431
- {
2432
- key: "_token",
2433
- value: profile?.token || ""
2434
- },
2695
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2435
2696
  {
2436
2697
  key: "_last_url",
2437
2698
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2438
- },
2439
- {
2440
- key: "_user_type",
2441
- value: userType
2442
2699
  }
2443
2700
  ];
2444
- if (profile) {
2445
- checkoutCustomAttributes.push({
2446
- key: "_login_user",
2447
- value: "1"
2448
- });
2449
- }
2450
2701
  if (deliveryCustomData) {
2451
2702
  checkoutCustomAttributes.push({
2452
2703
  key: "_checkout_delivery_custom",
@@ -2456,12 +2707,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2456
2707
  })
2457
2708
  });
2458
2709
  }
2459
- if (variant?.metafields?.presell) {
2460
- checkoutCustomAttributes.push({
2461
- key: "_presale",
2462
- value: "true"
2463
- });
2464
- }
2465
2710
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2466
2711
  checkoutCustomAttributes.push({
2467
2712
  key: "_hide_shipping",
@@ -2469,18 +2714,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2469
2714
  });
2470
2715
  }
2471
2716
  return checkoutCustomAttributes;
2472
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2717
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2473
2718
  };
2474
2719
  function useAutoRemovePlusMemberInCart({
2475
- metafields,
2476
- isMonthlyPlus,
2477
- isAnnualPlus
2720
+ cart,
2721
+ profile,
2722
+ memberSetting
2478
2723
  }) {
2479
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2480
- const { cart } = useCartContext();
2724
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2481
2725
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2482
2726
  useEffect(() => {
2483
- if (!cart) return;
2727
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2484
2728
  const removePlusProduct = async (productType) => {
2485
2729
  if (!productType) return;
2486
2730
  const product = cart.lineItems?.find(
@@ -2492,33 +2736,25 @@ function useAutoRemovePlusMemberInCart({
2492
2736
  });
2493
2737
  }
2494
2738
  };
2495
- if (isMonthlyPlus) {
2739
+ if (profile?.isMonthlyPlus) {
2496
2740
  removePlusProduct(plus_monthly_product);
2497
2741
  }
2498
- if (isAnnualPlus) {
2742
+ if (profile?.isAnnualPlus) {
2499
2743
  removePlusProduct(plus_annual_product);
2500
2744
  }
2501
- }, [
2502
- cart,
2503
- plus_annual_product,
2504
- plus_monthly_product,
2505
- isAnnualPlus,
2506
- isMonthlyPlus,
2507
- removeCartLines2
2508
- ]);
2745
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2509
2746
  }
2510
2747
  function useAddPlusMemberProductsToCart({
2511
2748
  cart,
2512
- memberSetting,
2513
- selectedPlusMemberMode,
2514
- selectedPlusMemberProduct
2749
+ profile
2515
2750
  }) {
2751
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2516
2752
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2517
- cart,
2518
- memberSetting
2753
+ memberSetting: plusMemberMetafields,
2754
+ cart
2519
2755
  });
2520
2756
  const plusMemberProduct = useMemo(() => {
2521
- if (selectedPlusMemberMode === "free" /* FREE */) {
2757
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2522
2758
  return void 0;
2523
2759
  }
2524
2760
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2527,7 +2763,10 @@ function useAddPlusMemberProductsToCart({
2527
2763
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2528
2764
  return void 0;
2529
2765
  }
2530
- if (!selectedPlusMemberProduct) {
2766
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2767
+ return void 0;
2768
+ }
2769
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2531
2770
  return void 0;
2532
2771
  }
2533
2772
  return selectedPlusMemberProduct;
@@ -2801,6 +3040,6 @@ function clearGeoLocationCache(cacheKey = "geoLocation") {
2801
3040
  }
2802
3041
  }
2803
3042
 
2804
- 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, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, preCheck, safeParse, useAddCartLines, useAddPlusMemberProductsToCart, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useBlog, useBuyNow, useCalcAutoFreeGift, 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 };
3043
+ 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 };
2805
3044
  //# sourceMappingURL=index.mjs.map
2806
3045
  //# sourceMappingURL=index.mjs.map