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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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';
@@ -45,6 +46,20 @@ var browserCartCookieAdapter = {
45
46
  Cookies5.remove(getCartCookieName(locale));
46
47
  }
47
48
  };
49
+
50
+ // src/adapters/browser-performance.ts
51
+ var BrowserPerformanceAdapter = class {
52
+ /**
53
+ * Start tracking a performance event
54
+ */
55
+ addToCartStart() {
56
+ }
57
+ /**
58
+ * End tracking a performance event
59
+ */
60
+ addToCartEnd() {
61
+ }
62
+ };
48
63
  function ShopifyProvider({
49
64
  config,
50
65
  locale,
@@ -53,7 +68,8 @@ function ShopifyProvider({
53
68
  cartCookieAdapter = browserCartCookieAdapter,
54
69
  routerAdapter,
55
70
  userAdapter,
56
- children
71
+ children,
72
+ performanceAdapter
57
73
  }) {
58
74
  const client = useMemo(() => {
59
75
  return createShopifyClient(config, locale);
@@ -67,7 +83,8 @@ function ShopifyProvider({
67
83
  cookieAdapter,
68
84
  cartCookieAdapter,
69
85
  routerAdapter,
70
- userAdapter
86
+ userAdapter,
87
+ performanceAdapter
71
88
  };
72
89
  }, [
73
90
  client,
@@ -77,6 +94,7 @@ function ShopifyProvider({
77
94
  cookieAdapter,
78
95
  cartCookieAdapter,
79
96
  routerAdapter,
97
+ performanceAdapter,
80
98
  userAdapter
81
99
  ]);
82
100
  return /* @__PURE__ */ jsx(ShopifyContext.Provider, { value, children });
@@ -140,9 +158,10 @@ function normalizeAddToCartLines(lines) {
140
158
  const variant = line.variant;
141
159
  const product = variant.product;
142
160
  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;
161
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
162
+ const finalPrice = variant.finalPrice?.amount === void 0 ? originalPrice : Number(variant.finalPrice?.amount);
163
+ const subtotalAmount = originalPrice * quantity;
164
+ const totalAmount = finalPrice * quantity;
146
165
  return {
147
166
  id: `temp-line-${index}-${variant.id}`,
148
167
  // Temporary ID for pre-cart lines
@@ -156,7 +175,7 @@ function normalizeAddToCartLines(lines) {
156
175
  customAttributes: line.attributes || [],
157
176
  variant: {
158
177
  id: variant.id,
159
- price,
178
+ price: finalPrice,
160
179
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
161
180
  sku: variant.sku || "",
162
181
  name: variant.title || "",
@@ -187,15 +206,16 @@ function createMockCartFromLines(lines, existingCart) {
187
206
  const normalizedLines = normalizeAddToCartLines(lines);
188
207
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
189
208
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
209
+ const currency = lines[0]?.variant?.price?.currencyCode;
190
210
  return {
191
211
  id: existingCart?.id || "temp-cart-id",
192
212
  customerId: existingCart?.customerId,
193
213
  email: existingCart?.email,
194
214
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
195
- currency: existingCart?.currency || { code: "USD" },
215
+ currency: existingCart?.currency || { code: currency },
196
216
  taxesIncluded: existingCart?.taxesIncluded,
197
217
  lineItems: normalizedLines,
198
- totallineItemsDiscount: 0,
218
+ totalLineItemsDiscount: 0,
199
219
  orderDiscounts: 0,
200
220
  lineItemsSubtotalPrice: subtotalPrice,
201
221
  subtotalPrice,
@@ -226,16 +246,6 @@ var getQuery = () => {
226
246
  }
227
247
  return theRequest;
228
248
  };
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
249
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
240
250
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
241
251
  const matchedList = cartData?.lineItems?.filter((line) => {
@@ -467,43 +477,29 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
467
477
  }
468
478
  return { activeCampaign: null, subtotal: 0 };
469
479
  }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
470
- const { qualifyingGift, nextTierGoal } = useMemo(() => {
480
+ const { qualifyingTier, nextTierGoal, actualThreshold, currentCurrency } = useMemo(() => {
471
481
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
472
- return { qualifyingGift: null, nextTierGoal: null };
482
+ return { qualifyingTier: null, nextTierGoal: null, actualThreshold: 0, currentCurrency: "" };
473
483
  }
474
484
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
475
- const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
476
- const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
477
- if (!qualifyingTier) {
478
- return { qualifyingGift: null, nextTierGoal: nextGoal || null };
479
- }
480
- const formattedGift = {
481
- tier: qualifyingTier,
482
- itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
483
- const giftProduct = reward?.variant_list?.[0];
484
- if (!giftProduct) return null;
485
- return {
486
- variant: {
487
- id: btoaID(giftProduct.variant_id),
488
- handle: giftProduct.handle,
489
- sku: giftProduct.sku
490
- },
491
- quantity: reward?.get_unit || 1,
492
- attributes: [
493
- {
494
- key: CUSTOMER_ATTRIBUTE_KEY,
495
- value: JSON.stringify({
496
- is_gift: true,
497
- rule_id: activeCampaign.rule_id,
498
- spend_sum_money: qualifyingTier.spend_sum_money
499
- })
500
- }
501
- ]
502
- };
503
- }).filter((item) => item !== null)
485
+ const currentCurrency2 = effectiveCart?.currency?.code || "";
486
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency2);
487
+ const getThresholdAmount = (tier) => {
488
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency2]?.value) {
489
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency2].value);
490
+ }
491
+ return Number(tier.spend_sum_money || 0);
504
492
  };
505
- return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
506
- }, [activeCampaign, subtotal]);
493
+ const qualifyingTier2 = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
494
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
495
+ const actualThreshold2 = qualifyingTier2 ? getThresholdAmount(qualifyingTier2) : 0;
496
+ return {
497
+ qualifyingTier: qualifyingTier2,
498
+ nextTierGoal: nextGoal || null,
499
+ actualThreshold: actualThreshold2,
500
+ currentCurrency: currentCurrency2
501
+ };
502
+ }, [activeCampaign, subtotal, effectiveCart]);
507
503
  const giftHandles = useMemo(() => {
508
504
  const giftVariant = autoFreeGiftConfig.map(
509
505
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -519,24 +515,82 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
519
515
  }
520
516
  return true;
521
517
  }, [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
- });
518
+ const { data: giftProductsResult } = useSWR(
519
+ shouldFetch ? giftHandles : null,
520
+ async () => {
521
+ const res = await getProductsByHandles(client, {
522
+ handles: giftHandles,
523
+ locale
524
+ });
525
+ const result = Array.isArray(res) ? res : [];
526
+ giftProductsCache.current = {
527
+ data: result,
528
+ giftHandles: [...giftHandles]
529
+ };
530
+ return result;
531
+ },
532
+ {
533
+ revalidateOnFocus: false
534
+ }
535
+ );
534
536
  const finalGiftProductsResult = useMemo(() => {
535
537
  if (giftProductsCache.current && !shouldFetch) {
536
538
  return giftProductsCache.current.data || void 0;
537
539
  }
538
540
  return giftProductsResult;
539
541
  }, [giftProductsResult, shouldFetch]);
542
+ const qualifyingGift = useMemo(() => {
543
+ if (!qualifyingTier || !activeCampaign) {
544
+ return null;
545
+ }
546
+ const itemsToAdd = qualifyingTier.reward_list?.map((reward) => {
547
+ if (!reward.variant_list || reward.variant_list.length === 0) {
548
+ return null;
549
+ }
550
+ let selectedGiftProduct = null;
551
+ for (const giftVariant of reward.variant_list) {
552
+ const productInfo = finalGiftProductsResult?.find(
553
+ (p) => p.handle === giftVariant.handle
554
+ );
555
+ if (productInfo) {
556
+ const variantInfo = productInfo.variants?.find((v) => v.sku === giftVariant.sku);
557
+ if (variantInfo?.availableForSale) {
558
+ selectedGiftProduct = giftVariant;
559
+ break;
560
+ }
561
+ }
562
+ }
563
+ if (!selectedGiftProduct) {
564
+ selectedGiftProduct = reward.variant_list[0];
565
+ }
566
+ return {
567
+ variant: {
568
+ id: btoaID(selectedGiftProduct.variant_id),
569
+ handle: selectedGiftProduct.handle,
570
+ sku: selectedGiftProduct.sku
571
+ },
572
+ quantity: reward?.get_unit || 1,
573
+ attributes: [
574
+ {
575
+ key: CUSTOMER_ATTRIBUTE_KEY,
576
+ value: JSON.stringify({
577
+ is_gift: true,
578
+ rule_id: activeCampaign.rule_id,
579
+ spend_sum_money: actualThreshold,
580
+ // 使用实际的门槛金额(多币种支持)
581
+ currency_code: currentCurrency
582
+ // 记录当前币种
583
+ })
584
+ }
585
+ ]
586
+ };
587
+ }).filter((item) => item !== null);
588
+ const formattedGift = {
589
+ tier: qualifyingTier,
590
+ itemsToAdd
591
+ };
592
+ return formattedGift;
593
+ }, [qualifyingTier, activeCampaign, finalGiftProductsResult, actualThreshold, currentCurrency]);
540
594
  return {
541
595
  qualifyingGift,
542
596
  nextTierGoal,
@@ -583,12 +637,14 @@ var useScriptAutoFreeGift = ({
583
637
  upgrade_multiple2 = 1.2;
584
638
  upgrade_value2 = 40;
585
639
  }
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
- });
640
+ effectiveCart?.lineItems?.forEach(
641
+ ({ customAttributes }) => {
642
+ customAttributes?.forEach(({ key, value }) => {
643
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
644
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
645
+ });
646
+ }
647
+ );
592
648
  return [upgrade_multiple2, upgrade_value2];
593
649
  }, [effectiveCart?.lineItems, points_subscribe]);
594
650
  const breakpoints = useMemo(() => {
@@ -653,18 +709,24 @@ var useScriptAutoFreeGift = ({
653
709
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
654
710
  return [currentLevel, nextLevel];
655
711
  }, [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
- });
712
+ const { data: giftProductsResult } = useSWR(
713
+ shouldFetch ? giftHandles : null,
714
+ async () => {
715
+ const res = await getProductsByHandles(client, {
716
+ handles: giftHandles,
717
+ locale
718
+ });
719
+ const result = Array.isArray(res) ? res : [];
720
+ giftProductsCache.current = {
721
+ data: result,
722
+ giftHandles: [...giftHandles]
723
+ };
724
+ return result;
725
+ },
726
+ {
727
+ revalidateOnFocus: false
728
+ }
729
+ );
668
730
  const finalGiftProductsResult = useMemo(() => {
669
731
  if (giftProductsCache.current && !shouldFetch) {
670
732
  return giftProductsCache.current.data || void 0;
@@ -731,11 +793,23 @@ function useAddCartLines(options) {
731
793
  const { mutateCart, metafieldIdentifiers } = useCartContext();
732
794
  const addLines = useCallback(
733
795
  async (_key, { arg }) => {
734
- let updatedCart = await addCartLines(client, {
735
- ...arg,
736
- metafieldIdentifiers,
737
- cookieAdapter: cartCookieAdapter
738
- });
796
+ const { cartId, lines } = arg;
797
+ const id = cartId || cartCookieAdapter?.getCartId(locale);
798
+ let updatedCart;
799
+ if (!id) {
800
+ updatedCart = await createCart(client, {
801
+ lines,
802
+ metafieldIdentifiers,
803
+ cookieAdapter: cartCookieAdapter
804
+ });
805
+ } else {
806
+ updatedCart = await addCartLines(client, {
807
+ cartId: id,
808
+ lines,
809
+ metafieldIdentifiers,
810
+ cookieAdapter: cartCookieAdapter
811
+ });
812
+ }
739
813
  if (updatedCart) {
740
814
  const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
741
815
  if (unApplicableCodes.length > 0) {
@@ -782,7 +856,7 @@ var trackAddToCartGA = ({
782
856
  const currencyCode = variant.product?.price?.currencyCode;
783
857
  const totalPrice = lineItems?.reduce(
784
858
  (prev, { variant: variant2 }) => prev.plus(
785
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
859
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
786
860
  ),
787
861
  new Decimal2(0)
788
862
  ).toNumber();
@@ -817,7 +891,7 @@ var trackBeginCheckoutGA = ({
817
891
  }
818
892
  const totalPrice = lineItems?.reduce(
819
893
  (prev, { variant }) => prev.plus(
820
- variant?.finalPrice?.amount ?? variant?.compareAtPrice?.amount ?? variant?.price?.amount ?? 0
894
+ variant?.finalPrice?.amount === void 0 ? Number(variant?.price?.amount) || 0 : Number(variant?.finalPrice?.amount) || 0
821
895
  ),
822
896
  new Decimal2(0)
823
897
  ).toNumber();
@@ -850,10 +924,10 @@ var trackBuyNowGA = ({
850
924
  return;
851
925
  }
852
926
  const { variant } = lineItems[0];
853
- const currencyCode = variant.price?.currencyCode;
927
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
854
928
  const totalPrice = lineItems?.reduce(
855
929
  (prev, { variant: variant2 }) => prev.plus(
856
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
930
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
857
931
  ),
858
932
  new Decimal2(0)
859
933
  ).toNumber();
@@ -927,7 +1001,7 @@ function useApplyCartCodes(options) {
927
1001
  if (!discountCodes?.length) {
928
1002
  throw new Error("Invalid input used for this operation: Miss discountCode");
929
1003
  }
930
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1004
+ const cartId = providedCartId || cart?.id;
931
1005
  if (!cartId) {
932
1006
  return void 0;
933
1007
  }
@@ -940,12 +1014,18 @@ function useApplyCartCodes(options) {
940
1014
  cookieAdapter: cartCookieAdapter,
941
1015
  metafieldIdentifiers
942
1016
  });
1017
+ const unApplicableCodes = discountCodes.filter(
1018
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
1019
+ );
1020
+ if (unApplicableCodes.length) {
1021
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
1022
+ }
943
1023
  if (updatedCart) {
944
1024
  mutateCart(updatedCart);
945
1025
  }
946
1026
  return updatedCart;
947
1027
  },
948
- [client, locale, cartCookieAdapter, mutateCart, cart]
1028
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
949
1029
  );
950
1030
  return useSWRMutation("apply-codes", applyCodes, options);
951
1031
  }
@@ -955,7 +1035,7 @@ function useRemoveCartCodes(options) {
955
1035
  const removeCodes = useCallback(
956
1036
  async (_key, { arg }) => {
957
1037
  const { cartId: providedCartId, discountCodes } = arg;
958
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1038
+ const cartId = providedCartId || cart?.id;
959
1039
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
960
1040
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
961
1041
  const updatedCart = await updateCartCodes(client, {
@@ -969,18 +1049,74 @@ function useRemoveCartCodes(options) {
969
1049
  }
970
1050
  return updatedCart;
971
1051
  },
972
- [client, locale, cartCookieAdapter, mutateCart, cart]
1052
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
973
1053
  );
974
1054
  return useSWRMutation("remove-codes", removeCodes, options);
975
1055
  }
976
1056
 
1057
+ // src/hooks/cart/utils/add-to-cart.ts
1058
+ var getLinesWithAttributes = ({
1059
+ cart,
1060
+ lineItems
1061
+ }) => {
1062
+ return lineItems.map((line) => {
1063
+ const sameLineInCart = cart?.lineItems.find(
1064
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
1065
+ );
1066
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
1067
+ (attr) => attr.key === CODE_AMOUNT_KEY
1068
+ );
1069
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
1070
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
1071
+ );
1072
+ let functionAttribute = null;
1073
+ try {
1074
+ functionAttribute = sameLineInCart?.customAttributes?.find(
1075
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
1076
+ );
1077
+ } catch (error) {
1078
+ }
1079
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
1080
+ return {
1081
+ ...line,
1082
+ attributes: [
1083
+ ...line.attributes || [],
1084
+ codeAmountAttribute,
1085
+ functionAttribute,
1086
+ scriptCodeAmountAttribute
1087
+ ].filter(Boolean)
1088
+ };
1089
+ }
1090
+ return line;
1091
+ });
1092
+ };
1093
+ var getLinesWithFunctionAttributes = (lineItems) => {
1094
+ return lineItems.map((line) => {
1095
+ let itemAttributes = line.attributes || [];
1096
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
1097
+ if (!functionEnvAttribute) {
1098
+ itemAttributes = itemAttributes.concat([
1099
+ {
1100
+ key: CUSTOMER_ATTRIBUTE_KEY,
1101
+ value: JSON.stringify({
1102
+ is_gift: false,
1103
+ discounted_amount: line.variant?.finalPrice?.amount === void 0 ? Number(line.variant?.price?.amount) * (line.quantity || 1) : Number(line.variant?.finalPrice?.amount) * (line.quantity || 1)
1104
+ })
1105
+ }
1106
+ ]);
1107
+ }
1108
+ return { ...line, attributes: itemAttributes };
1109
+ });
1110
+ };
1111
+
977
1112
  // src/hooks/cart/use-add-to-cart.ts
978
1113
  function useAddToCart({ withTrack = true } = {}, swrOptions) {
979
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
980
- const { cart } = useCartContext();
1114
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
1115
+ const { cart, addCustomAttributes } = useCartContext();
981
1116
  const { trigger: applyCartCodes } = useApplyCartCodes();
982
1117
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
983
1118
  const { trigger: addCartLines2 } = useAddCartLines();
1119
+ const { trigger: createCart4 } = useCreateCart();
984
1120
  const addToCart = useCallback(
985
1121
  async (_key, { arg }) => {
986
1122
  const {
@@ -991,12 +1127,19 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
991
1127
  buyerIdentity,
992
1128
  needCreateCart = false,
993
1129
  onCodesInvalid,
994
- replaceExistingCodes
1130
+ replaceExistingCodes,
1131
+ customAttributes
995
1132
  } = arg;
996
1133
  if (!lineItems || lineItems.length === 0) {
997
1134
  return;
998
1135
  }
999
- const lines = lineItems.map((item) => ({
1136
+ performanceAdapter?.addToCartStart();
1137
+ const linesWithAttributes = getLinesWithAttributes({
1138
+ cart,
1139
+ lineItems
1140
+ });
1141
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(linesWithAttributes);
1142
+ const lines = linesWithFunctionAttributes.map((item) => ({
1000
1143
  merchandiseId: item.variant?.id || "",
1001
1144
  quantity: item.quantity || 1,
1002
1145
  attributes: item.attributes,
@@ -1005,36 +1148,45 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
1005
1148
  if (lines.length === 0) {
1006
1149
  return;
1007
1150
  }
1008
- const cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
1009
- let resultCart = await addCartLines2({
1010
- cartId,
1011
- lines,
1012
- buyerIdentity
1013
- });
1014
- if (!resultCart) {
1015
- return void 0;
1016
- }
1017
- console.log("npm addCartLines resultCart", resultCart);
1018
- if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
1019
- const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1020
- if (unapplicableCodes.length > 0) {
1021
- if (onCodesInvalid) {
1022
- const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
1023
- if (handledCart) {
1024
- resultCart = handledCart;
1151
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
1152
+ let resultCart = null;
1153
+ if (!cartId) {
1154
+ resultCart = await createCart4({
1155
+ lines,
1156
+ buyerIdentity,
1157
+ discountCodes,
1158
+ customAttributes
1159
+ });
1160
+ } else {
1161
+ resultCart = await addCartLines2({
1162
+ cartId,
1163
+ lines
1164
+ });
1165
+ console.log("npm addCartLines resultCart", resultCart);
1166
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
1167
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1168
+ if (unapplicableCodes.length > 0) {
1169
+ if (onCodesInvalid) {
1170
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
1171
+ if (handledCart) {
1172
+ resultCart = handledCart;
1173
+ }
1174
+ } else {
1175
+ await removeInvalidCodes({
1176
+ discountCodes: unapplicableCodes
1177
+ });
1025
1178
  }
1026
- } else {
1027
- await removeInvalidCodes({
1028
- discountCodes: unapplicableCodes
1029
- });
1030
1179
  }
1031
1180
  }
1032
- }
1033
- if (discountCodes && discountCodes.length > 0) {
1034
- applyCartCodes({
1035
- replaceExistingCodes,
1036
- discountCodes
1037
- });
1181
+ if (resultCart && discountCodes && discountCodes.length > 0) {
1182
+ applyCartCodes({
1183
+ replaceExistingCodes,
1184
+ discountCodes
1185
+ });
1186
+ }
1187
+ if (customAttributes && customAttributes.length > 0) {
1188
+ addCustomAttributes(customAttributes);
1189
+ }
1038
1190
  }
1039
1191
  if (withTrack) {
1040
1192
  trackAddToCartGA({
@@ -1043,9 +1195,24 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
1043
1195
  });
1044
1196
  trackAddToCartFBQ({ lineItems });
1045
1197
  }
1198
+ performanceAdapter?.addToCartEnd();
1046
1199
  return resultCart;
1047
1200
  },
1048
- [client, locale, cartCookieAdapter, userAdapter, cart, withTrack]
1201
+ [
1202
+ client,
1203
+ locale,
1204
+ cartCookieAdapter,
1205
+ userAdapter,
1206
+ cart,
1207
+ withTrack,
1208
+ performanceAdapter,
1209
+ createCart4,
1210
+ addCartLines2,
1211
+ applyCartCodes,
1212
+ removeInvalidCodes,
1213
+ addCustomAttributes,
1214
+ config
1215
+ ]
1049
1216
  );
1050
1217
  return useSWRMutation("add-to-cart", addToCart, swrOptions);
1051
1218
  }
@@ -1062,9 +1229,10 @@ function useUpdateCartLines(options) {
1062
1229
  if (updatedCart) {
1063
1230
  mutateCart(updatedCart);
1064
1231
  }
1232
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
1065
1233
  return updatedCart;
1066
1234
  },
1067
- [client, locale, cartCookieAdapter, mutateCart]
1235
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1068
1236
  );
1069
1237
  return useSWRMutation("update-cart-lines", updateLines, options);
1070
1238
  }
@@ -1103,7 +1271,7 @@ function useRemoveCartLines(options) {
1103
1271
  }
1104
1272
  return updatedCart;
1105
1273
  },
1106
- [client, locale, cartCookieAdapter, mutateCart]
1274
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1107
1275
  );
1108
1276
  return useSWRMutation("remove-cart-lines", removeLines, options);
1109
1277
  }
@@ -1122,7 +1290,7 @@ function useUpdateCartAttributes(mutate, metafieldIdentifiers, options) {
1122
1290
  }
1123
1291
  return updatedCart;
1124
1292
  },
1125
- [client, locale, cartCookieAdapter, mutate]
1293
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers]
1126
1294
  );
1127
1295
  return useSWRMutation("update-cart-attributes", updateAttributes, options);
1128
1296
  }
@@ -1144,7 +1312,8 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1144
1312
  if (!lineItems || lineItems.length === 0) {
1145
1313
  return;
1146
1314
  }
1147
- const lines = lineItems.map((item) => ({
1315
+ const linesWithFunctionAttributes = getLinesWithFunctionAttributes(lineItems);
1316
+ const lines = linesWithFunctionAttributes.map((item) => ({
1148
1317
  merchandiseId: item.variant?.id || "",
1149
1318
  quantity: item.quantity || 1,
1150
1319
  attributes: item.attributes,
@@ -1262,7 +1431,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1262
1431
  const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
1263
1432
  const dealsType = "";
1264
1433
  const { activeCampaign, subtotal } = useMemo(() => {
1265
- for (const campaign of orderDiscountConfig) {
1434
+ for (const campaign of orderDiscountConfig || []) {
1266
1435
  const { rule_conditions = [], result_detail } = campaign;
1267
1436
  const { main_product, order_discount_conf } = result_detail || {};
1268
1437
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
@@ -1292,9 +1461,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1292
1461
  discountAmount: 0
1293
1462
  };
1294
1463
  }
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));
1464
+ const currentCurrency = cart?.currency?.code || "";
1465
+ console.log("currentCurrency", cart, currentCurrency);
1466
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1467
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1468
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1469
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1298
1470
  if (!qualifyingTier) {
1299
1471
  return {
1300
1472
  qualifyingDiscount: null,
@@ -1362,12 +1534,10 @@ function useHasPlusMemberInCart({
1362
1534
  };
1363
1535
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1364
1536
  }
1365
-
1366
- // src/hooks/cart/feature/use-cart-attributes.ts
1367
1537
  var getReferralAttributes = () => {
1368
- const inviteCode = Cookies5.get("invite_code");
1369
- const playModeId = Cookies5.get("playModeId");
1370
- const popup = Cookies5.get("_popup");
1538
+ const inviteCode = getLocalStorage("inviteCode") || Cookies5.get("inviteCode");
1539
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
1540
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
1371
1541
  if (inviteCode && playModeId) {
1372
1542
  return popup ? [
1373
1543
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1391,8 +1561,6 @@ var useCartAttributes = ({
1391
1561
  memberSetting,
1392
1562
  cart
1393
1563
  });
1394
- console.log("memberSetting", memberSetting);
1395
- console.log("hasPlusMember", hasPlusMember);
1396
1564
  useEffect(() => {
1397
1565
  setCurrentUrl(window.location.href);
1398
1566
  }, []);
@@ -1418,7 +1586,7 @@ var useCartAttributes = ({
1418
1586
  return "new_user_login";
1419
1587
  }, [customer]);
1420
1588
  const memberAttributes = useMemo(() => {
1421
- return [
1589
+ const attributes = [
1422
1590
  {
1423
1591
  key: "_token",
1424
1592
  value: profile?.token
@@ -1439,17 +1607,28 @@ var useCartAttributes = ({
1439
1607
  value: profile?.token ? "true" : "false"
1440
1608
  }
1441
1609
  ];
1610
+ if (profile?.token) {
1611
+ attributes.push({
1612
+ key: "_login_user",
1613
+ value: "1"
1614
+ });
1615
+ }
1616
+ return attributes;
1442
1617
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1443
1618
  const functionAttributes = useMemo(() => {
1444
- return [
1445
- cart?.discountCodes && {
1619
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1620
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1621
+ );
1622
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1623
+ return hasFunctionEnvAttribute ? [
1624
+ {
1446
1625
  key: "_discounts_function_env",
1447
1626
  value: JSON.stringify({
1448
- discount_code: cart?.discountCodes.map((item) => item.code),
1627
+ discount_code: discountCodes,
1449
1628
  user_tags: customer?.tags || []
1450
1629
  })
1451
1630
  }
1452
- ];
1631
+ ] : [];
1453
1632
  }, [cart]);
1454
1633
  const presellAttributes = useMemo(() => {
1455
1634
  return [
@@ -1481,18 +1660,50 @@ var useCartAttributes = ({
1481
1660
  }
1482
1661
  ];
1483
1662
  }, [currentUrl]);
1663
+ const commonAttributes = useMemo(
1664
+ () => [
1665
+ ...memberAttributes,
1666
+ ...functionAttributes,
1667
+ ...presellAttributes,
1668
+ ...weightAttributes,
1669
+ ...trackingAttributes,
1670
+ ...getReferralAttributes()
1671
+ ].filter((item) => item?.value),
1672
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1673
+ );
1674
+ const extraAttributesInCart = useMemo(() => {
1675
+ const commonAttributeKeys = [
1676
+ // member attributes
1677
+ "_token",
1678
+ "_member_type",
1679
+ "_user_type",
1680
+ "_is_login",
1681
+ "_login_user",
1682
+ // function attributes
1683
+ "_discounts_function_env",
1684
+ // presell attributes
1685
+ "_presale",
1686
+ // weight attributes
1687
+ "_weight",
1688
+ "_app_source_name",
1689
+ // tracking attributes
1690
+ "utm_params",
1691
+ // referral attributes
1692
+ "_invite_code",
1693
+ "_play_mode_id",
1694
+ "_popup"
1695
+ ];
1696
+ return cart?.customAttributes?.filter(
1697
+ (item) => !commonAttributeKeys.includes(item.key)
1698
+ ) || [];
1699
+ }, [cart]);
1484
1700
  return useMemo(
1485
1701
  () => ({
1486
- attributes: [
1487
- ...memberAttributes,
1488
- ...functionAttributes,
1489
- ...presellAttributes,
1490
- ...weightAttributes,
1491
- ...trackingAttributes,
1492
- ...getReferralAttributes()
1493
- ].filter((item) => item?.value)
1702
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1703
+ (item) => item?.value
1704
+ )
1494
1705
  }),
1495
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1706
+ [commonAttributes, extraAttributesInCart]
1496
1707
  );
1497
1708
  };
1498
1709
  var DEFAULT_MIN = 1;
@@ -1555,7 +1766,7 @@ var useUpdateLineCodeAmountAttributes = ({
1555
1766
  );
1556
1767
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1557
1768
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1558
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1769
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1559
1770
  attrNeedUpdate.push({
1560
1771
  key: CUSTOMER_ATTRIBUTE_KEY,
1561
1772
  value: JSON.stringify({
@@ -1594,29 +1805,22 @@ var useUpdateLineCodeAmountAttributes = ({
1594
1805
  }).filter(
1595
1806
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1596
1807
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1808
+ let lineId = line.id;
1809
+ let attributes = line.customAttributes || [];
1810
+ if (attrNeedDelete.length) {
1811
+ attributes = attributes.filter(
1812
+ (attr) => !attrNeedDelete.includes(attr.key)
1813
+ );
1814
+ }
1597
1815
  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
- };
1816
+ attributes = attributes.filter(
1817
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1818
+ ).concat(attrNeedUpdate);
1619
1819
  }
1820
+ return {
1821
+ id: lineId,
1822
+ attributes
1823
+ };
1620
1824
  }),
1621
1825
  [cart?.lineItems, mainProductDiscountCodes]
1622
1826
  );
@@ -1709,8 +1913,9 @@ function useProductsByHandles(options = {}) {
1709
1913
  metafieldIdentifiers
1710
1914
  });
1711
1915
  },
1712
- swrOptions || {
1713
- revalidateOnFocus: false
1916
+ {
1917
+ revalidateOnFocus: false,
1918
+ ...swrOptions
1714
1919
  }
1715
1920
  );
1716
1921
  }
@@ -2339,7 +2544,10 @@ var createInitialValue = () => ({
2339
2544
  freeShippingMethods: [],
2340
2545
  paymentShippingMethods: [],
2341
2546
  nddOverweight: false,
2342
- tddOverweight: false
2547
+ tddOverweight: false,
2548
+ nddCoupon: void 0,
2549
+ tddCoupon: void 0,
2550
+ isLoadingCoupon: false
2343
2551
  },
2344
2552
  selectedPlusMemberProduct: null,
2345
2553
  plusMemberProducts: [],
@@ -2384,15 +2592,29 @@ function usePlusAnnualProductVariant() {
2384
2592
  }, [plusMemberProducts, plusAnnual]);
2385
2593
  return plusAnnualProductVariant;
2386
2594
  }
2387
- function useShippingMethods(options) {
2388
- const {
2389
- variant,
2390
- plusMemberMetafields,
2391
- selectedPlusMemberMode,
2392
- isPlus = false,
2595
+ var useAvailableDeliveryCoupon = ({
2596
+ profile
2597
+ }) => {
2598
+ const { data: availableDeliveryCoupon, isLoading } = useSWR(
2599
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
2600
+ async ([apiPath]) => {
2601
+ return fetch(apiPath).then((res) => res.json());
2602
+ }
2603
+ );
2604
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
2605
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
2606
+ return {
2393
2607
  nddCoupon,
2394
- tddCoupon
2395
- } = options;
2608
+ tddCoupon,
2609
+ isLoading
2610
+ };
2611
+ };
2612
+
2613
+ // src/hooks/member/plus/use-shipping-methods.ts
2614
+ function useShippingMethods(options) {
2615
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, isPlus = false, profile } = options;
2616
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
2617
+ console.log("nddCoupon", nddCoupon);
2396
2618
  const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2397
2619
  const nddOverweight = useMemo(() => {
2398
2620
  return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
@@ -2402,12 +2624,10 @@ function useShippingMethods(options) {
2402
2624
  }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2403
2625
  const paymentShippingMethods = useMemo(() => {
2404
2626
  const weight = variant?.weight || 0;
2405
- const methods = plus_shipping?.shipping_methods?.filter(
2406
- ({ weight_low, weight_high, __mode, __plus }) => {
2407
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2408
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2409
- }
2410
- ) || [];
2627
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
2628
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2629
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2630
+ }) || [];
2411
2631
  return methods.map((method) => {
2412
2632
  let disabled = false;
2413
2633
  const selectedFreeMember = selectedPlusMemberMode === "free";
@@ -2434,40 +2654,34 @@ function useShippingMethods(options) {
2434
2654
  ]);
2435
2655
  const nddPrice = useMemo(() => {
2436
2656
  const weight = variant?.weight || 0;
2437
- const nddMethod = paymentShippingMethods.find(
2438
- ({ __mode, weight_high, weight_low }) => {
2439
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2440
- return __mode === "ndd" && fitWeight;
2441
- }
2442
- );
2657
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2658
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2659
+ return __mode === "ndd" && fitWeight;
2660
+ });
2443
2661
  return nddMethod?.price || 0;
2444
2662
  }, [variant?.weight, paymentShippingMethods]);
2445
2663
  const tddPrice = useMemo(() => {
2446
2664
  const weight = variant?.weight || 0;
2447
- const tddMethod = paymentShippingMethods.find(
2448
- ({ __mode, weight_high, weight_low }) => {
2449
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2450
- return __mode === "tdd" && fitWeight;
2451
- }
2452
- );
2665
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2666
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2667
+ return __mode === "tdd" && fitWeight;
2668
+ });
2453
2669
  return tddMethod?.price || 0;
2454
2670
  }, [variant?.weight, paymentShippingMethods]);
2455
2671
  const freeShippingMethods = useMemo(() => {
2456
2672
  const weight = variant?.weight || 0;
2457
- let methods = plus_shipping?.shipping_methods?.filter(
2458
- ({ __mode, __plus, weight_low, weight_high }) => {
2459
- if (__mode === "free" /* FREE */) {
2460
- return true;
2461
- }
2462
- if (isPlus) {
2463
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2464
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2465
- return hasCoupon && fitWeight && !__plus;
2466
- } else {
2467
- return __plus;
2468
- }
2673
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
2674
+ if (__mode === "free" /* FREE */) {
2675
+ return true;
2469
2676
  }
2470
- ) || [];
2677
+ if (isPlus) {
2678
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2679
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2680
+ return hasCoupon && fitWeight && !__plus;
2681
+ } else {
2682
+ return __plus;
2683
+ }
2684
+ }) || [];
2471
2685
  if (isPlus) {
2472
2686
  methods = methods.sort((a, b) => {
2473
2687
  if (b.__mode === "free" /* FREE */) return -1;
@@ -2521,7 +2735,10 @@ function useShippingMethods(options) {
2521
2735
  freeShippingMethods,
2522
2736
  paymentShippingMethods,
2523
2737
  nddOverweight,
2524
- tddOverweight
2738
+ tddOverweight,
2739
+ nddCoupon,
2740
+ tddCoupon,
2741
+ isLoadingCoupon: isLoading
2525
2742
  };
2526
2743
  }
2527
2744
  function useShippingMethodAvailableCheck() {
@@ -2626,6 +2843,73 @@ var usePlusMemberDeliveryCodes = ({
2626
2843
  [deliveryData]
2627
2844
  );
2628
2845
  };
2846
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2847
+ const { client, locale, cartCookieAdapter } = useShopify();
2848
+ const updateDeliveryOptions = useCallback(
2849
+ async (_key, { arg }) => {
2850
+ const updatedCart = await updateCartDeliveryOptions(client, {
2851
+ ...arg,
2852
+ metafieldIdentifiers,
2853
+ cookieAdapter: cartCookieAdapter
2854
+ });
2855
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2856
+ if (updatedCart) {
2857
+ mutate(updatedCart);
2858
+ }
2859
+ return updatedCart;
2860
+ },
2861
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers]
2862
+ );
2863
+ return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2864
+ }
2865
+
2866
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2867
+ var useUpdatePlusMemberDeliveryOptions = ({
2868
+ options
2869
+ } = {}) => {
2870
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2871
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2872
+ mutateCart,
2873
+ metafieldIdentifiers
2874
+ );
2875
+ const handler = useCallback(
2876
+ async (_, { arg }) => {
2877
+ const currentCart = arg?.cart || cartContextData;
2878
+ const { deliveryData } = arg;
2879
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2880
+ const deliveryGroupId = firstDeliveryGroup?.id;
2881
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2882
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2883
+ return null;
2884
+ }
2885
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2886
+ (group) => group?.id === deliveryGroupId
2887
+ );
2888
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2889
+ (option) => option?.code === selectedOptionCode
2890
+ );
2891
+ if (!matchedOption?.handle) {
2892
+ return null;
2893
+ }
2894
+ const deliveryOptions = [
2895
+ {
2896
+ deliveryGroupId,
2897
+ deliveryOptionHandle: matchedOption.handle
2898
+ }
2899
+ ];
2900
+ const updatedCart = await updateCartDeliveryOptions2({
2901
+ selectedDeliveryOptions: deliveryOptions,
2902
+ cartId: currentCart?.id
2903
+ });
2904
+ if (updatedCart && mutateCart) {
2905
+ mutateCart(updatedCart);
2906
+ }
2907
+ return updatedCart;
2908
+ },
2909
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2910
+ );
2911
+ return useSWRMutation("update-cart-delivery-options", handler, options);
2912
+ };
2629
2913
  var usePlusMemberItemCustomAttributes = ({
2630
2914
  deliveryData
2631
2915
  }) => {
@@ -2645,48 +2929,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2645
2929
  deliveryData,
2646
2930
  product,
2647
2931
  variant,
2648
- customer,
2649
2932
  isShowShippingBenefits
2650
2933
  }) => {
2651
2934
  const { deliveryCustomData } = deliveryData || {};
2652
2935
  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
2936
  return useMemo(() => {
2670
2937
  const checkoutCustomAttributes = [
2671
- {
2672
- key: "_token",
2673
- value: profile?.token || ""
2674
- },
2938
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2675
2939
  {
2676
2940
  key: "_last_url",
2677
2941
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2678
- },
2679
- {
2680
- key: "_user_type",
2681
- value: userType
2682
2942
  }
2683
2943
  ];
2684
- if (profile) {
2685
- checkoutCustomAttributes.push({
2686
- key: "_login_user",
2687
- value: "1"
2688
- });
2689
- }
2690
2944
  if (deliveryCustomData) {
2691
2945
  checkoutCustomAttributes.push({
2692
2946
  key: "_checkout_delivery_custom",
@@ -2696,12 +2950,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2696
2950
  })
2697
2951
  });
2698
2952
  }
2699
- if (variant?.metafields?.presell) {
2700
- checkoutCustomAttributes.push({
2701
- key: "_presale",
2702
- value: "true"
2703
- });
2704
- }
2705
2953
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2706
2954
  checkoutCustomAttributes.push({
2707
2955
  key: "_hide_shipping",
@@ -2709,18 +2957,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2709
2957
  });
2710
2958
  }
2711
2959
  return checkoutCustomAttributes;
2712
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2960
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2713
2961
  };
2714
2962
  function useAutoRemovePlusMemberInCart({
2715
- metafields,
2716
- isMonthlyPlus,
2717
- isAnnualPlus
2963
+ cart,
2964
+ profile,
2965
+ memberSetting
2718
2966
  }) {
2719
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2720
- const { cart } = useCartContext();
2967
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2721
2968
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2722
2969
  useEffect(() => {
2723
- if (!cart) return;
2970
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2724
2971
  const removePlusProduct = async (productType) => {
2725
2972
  if (!productType) return;
2726
2973
  const product = cart.lineItems?.find(
@@ -2732,33 +2979,25 @@ function useAutoRemovePlusMemberInCart({
2732
2979
  });
2733
2980
  }
2734
2981
  };
2735
- if (isMonthlyPlus) {
2982
+ if (profile?.isMonthlyPlus) {
2736
2983
  removePlusProduct(plus_monthly_product);
2737
2984
  }
2738
- if (isAnnualPlus) {
2985
+ if (profile?.isAnnualPlus) {
2739
2986
  removePlusProduct(plus_annual_product);
2740
2987
  }
2741
- }, [
2742
- cart,
2743
- plus_annual_product,
2744
- plus_monthly_product,
2745
- isAnnualPlus,
2746
- isMonthlyPlus,
2747
- removeCartLines2
2748
- ]);
2988
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2749
2989
  }
2750
- function useAddPlusMemberProductsToCart({
2990
+ function usePlusMemberNeedAddToCart({
2751
2991
  cart,
2752
- memberSetting,
2753
- selectedPlusMemberMode,
2754
- selectedPlusMemberProduct
2992
+ profile
2755
2993
  }) {
2994
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2756
2995
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2757
- cart,
2758
- memberSetting
2996
+ memberSetting: plusMemberMetafields,
2997
+ cart
2759
2998
  });
2760
2999
  const plusMemberProduct = useMemo(() => {
2761
- if (selectedPlusMemberMode === "free" /* FREE */) {
3000
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2762
3001
  return void 0;
2763
3002
  }
2764
3003
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2767,7 +3006,10 @@ function useAddPlusMemberProductsToCart({
2767
3006
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2768
3007
  return void 0;
2769
3008
  }
2770
- if (!selectedPlusMemberProduct) {
3009
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
3010
+ return void 0;
3011
+ }
3012
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2771
3013
  return void 0;
2772
3014
  }
2773
3015
  return selectedPlusMemberProduct;
@@ -2786,9 +3028,9 @@ var PlusMemberProvider = ({
2786
3028
  memberSetting,
2787
3029
  initialSelectedPlusMemberMode = "free",
2788
3030
  profile,
2789
- locale,
2790
3031
  children
2791
3032
  }) => {
3033
+ const { locale } = useShopify();
2792
3034
  const [zipCode, setZipCode] = useState("");
2793
3035
  const [showTip, setShowTip] = useState(false);
2794
3036
  const [selectedPlusMemberMode, setSelectedPlusMemberMode] = useState(
@@ -2804,7 +3046,11 @@ var PlusMemberProvider = ({
2804
3046
  const shippingMethodsContext = useShippingMethods({
2805
3047
  variant,
2806
3048
  plusMemberMetafields: memberSetting,
2807
- selectedPlusMemberMode});
3049
+ selectedPlusMemberMode,
3050
+ profile,
3051
+ isPlus: profile?.isPlus || false
3052
+ });
3053
+ console.log("shippingMethodsContext", shippingMethodsContext);
2808
3054
  const plusMemberHandles = useMemo(() => {
2809
3055
  return [
2810
3056
  memberSetting?.plus_monthly_product?.handle,
@@ -3086,8 +3332,13 @@ function CartProvider({
3086
3332
  const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
3087
3333
  useRequest(
3088
3334
  () => {
3089
- const newAttributes = [...attributes, ...customAttributes];
3090
- const needUpdate = cart && !checkAttributesUpdateNeeded(
3335
+ const newAttributes = [...attributes];
3336
+ customAttributes.forEach((item) => {
3337
+ if (item.value && !newAttributes.some((attr) => attr.key === item.key)) {
3338
+ newAttributes.push(item);
3339
+ }
3340
+ });
3341
+ const needUpdate = cart && checkAttributesUpdateNeeded(
3091
3342
  cart.customAttributes,
3092
3343
  newAttributes,
3093
3344
  customAttributesNeedDelete
@@ -3110,7 +3361,8 @@ function CartProvider({
3110
3361
  cart,
3111
3362
  mutateCart,
3112
3363
  isCartLoading: isCartLoading || isCodeChanging,
3113
- setLoadingState
3364
+ setLoadingState,
3365
+ metafieldIdentifiers
3114
3366
  });
3115
3367
  const removeCustomAttributes = useCallback(
3116
3368
  (attributes2) => {
@@ -3191,8 +3443,14 @@ function CartProvider({
3191
3443
  );
3192
3444
  return result;
3193
3445
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
3446
+ const totalQuantity = useMemo(() => {
3447
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
3448
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3449
+ return cartLinesCount + giftLinesCount;
3450
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
3194
3451
  const value = useMemo(
3195
3452
  () => ({
3453
+ totalQuantity,
3196
3454
  cart,
3197
3455
  isCartLoading,
3198
3456
  triggerFetch: fetchCart,
@@ -3220,6 +3478,7 @@ function CartProvider({
3220
3478
  }),
3221
3479
  [
3222
3480
  cart,
3481
+ totalQuantity,
3223
3482
  isCartLoading,
3224
3483
  fetchCart,
3225
3484
  mutateCart,
@@ -3244,14 +3503,14 @@ function CartProvider({
3244
3503
  );
3245
3504
  return /* @__PURE__ */ jsx(CartContext.Provider, { value, children });
3246
3505
  }
3247
- function useCartContext() {
3506
+ function useCartContext(options) {
3248
3507
  const context = useContext(CartContext);
3249
- if (!context) {
3508
+ if (!context && !options?.optional) {
3250
3509
  throw new Error("useCartContext must be used within a CartProvider");
3251
3510
  }
3252
3511
  return context;
3253
3512
  }
3254
3513
 
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 };
3514
+ export { BrowserPerformanceAdapter, 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, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useAvailableDeliveryCoupon, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartContext, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useIntersection, usePlusAnnualProductVariant, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberDeliveryCodes, usePlusMemberItemCustomAttributes, usePlusMemberNeedAddToCart, usePlusMonthlyProductVariant, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethodAvailableCheck, useShippingMethods, useShopify, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdatePlusMemberDeliveryOptions, useUpdateVariantQuery, useVariant, useVariantMedia };
3256
3515
  //# sourceMappingURL=index.mjs.map
3257
3516
  //# sourceMappingURL=index.mjs.map