@anker-in/shopify-react 0.1.1-beta.9 → 0.1.1

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, updateCartDeliveryOptions } 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, getLocalStorage, updateCartLines, removeCartLines, updateCartAttributes, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getCart, setLocalStorage } 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 });
@@ -132,6 +150,7 @@ var CUSTOMER_ATTRIBUTE_KEY = "_discounts_function_env";
132
150
  var CUSTOMER_SCRIPT_GIFT_KEY = "_giveaway_gradient_gifts";
133
151
  var CODE_AMOUNT_KEY = "_sku_code_money";
134
152
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
153
+ var MEMBER_PRICE_ATTRIBUTE_KEY = "_member_price";
135
154
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
136
155
 
137
156
  // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
@@ -140,9 +159,10 @@ function normalizeAddToCartLines(lines) {
140
159
  const variant = line.variant;
141
160
  const product = variant.product;
142
161
  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;
162
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
163
+ const finalPrice = variant.finalPrice?.amount === void 0 ? originalPrice : Number(variant.finalPrice?.amount);
164
+ const subtotalAmount = originalPrice * quantity;
165
+ const totalAmount = finalPrice * quantity;
146
166
  return {
147
167
  id: `temp-line-${index}-${variant.id}`,
148
168
  // Temporary ID for pre-cart lines
@@ -156,7 +176,7 @@ function normalizeAddToCartLines(lines) {
156
176
  customAttributes: line.attributes || [],
157
177
  variant: {
158
178
  id: variant.id,
159
- price,
179
+ price: finalPrice,
160
180
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
161
181
  sku: variant.sku || "",
162
182
  name: variant.title || "",
@@ -187,12 +207,13 @@ function createMockCartFromLines(lines, existingCart) {
187
207
  const normalizedLines = normalizeAddToCartLines(lines);
188
208
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
189
209
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
210
+ const currency = lines[0]?.variant?.price?.currencyCode;
190
211
  return {
191
212
  id: existingCart?.id || "temp-cart-id",
192
213
  customerId: existingCart?.customerId,
193
214
  email: existingCart?.email,
194
215
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
195
- currency: existingCart?.currency || { code: "USD" },
216
+ currency: existingCart?.currency || { code: currency },
196
217
  taxesIncluded: existingCart?.taxesIncluded,
197
218
  lineItems: normalizedLines,
198
219
  totalLineItemsDiscount: 0,
@@ -226,16 +247,6 @@ var getQuery = () => {
226
247
  }
227
248
  return theRequest;
228
249
  };
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
250
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
240
251
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
241
252
  const matchedList = cartData?.lineItems?.filter((line) => {
@@ -259,14 +270,6 @@ var getDiscountEnvAttributeValue = (attributes = []) => {
259
270
  const attr = attributes.find((attr2) => attr2.key === CUSTOMER_ATTRIBUTE_KEY);
260
271
  return safeParse(attr?.value ?? "") ?? {};
261
272
  };
262
- var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
263
- return oldAttributes.some((attr) => {
264
- const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
265
- return newAttr ? newAttr.value !== attr.value : true;
266
- }) || newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || customAttributesNeedRemove.some(
267
- (removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
268
- );
269
- };
270
273
  var containsAll = (source, requiredItems = []) => {
271
274
  if (!requiredItems?.length) return true;
272
275
  const sourceSet = new Set(source);
@@ -467,43 +470,29 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
467
470
  }
468
471
  return { activeCampaign: null, subtotal: 0 };
469
472
  }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
470
- const { qualifyingGift, nextTierGoal } = useMemo(() => {
473
+ const { qualifyingTier, nextTierGoal, actualThreshold, currentCurrency } = useMemo(() => {
471
474
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
472
- return { qualifyingGift: null, nextTierGoal: null };
475
+ return { qualifyingTier: null, nextTierGoal: null, actualThreshold: 0, currentCurrency: "" };
473
476
  }
474
477
  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)
478
+ const currentCurrency2 = effectiveCart?.currency?.code || "";
479
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency2);
480
+ const getThresholdAmount = (tier) => {
481
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency2]?.value) {
482
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency2].value);
483
+ }
484
+ return Number(tier.spend_sum_money || 0);
504
485
  };
505
- return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
506
- }, [activeCampaign, subtotal]);
486
+ const qualifyingTier2 = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
487
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
488
+ const actualThreshold2 = qualifyingTier2 ? getThresholdAmount(qualifyingTier2) : 0;
489
+ return {
490
+ qualifyingTier: qualifyingTier2,
491
+ nextTierGoal: nextGoal || null,
492
+ actualThreshold: actualThreshold2,
493
+ currentCurrency: currentCurrency2
494
+ };
495
+ }, [activeCampaign, subtotal, effectiveCart]);
507
496
  const giftHandles = useMemo(() => {
508
497
  const giftVariant = autoFreeGiftConfig.map(
509
498
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -519,24 +508,82 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
519
508
  }
520
509
  return true;
521
510
  }, [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
- });
511
+ const { data: giftProductsResult } = useSWR(
512
+ shouldFetch ? giftHandles : null,
513
+ async () => {
514
+ const res = await getProductsByHandles(client, {
515
+ handles: giftHandles,
516
+ locale
517
+ });
518
+ const result = Array.isArray(res) ? res : [];
519
+ giftProductsCache.current = {
520
+ data: result,
521
+ giftHandles: [...giftHandles]
522
+ };
523
+ return result;
524
+ },
525
+ {
526
+ revalidateOnFocus: false
527
+ }
528
+ );
534
529
  const finalGiftProductsResult = useMemo(() => {
535
530
  if (giftProductsCache.current && !shouldFetch) {
536
531
  return giftProductsCache.current.data || void 0;
537
532
  }
538
533
  return giftProductsResult;
539
534
  }, [giftProductsResult, shouldFetch]);
535
+ const qualifyingGift = useMemo(() => {
536
+ if (!qualifyingTier || !activeCampaign) {
537
+ return null;
538
+ }
539
+ const itemsToAdd = qualifyingTier.reward_list?.map((reward) => {
540
+ if (!reward.variant_list || reward.variant_list.length === 0) {
541
+ return null;
542
+ }
543
+ let selectedGiftProduct = null;
544
+ for (const giftVariant of reward.variant_list) {
545
+ const productInfo = finalGiftProductsResult?.find(
546
+ (p) => p.handle === giftVariant.handle
547
+ );
548
+ if (productInfo) {
549
+ const variantInfo = productInfo.variants?.find((v) => v.sku === giftVariant.sku);
550
+ if (variantInfo?.availableForSale) {
551
+ selectedGiftProduct = giftVariant;
552
+ break;
553
+ }
554
+ }
555
+ }
556
+ if (!selectedGiftProduct) {
557
+ selectedGiftProduct = reward.variant_list[0];
558
+ }
559
+ return {
560
+ variant: {
561
+ id: btoaID(selectedGiftProduct.variant_id),
562
+ handle: selectedGiftProduct.handle,
563
+ sku: selectedGiftProduct.sku
564
+ },
565
+ quantity: reward?.get_unit || 1,
566
+ attributes: [
567
+ {
568
+ key: CUSTOMER_ATTRIBUTE_KEY,
569
+ value: JSON.stringify({
570
+ is_gift: true,
571
+ rule_id: activeCampaign.rule_id,
572
+ spend_sum_money: actualThreshold,
573
+ // 使用实际的门槛金额(多币种支持)
574
+ currency_code: currentCurrency
575
+ // 记录当前币种
576
+ })
577
+ }
578
+ ]
579
+ };
580
+ }).filter((item) => item !== null);
581
+ const formattedGift = {
582
+ tier: qualifyingTier,
583
+ itemsToAdd
584
+ };
585
+ return formattedGift;
586
+ }, [qualifyingTier, activeCampaign, finalGiftProductsResult, actualThreshold, currentCurrency]);
540
587
  return {
541
588
  qualifyingGift,
542
589
  nextTierGoal,
@@ -550,7 +597,8 @@ var useScriptAutoFreeGift = ({
550
597
  _giveaway,
551
598
  cart,
552
599
  locale: providedLocale,
553
- lines
600
+ lines,
601
+ profile
554
602
  }) => {
555
603
  const { client, locale: contextLocale } = useShopify();
556
604
  const locale = providedLocale || contextLocale;
@@ -574,8 +622,9 @@ var useScriptAutoFreeGift = ({
574
622
  const utmCampaign = Cookies5.get("utm_campaign") || query?.utm_campaign;
575
623
  if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
576
624
  return false;
625
+ if (campaign.requireLogin && !profile?.email) return false;
577
626
  return true;
578
- }, [campaign]);
627
+ }, [campaign, profile]);
579
628
  const [upgrade_multiple, upgrade_value] = useMemo(() => {
580
629
  let upgrade_multiple2 = 1;
581
630
  let upgrade_value2 = 0;
@@ -583,12 +632,14 @@ var useScriptAutoFreeGift = ({
583
632
  upgrade_multiple2 = 1.2;
584
633
  upgrade_value2 = 40;
585
634
  }
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
- });
635
+ effectiveCart?.lineItems?.forEach(
636
+ ({ customAttributes }) => {
637
+ customAttributes?.forEach(({ key, value }) => {
638
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
639
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
640
+ });
641
+ }
642
+ );
592
643
  return [upgrade_multiple2, upgrade_value2];
593
644
  }, [effectiveCart?.lineItems, points_subscribe]);
594
645
  const breakpoints = useMemo(() => {
@@ -653,18 +704,24 @@ var useScriptAutoFreeGift = ({
653
704
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
654
705
  return [currentLevel, nextLevel];
655
706
  }, [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
- });
707
+ const { data: giftProductsResult } = useSWR(
708
+ shouldFetch ? giftHandles : null,
709
+ async () => {
710
+ const res = await getProductsByHandles(client, {
711
+ handles: giftHandles,
712
+ locale
713
+ });
714
+ const result = Array.isArray(res) ? res : [];
715
+ giftProductsCache.current = {
716
+ data: result,
717
+ giftHandles: [...giftHandles]
718
+ };
719
+ return result;
720
+ },
721
+ {
722
+ revalidateOnFocus: false
723
+ }
724
+ );
668
725
  const finalGiftProductsResult = useMemo(() => {
669
726
  if (giftProductsCache.current && !shouldFetch) {
670
727
  return giftProductsCache.current.data || void 0;
@@ -696,7 +753,20 @@ var useScriptAutoFreeGift = ({
696
753
  giftProductsResult: finalGiftProductsResult
697
754
  };
698
755
  };
699
- function useCreateCart(options) {
756
+
757
+ // src/hooks/cart/utils/cart-attributes.ts
758
+ var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
759
+ return newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || oldAttributes.some((attr) => {
760
+ const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
761
+ return newAttr ? newAttr.value !== attr.value : true;
762
+ }) || customAttributesNeedRemove.some(
763
+ (removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
764
+ );
765
+ };
766
+ function useCreateCart({
767
+ updateCookie = false,
768
+ options
769
+ }) {
700
770
  const { client, locale, cartCookieAdapter } = useShopify();
701
771
  const { mutateCart, metafieldIdentifiers } = useCartContext();
702
772
  const createNewCart = useCallback(
@@ -704,7 +774,8 @@ function useCreateCart(options) {
704
774
  let newCart = await createCart(client, {
705
775
  ...arg,
706
776
  metafieldIdentifiers,
707
- cookieAdapter: cartCookieAdapter
777
+ cookieAdapter: cartCookieAdapter,
778
+ updateCookie
708
779
  });
709
780
  if (newCart) {
710
781
  const unApplicableCodes = newCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
@@ -731,11 +802,23 @@ function useAddCartLines(options) {
731
802
  const { mutateCart, metafieldIdentifiers } = useCartContext();
732
803
  const addLines = useCallback(
733
804
  async (_key, { arg }) => {
734
- let updatedCart = await addCartLines(client, {
735
- ...arg,
736
- metafieldIdentifiers,
737
- cookieAdapter: cartCookieAdapter
738
- });
805
+ const { cartId, lines } = arg;
806
+ const id = cartId || cartCookieAdapter?.getCartId(locale);
807
+ let updatedCart;
808
+ if (!id) {
809
+ updatedCart = await createCart(client, {
810
+ lines,
811
+ metafieldIdentifiers,
812
+ cookieAdapter: cartCookieAdapter
813
+ });
814
+ } else {
815
+ updatedCart = await addCartLines(client, {
816
+ cartId: id,
817
+ lines,
818
+ metafieldIdentifiers,
819
+ cookieAdapter: cartCookieAdapter
820
+ });
821
+ }
739
822
  if (updatedCart) {
740
823
  const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
741
824
  if (unApplicableCodes.length > 0) {
@@ -782,7 +865,7 @@ var trackAddToCartGA = ({
782
865
  const currencyCode = variant.product?.price?.currencyCode;
783
866
  const totalPrice = lineItems?.reduce(
784
867
  (prev, { variant: variant2 }) => prev.plus(
785
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
868
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
786
869
  ),
787
870
  new Decimal2(0)
788
871
  ).toNumber();
@@ -817,7 +900,7 @@ var trackBeginCheckoutGA = ({
817
900
  }
818
901
  const totalPrice = lineItems?.reduce(
819
902
  (prev, { variant }) => prev.plus(
820
- variant?.finalPrice?.amount ?? variant?.compareAtPrice?.amount ?? variant?.price?.amount ?? 0
903
+ variant?.finalPrice?.amount === void 0 ? Number(variant?.price?.amount) || 0 : Number(variant?.finalPrice?.amount) || 0
821
904
  ),
822
905
  new Decimal2(0)
823
906
  ).toNumber();
@@ -850,10 +933,10 @@ var trackBuyNowGA = ({
850
933
  return;
851
934
  }
852
935
  const { variant } = lineItems[0];
853
- const currencyCode = variant.price?.currencyCode;
936
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
854
937
  const totalPrice = lineItems?.reduce(
855
938
  (prev, { variant: variant2 }) => prev.plus(
856
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
939
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
857
940
  ),
858
941
  new Decimal2(0)
859
942
  ).toNumber();
@@ -927,7 +1010,7 @@ function useApplyCartCodes(options) {
927
1010
  if (!discountCodes?.length) {
928
1011
  throw new Error("Invalid input used for this operation: Miss discountCode");
929
1012
  }
930
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1013
+ const cartId = providedCartId || cart?.id;
931
1014
  if (!cartId) {
932
1015
  return void 0;
933
1016
  }
@@ -940,12 +1023,18 @@ function useApplyCartCodes(options) {
940
1023
  cookieAdapter: cartCookieAdapter,
941
1024
  metafieldIdentifiers
942
1025
  });
1026
+ const unApplicableCodes = discountCodes.filter(
1027
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
1028
+ );
1029
+ if (unApplicableCodes.length) {
1030
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
1031
+ }
943
1032
  if (updatedCart) {
944
1033
  mutateCart(updatedCart);
945
1034
  }
946
1035
  return updatedCart;
947
1036
  },
948
- [client, locale, cartCookieAdapter, mutateCart, cart]
1037
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
949
1038
  );
950
1039
  return useSWRMutation("apply-codes", applyCodes, options);
951
1040
  }
@@ -955,7 +1044,7 @@ function useRemoveCartCodes(options) {
955
1044
  const removeCodes = useCallback(
956
1045
  async (_key, { arg }) => {
957
1046
  const { cartId: providedCartId, discountCodes } = arg;
958
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
1047
+ const cartId = providedCartId || cart?.id;
959
1048
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
960
1049
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
961
1050
  const updatedCart = await updateCartCodes(client, {
@@ -969,225 +1058,96 @@ function useRemoveCartCodes(options) {
969
1058
  }
970
1059
  return updatedCart;
971
1060
  },
972
- [client, locale, cartCookieAdapter, mutateCart, cart]
1061
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
973
1062
  );
974
1063
  return useSWRMutation("remove-codes", removeCodes, options);
975
1064
  }
976
-
977
- // src/hooks/cart/use-add-to-cart.ts
978
- function useAddToCart({ withTrack = true } = {}, swrOptions) {
979
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
980
- const { cart } = useCartContext();
981
- const { trigger: applyCartCodes } = useApplyCartCodes();
982
- const { trigger: removeInvalidCodes } = useRemoveCartCodes();
983
- const { trigger: addCartLines2 } = useAddCartLines();
984
- const addToCart = useCallback(
985
- async (_key, { arg }) => {
986
- const {
987
- lineItems,
988
- cartId: providedCartId,
989
- discountCodes,
990
- gtmParams = {},
991
- buyerIdentity,
992
- needCreateCart = false,
993
- onCodesInvalid,
994
- replaceExistingCodes
995
- } = arg;
996
- if (!lineItems || lineItems.length === 0) {
997
- return;
998
- }
999
- const lines = lineItems.map((item) => ({
1000
- merchandiseId: item.variant?.id || "",
1001
- quantity: item.quantity || 1,
1002
- attributes: item.attributes,
1003
- sellingPlanId: item.sellingPlanId
1004
- })).filter((item) => item.merchandiseId && item.quantity);
1005
- if (lines.length === 0) {
1006
- return;
1007
- }
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;
1025
- }
1026
- } else {
1027
- await removeInvalidCodes({
1028
- discountCodes: unapplicableCodes
1029
- });
1030
- }
1031
- }
1032
- }
1033
- if (discountCodes && discountCodes.length > 0) {
1034
- applyCartCodes({
1035
- replaceExistingCodes,
1036
- discountCodes
1037
- });
1038
- }
1039
- if (withTrack) {
1040
- trackAddToCartGA({
1041
- lineItems,
1042
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1043
- });
1044
- trackAddToCartFBQ({ lineItems });
1045
- }
1046
- return resultCart;
1047
- },
1048
- [client, locale, cartCookieAdapter, userAdapter, cart, withTrack]
1065
+ var initSameLinesAttributes = ({
1066
+ cart,
1067
+ line
1068
+ }) => {
1069
+ const sameLineInCart = cart?.lineItems.find(
1070
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
1049
1071
  );
1050
- return useSWRMutation("add-to-cart", addToCart, swrOptions);
1051
- }
1052
- function useUpdateCartLines(options) {
1053
- const { client, locale, cartCookieAdapter } = useShopify();
1054
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1055
- const updateLines = useCallback(
1056
- async (_key, { arg }) => {
1057
- const updatedCart = await updateCartLines(client, {
1058
- ...arg,
1059
- metafieldIdentifiers,
1060
- cookieAdapter: cartCookieAdapter
1061
- });
1062
- if (updatedCart) {
1063
- mutateCart(updatedCart);
1064
- }
1065
- return updatedCart;
1066
- },
1067
- [client, locale, cartCookieAdapter, mutateCart]
1072
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
1073
+ (attr) => attr.key === CODE_AMOUNT_KEY
1068
1074
  );
1069
- return useSWRMutation("update-cart-lines", updateLines, options);
1070
- }
1071
- function useRemoveCartLines(options) {
1072
- const { client, locale, cartCookieAdapter } = useShopify();
1073
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1074
- const removeLines = useCallback(
1075
- async (_key, { arg }) => {
1076
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1077
- let updatedCart = await removeCartLines(client, {
1078
- cartId,
1079
- lineIds,
1080
- metafieldIdentifiers,
1081
- cookieAdapter: cartCookieAdapter
1082
- });
1083
- if (updatedCart && autoRemoveInvalidCodes) {
1084
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1085
- if (unApplicableCodes.length > 0) {
1086
- if (onCodesRemoved) {
1087
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1088
- if (handledCart) {
1089
- updatedCart = handledCart;
1090
- }
1091
- } else {
1092
- updatedCart = await updateCartCodes(client, {
1093
- cartId: updatedCart.id,
1094
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1095
- metafieldIdentifiers,
1096
- cookieAdapter: cartCookieAdapter
1097
- }) || updatedCart;
1098
- }
1099
- }
1100
- }
1101
- if (updatedCart) {
1102
- mutateCart(updatedCart);
1075
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
1076
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
1077
+ );
1078
+ let functionAttribute = null;
1079
+ try {
1080
+ functionAttribute = sameLineInCart?.customAttributes?.find(
1081
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
1082
+ );
1083
+ } catch (error) {
1084
+ }
1085
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
1086
+ return {
1087
+ ...line,
1088
+ attributes: [
1089
+ ...line.attributes || [],
1090
+ codeAmountAttribute,
1091
+ functionAttribute,
1092
+ scriptCodeAmountAttribute
1093
+ ].filter(Boolean)
1094
+ };
1095
+ }
1096
+ return line;
1097
+ };
1098
+ var initDiscountAttributes = ({ line }) => {
1099
+ let itemAttributes = line.attributes || [];
1100
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
1101
+ if (!functionEnvAttribute) {
1102
+ itemAttributes = itemAttributes.concat([
1103
+ {
1104
+ key: CUSTOMER_ATTRIBUTE_KEY,
1105
+ value: JSON.stringify({
1106
+ is_gift: false,
1107
+ discounted_amount: line.variant?.finalPrice?.amount === void 0 ? Number(line.variant?.price?.amount) * (line.quantity || 1) : Number(line.variant?.finalPrice?.amount) * (line.quantity || 1)
1108
+ })
1103
1109
  }
1104
- return updatedCart;
1105
- },
1106
- [client, locale, cartCookieAdapter, mutateCart]
1110
+ ]);
1111
+ }
1112
+ const memberPriceAttribute = itemAttributes.find(
1113
+ (attr) => attr.key === MEMBER_PRICE_ATTRIBUTE_KEY
1107
1114
  );
1108
- return useSWRMutation("remove-cart-lines", removeLines, options);
1109
- }
1110
- function useUpdateCartAttributes(mutate, metafieldIdentifiers, options) {
1111
- const { client, locale, cartCookieAdapter } = useShopify();
1112
- const updateAttributes = useCallback(
1113
- async (_key, { arg }) => {
1114
- const updatedCart = await updateCartAttributes(client, {
1115
- ...arg,
1116
- metafieldIdentifiers,
1117
- cookieAdapter: cartCookieAdapter
1118
- });
1119
- console.log("useUpdateCartAttributes updatedCart", updatedCart);
1120
- if (updatedCart) {
1121
- mutate(updatedCart);
1115
+ const coupon = line.coupon;
1116
+ if (!memberPriceAttribute && coupon) {
1117
+ itemAttributes = itemAttributes.concat([
1118
+ {
1119
+ key: MEMBER_PRICE_ATTRIBUTE_KEY,
1120
+ value: JSON.stringify({ code: coupon.code })
1122
1121
  }
1123
- return updatedCart;
1124
- },
1125
- [client, locale, cartCookieAdapter, mutate]
1122
+ ]);
1123
+ }
1124
+ const couponDiscountAttribute = itemAttributes.find(
1125
+ (attr) => attr.key === CODE_AMOUNT_KEY || attr.key === SCRIPT_CODE_AMOUNT_KEY
1126
1126
  );
1127
- return useSWRMutation("update-cart-attributes", updateAttributes, options);
1128
- }
1129
- function useBuyNow({ withTrack = true } = {}, swrOptions) {
1130
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
1131
- const isLoggedIn = userAdapter?.isLoggedIn || false;
1132
- const buyNow = useCallback(
1133
- async (_key, { arg }) => {
1134
- const {
1135
- lineItems,
1136
- discountCodes,
1137
- gtmParams = {},
1138
- buyerIdentity,
1139
- fbqTrackConfig,
1140
- customAttributes,
1141
- metafieldIdentifiers,
1142
- redirectToCheckout
1143
- } = arg;
1144
- if (!lineItems || lineItems.length === 0) {
1145
- return;
1146
- }
1147
- const lines = lineItems.map((item) => ({
1148
- merchandiseId: item.variant?.id || "",
1149
- quantity: item.quantity || 1,
1150
- attributes: item.attributes,
1151
- sellingPlanId: item.sellingPlanId
1152
- })).filter((item) => item.merchandiseId && item.quantity);
1153
- if (lines.length === 0) {
1154
- return;
1155
- }
1156
- const resultCart = await createCart(client, {
1157
- lines,
1158
- metafieldIdentifiers,
1159
- cookieAdapter: cartCookieAdapter,
1160
- buyerIdentity,
1161
- discountCodes,
1162
- customAttributes
1163
- });
1164
- if (!resultCart) {
1165
- throw new Error("Failed to create cart for buy now");
1166
- }
1167
- if (withTrack && resultCart.lineItems) {
1168
- trackBuyNowGA({
1169
- lineItems,
1170
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1171
- });
1172
- if (fbqTrackConfig) {
1173
- trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
1174
- }
1175
- }
1176
- if (redirectToCheckout) {
1177
- if (resultCart.url) {
1178
- if (typeof window !== "undefined") {
1179
- window.location.href = resultCart.url;
1180
- }
1181
- } else {
1182
- throw new Error("Failed to get checkout URL");
1183
- }
1127
+ if (!couponDiscountAttribute && coupon && Number(coupon?.amount) > 0) {
1128
+ itemAttributes = itemAttributes.concat([
1129
+ {
1130
+ key: CODE_AMOUNT_KEY,
1131
+ value: new Decimal2(coupon.amount).times(line.quantity || 1).toString()
1132
+ },
1133
+ {
1134
+ key: SCRIPT_CODE_AMOUNT_KEY,
1135
+ value: new Decimal2(coupon.amount).times(line.quantity || 1).toString()
1184
1136
  }
1185
- return resultCart;
1186
- },
1187
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
1188
- );
1189
- return useSWRMutation("buy-now", buyNow, swrOptions);
1190
- }
1137
+ ]);
1138
+ }
1139
+ return { ...line, attributes: itemAttributes };
1140
+ };
1141
+ var getLinesWithAttributes = ({
1142
+ cart,
1143
+ lineItems
1144
+ }) => {
1145
+ return lineItems.map((line) => {
1146
+ const sameLine = initSameLinesAttributes({ cart, line });
1147
+ const functionLine = initDiscountAttributes({ line: sameLine });
1148
+ return functionLine;
1149
+ });
1150
+ };
1191
1151
  function useCalcGiftsFromLines({
1192
1152
  lines,
1193
1153
  customer,
@@ -1204,30 +1164,55 @@ function useCalcGiftsFromLines({
1204
1164
  lines
1205
1165
  });
1206
1166
  const allGiftLines = useMemo(() => {
1207
- const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || [];
1208
- const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((product) => {
1209
- const giftProduct = scriptGift.giftProductsResult?.find(
1210
- (p) => p.handle === product.handle
1167
+ const functionGiftLines = (functionGift.qualifyingGift?.itemsToAdd || []).map((item) => {
1168
+ const product = functionGift.giftProductsResult?.find(
1169
+ (product2) => product2.handle === item.variant.handle
1170
+ );
1171
+ const variants = product?.variants;
1172
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.variant.sku) : void 0;
1173
+ if (!variant) {
1174
+ console.warn(
1175
+ `Function gift: Variant not found for handle=${item.variant.handle}, sku=${item.variant.sku}`
1176
+ );
1177
+ return null;
1178
+ }
1179
+ return {
1180
+ variant: {
1181
+ ...variant,
1182
+ product
1183
+ },
1184
+ quantity: item.quantity ?? 1,
1185
+ attributes: item.attributes
1186
+ };
1187
+ }).filter((item) => item !== null);
1188
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((item) => {
1189
+ const product = scriptGift.giftProductsResult?.find(
1190
+ (product2) => product2.handle === item.handle
1211
1191
  );
1212
- const variant = giftProduct?.variants?.[0];
1192
+ const variants = product?.variants;
1193
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1194
+ if (!variant) {
1195
+ console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1196
+ return null;
1197
+ }
1213
1198
  return {
1214
1199
  variant: {
1215
- id: variant?.id || "",
1216
- handle: product.handle,
1217
- sku: product.sku
1200
+ ...variant,
1201
+ product
1218
1202
  },
1219
1203
  quantity: 1,
1220
1204
  attributes: [
1221
1205
  {
1222
1206
  key: scriptGiveawayKey,
1223
- value: "true"
1207
+ value: scriptGiveawayKey
1224
1208
  }
1225
1209
  ]
1226
1210
  };
1227
- }).filter((item) => item.variant.id) : [];
1211
+ }).filter((item) => item !== null) : [];
1228
1212
  return [...functionGiftLines, ...scriptGiftLines];
1229
1213
  }, [
1230
1214
  functionGift.qualifyingGift,
1215
+ functionGift.giftProductsResult,
1231
1216
  scriptGift.freeGiftLevel,
1232
1217
  scriptGift.giftProductsResult,
1233
1218
  scriptGiveawayKey
@@ -1262,7 +1247,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1262
1247
  const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
1263
1248
  const dealsType = "";
1264
1249
  const { activeCampaign, subtotal } = useMemo(() => {
1265
- for (const campaign of orderDiscountConfig) {
1250
+ for (const campaign of orderDiscountConfig || []) {
1266
1251
  const { rule_conditions = [], result_detail } = campaign;
1267
1252
  const { main_product, order_discount_conf } = result_detail || {};
1268
1253
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
@@ -1292,9 +1277,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1292
1277
  discountAmount: 0
1293
1278
  };
1294
1279
  }
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));
1280
+ const currentCurrency = cart?.currency?.code || "";
1281
+ console.log("currentCurrency", cart, currentCurrency);
1282
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1283
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1284
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1285
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1298
1286
  if (!qualifyingTier) {
1299
1287
  return {
1300
1288
  qualifyingDiscount: null,
@@ -1331,43 +1319,10 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1331
1319
  isLoading: isCustomerLoading
1332
1320
  };
1333
1321
  };
1334
- function useHasPlusMemberInCart({
1335
- memberSetting,
1336
- cart
1337
- }) {
1338
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1339
- return useMemo(() => {
1340
- if (!cart?.lineItems) {
1341
- return {
1342
- hasPlusMember: false,
1343
- hasMonthlyPlus: false,
1344
- hasAnnualPlus: false
1345
- };
1346
- }
1347
- const monthlyPlusItem = cart.lineItems.find(
1348
- (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1349
- );
1350
- const annualPlusItem = cart.lineItems.find(
1351
- (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1352
- );
1353
- const hasMonthlyPlus = !!monthlyPlusItem;
1354
- const hasAnnualPlus = !!annualPlusItem;
1355
- const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1356
- return {
1357
- hasPlusMember,
1358
- hasMonthlyPlus,
1359
- hasAnnualPlus,
1360
- monthlyPlusItem,
1361
- annualPlusItem
1362
- };
1363
- }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1364
- }
1365
-
1366
- // src/hooks/cart/feature/use-cart-attributes.ts
1367
1322
  var getReferralAttributes = () => {
1368
- const inviteCode = Cookies5.get("invite_code");
1369
- const playModeId = Cookies5.get("playModeId");
1370
- const popup = Cookies5.get("_popup");
1323
+ const inviteCode = getLocalStorage("inviteCode") || Cookies5.get("inviteCode");
1324
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
1325
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
1371
1326
  if (inviteCode && playModeId) {
1372
1327
  return popup ? [
1373
1328
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1380,121 +1335,130 @@ var getReferralAttributes = () => {
1380
1335
  }
1381
1336
  return [];
1382
1337
  };
1338
+ var getUserType = (customer) => {
1339
+ let userInfo = Cookies5.get("userInfo");
1340
+ if (userInfo) {
1341
+ userInfo = JSON.parse(userInfo);
1342
+ let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1343
+ userInfo.setId = arr[arr.length - 1];
1344
+ }
1345
+ const customerInfo = userInfo || customer;
1346
+ if (!customerInfo) {
1347
+ return "new_user_unlogin";
1348
+ }
1349
+ if (customer) {
1350
+ const { orders = {} } = customer;
1351
+ if (orders?.edges?.length === 1) {
1352
+ return "old_user_orders_once";
1353
+ } else if (orders?.edges?.length > 1) {
1354
+ return "old_user_orders_twice";
1355
+ }
1356
+ }
1357
+ return "new_user_login";
1358
+ };
1359
+ function getCartAttributes({
1360
+ profile,
1361
+ customer,
1362
+ cart,
1363
+ memberType,
1364
+ currentUrl = ""
1365
+ }) {
1366
+ const userType = getUserType(customer);
1367
+ const memberAttributes = [
1368
+ {
1369
+ key: "_token",
1370
+ value: profile?.token
1371
+ },
1372
+ {
1373
+ key: "_member_type",
1374
+ value: memberType ?? String(profile?.memberType ?? 0)
1375
+ },
1376
+ {
1377
+ key: "_user_type",
1378
+ value: userType
1379
+ },
1380
+ {
1381
+ key: "_is_login",
1382
+ value: profile?.token ? "true" : "false"
1383
+ }
1384
+ ];
1385
+ if (profile?.token) {
1386
+ memberAttributes.push({
1387
+ key: "_login_user",
1388
+ value: "1"
1389
+ });
1390
+ }
1391
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1392
+ const functionAttributes = [
1393
+ {
1394
+ key: CUSTOMER_ATTRIBUTE_KEY,
1395
+ value: JSON.stringify({
1396
+ discount_code: discountCodes,
1397
+ user_tags: customer?.tags || []
1398
+ })
1399
+ }
1400
+ ];
1401
+ const presellAttributes = [
1402
+ {
1403
+ key: "_presale",
1404
+ value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1405
+ }
1406
+ ];
1407
+ const weightAttributes = [
1408
+ {
1409
+ key: "_weight",
1410
+ value: cart?.lineItems.reduce((acc, item) => {
1411
+ return new Decimal2(acc).plus(item.variant.weight ?? 0).toNumber();
1412
+ }, 0).toString()
1413
+ },
1414
+ {
1415
+ key: "_app_source_name",
1416
+ value: "dtc"
1417
+ }
1418
+ ];
1419
+ const trackingAttributes = [
1420
+ {
1421
+ key: "utm_params",
1422
+ value: currentUrl
1423
+ }
1424
+ ];
1425
+ const commonAttributes = [
1426
+ ...memberAttributes,
1427
+ ...functionAttributes,
1428
+ ...presellAttributes,
1429
+ ...weightAttributes,
1430
+ ...trackingAttributes,
1431
+ ...getReferralAttributes()
1432
+ ].filter((item) => item?.value);
1433
+ const extraAttributesInCart = cart?.customAttributes?.filter(
1434
+ (item) => !commonAttributes.some((attr) => attr.key === item.key)
1435
+ ) || [];
1436
+ return [...commonAttributes, ...extraAttributesInCart].filter((item) => item?.value);
1437
+ }
1383
1438
  var useCartAttributes = ({
1384
1439
  profile,
1385
1440
  customer,
1386
1441
  cart,
1387
- memberSetting
1442
+ memberType
1388
1443
  }) => {
1389
1444
  const [currentUrl, setCurrentUrl] = useState("");
1390
- const { hasPlusMember } = useHasPlusMemberInCart({
1391
- memberSetting,
1392
- cart
1393
- });
1394
1445
  useEffect(() => {
1395
1446
  setCurrentUrl(window.location.href);
1396
1447
  }, []);
1397
- const userType = useMemo(() => {
1398
- let userInfo = Cookies5.get("userInfo");
1399
- if (userInfo) {
1400
- userInfo = JSON.parse(userInfo);
1401
- let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1402
- userInfo.setId = arr[arr.length - 1];
1403
- }
1404
- const customerInfo = userInfo || customer;
1405
- if (!customerInfo) {
1406
- return "new_user_unlogin";
1407
- }
1408
- if (customer) {
1409
- const { orders = {} } = customer;
1410
- if (orders?.edges?.length === 1) {
1411
- return "old_user_orders_once";
1412
- } else if (orders?.edges?.length > 1) {
1413
- return "old_user_orders_twice";
1414
- }
1415
- }
1416
- return "new_user_login";
1417
- }, [customer]);
1418
- const memberAttributes = useMemo(() => {
1419
- return [
1420
- {
1421
- key: "_token",
1422
- value: profile?.token
1423
- //是否登录
1424
- },
1425
- {
1426
- key: "_member_type",
1427
- value: hasPlusMember ? "2" : profile?.memberType
1428
- //:0(游客),1(普通会员),2(付费会员)
1429
- },
1430
- {
1431
- key: "_user_type",
1432
- value: userType
1433
- // n
1434
- },
1435
- {
1436
- key: "_is_login",
1437
- value: profile?.token ? "true" : "false"
1438
- }
1439
- ];
1440
- }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1441
- const functionAttributes = useMemo(() => {
1442
- const hasFunctionEnvAttribute = cart?.lineItems.some(
1443
- (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1444
- );
1445
- const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1446
- return hasFunctionEnvAttribute ? [
1447
- {
1448
- key: "_discounts_function_env",
1449
- value: JSON.stringify({
1450
- discount_code: discountCodes,
1451
- user_tags: customer?.tags || []
1452
- })
1453
- }
1454
- ] : [];
1455
- }, [cart]);
1456
- const presellAttributes = useMemo(() => {
1457
- return [
1458
- {
1459
- key: "_presale",
1460
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1461
- }
1462
- ];
1463
- }, [cart]);
1464
- const weightAttributes = useMemo(() => {
1465
- return [
1466
- {
1467
- key: "_weight",
1468
- value: cart?.lineItems.reduce((acc, item) => {
1469
- return new Decimal2(acc).plus(item.variant.weight ?? 0).toNumber();
1470
- }, 0).toString()
1471
- },
1472
- {
1473
- key: "_app_source_name",
1474
- value: "dtc"
1475
- }
1476
- ];
1477
- }, [cart]);
1478
- const trackingAttributes = useMemo(() => {
1479
- return [
1480
- {
1481
- key: "utm_params",
1482
- value: currentUrl
1483
- }
1484
- ];
1485
- }, [currentUrl]);
1448
+ const attributes = useMemo(() => {
1449
+ return getCartAttributes({
1450
+ profile,
1451
+ customer,
1452
+ cart,
1453
+ memberType,
1454
+ currentUrl
1455
+ });
1456
+ }, [profile, customer, cart, memberType, currentUrl]);
1486
1457
  return useMemo(
1487
1458
  () => ({
1488
- attributes: [
1489
- ...memberAttributes,
1490
- ...functionAttributes,
1491
- ...presellAttributes,
1492
- ...weightAttributes,
1493
- ...trackingAttributes,
1494
- ...getReferralAttributes()
1495
- ].filter((item) => item?.value)
1459
+ attributes
1496
1460
  }),
1497
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1461
+ [attributes]
1498
1462
  );
1499
1463
  };
1500
1464
  var DEFAULT_MIN = 1;
@@ -1557,7 +1521,7 @@ var useUpdateLineCodeAmountAttributes = ({
1557
1521
  );
1558
1522
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1559
1523
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1560
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1524
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1561
1525
  attrNeedUpdate.push({
1562
1526
  key: CUSTOMER_ATTRIBUTE_KEY,
1563
1527
  value: JSON.stringify({
@@ -1596,29 +1560,22 @@ var useUpdateLineCodeAmountAttributes = ({
1596
1560
  }).filter(
1597
1561
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1598
1562
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1563
+ let lineId = line.id;
1564
+ let attributes = line.customAttributes || [];
1565
+ if (attrNeedDelete.length) {
1566
+ attributes = attributes.filter(
1567
+ (attr) => !attrNeedDelete.includes(attr.key)
1568
+ );
1569
+ }
1599
1570
  if (attrNeedUpdate.length) {
1600
- return {
1601
- id: line.id,
1602
- attributes: [
1603
- ...line.customAttributes?.filter(
1604
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1605
- ) || [],
1606
- ...attrNeedUpdate
1607
- ]
1608
- };
1609
- } else if (attrNeedDelete.length) {
1610
- return {
1611
- id: line.id,
1612
- attributes: line.customAttributes?.filter(
1613
- (attr) => !attrNeedDelete.includes(attr.key)
1614
- ) || []
1615
- };
1616
- } else {
1617
- return {
1618
- id: line.id,
1619
- attributes: line.customAttributes || []
1620
- };
1571
+ attributes = attributes.filter(
1572
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1573
+ ).concat(attrNeedUpdate);
1621
1574
  }
1575
+ return {
1576
+ id: lineId,
1577
+ attributes
1578
+ };
1622
1579
  }),
1623
1580
  [cart?.lineItems, mainProductDiscountCodes]
1624
1581
  );
@@ -1653,45 +1610,61 @@ var useUpdateLineCodeAmountAttributes = ({
1653
1610
  }, [loading, setLoadingState]);
1654
1611
  };
1655
1612
 
1656
- // src/hooks/cart/types/price-discount.ts
1657
- var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
1658
- PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1659
- PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1660
- return PriceDiscountType2;
1661
- })(PriceDiscountType || {});
1662
- var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
1663
- PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
1664
- PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
1665
- return PriceBasePriceType2;
1666
- })(PriceBasePriceType || {});
1667
- function useProduct(options = {}) {
1668
- const { client, locale } = useShopify();
1669
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
1670
- return useSWR(
1671
- handle ? ["product", locale, handle, metafieldIdentifiers] : null,
1672
- () => getProduct(client, {
1673
- handle,
1674
- locale,
1675
- metafieldIdentifiers
1676
- }),
1677
- swrOptions
1678
- );
1679
- }
1680
- function useAllProducts(options = {}) {
1681
- const { client, locale } = useShopify();
1682
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
1683
- return useSWR(
1684
- ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
1685
- () => getAllProducts(client, {
1686
- locale,
1687
- first,
1688
- query,
1689
- sortKey,
1690
- reverse,
1691
- metafieldIdentifiers
1692
- }),
1693
- swrOptions
1694
- );
1613
+ // src/hooks/member/plus/types.ts
1614
+ var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
1615
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
1616
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
1617
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
1618
+ return PLUS_MEMBER_TYPE2;
1619
+ })(PLUS_MEMBER_TYPE || {});
1620
+ var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
1621
+ PlusMemberMode2["MONTHLY"] = "monthly";
1622
+ PlusMemberMode2["ANNUAL"] = "annual";
1623
+ return PlusMemberMode2;
1624
+ })(PlusMemberMode || {});
1625
+ var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
1626
+ DeliveryPlusType2["FREE"] = "free";
1627
+ DeliveryPlusType2["MONTHLY"] = "monthly";
1628
+ DeliveryPlusType2["ANNUAL"] = "annual";
1629
+ return DeliveryPlusType2;
1630
+ })(DeliveryPlusType || {});
1631
+ var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
1632
+ ShippingMethodMode2["FREE"] = "free";
1633
+ ShippingMethodMode2["TDD"] = "tdd";
1634
+ ShippingMethodMode2["NDD"] = "ndd";
1635
+ return ShippingMethodMode2;
1636
+ })(ShippingMethodMode || {});
1637
+ var createInitialValue = () => ({
1638
+ plusMemberMetafields: {},
1639
+ selectedPlusMemberMode: "free",
1640
+ setSelectedPlusMemberMode: () => {
1641
+ },
1642
+ selectedShippingMethod: void 0,
1643
+ setSelectedShippingMethod: () => {
1644
+ },
1645
+ showMoreShippingMethod: false,
1646
+ setShowMoreShippingMethod: () => {
1647
+ },
1648
+ variant: {},
1649
+ product: {},
1650
+ shippingMethodsContext: {
1651
+ freeShippingMethods: [],
1652
+ paymentShippingMethods: [],
1653
+ nddOverweight: false,
1654
+ tddOverweight: false,
1655
+ nddCoupon: void 0,
1656
+ tddCoupon: void 0,
1657
+ isLoadingCoupon: false
1658
+ },
1659
+ selectedPlusMemberVariant: void 0,
1660
+ showPlusMemberBenefit: false,
1661
+ setShowPlusMemberBenefit: () => {
1662
+ },
1663
+ profile: void 0
1664
+ });
1665
+ var PlusMemberContext = createContext(createInitialValue());
1666
+ function usePlusMemberContext() {
1667
+ return useContext(PlusMemberContext);
1695
1668
  }
1696
1669
  function useProductsByHandles(options = {}) {
1697
1670
  const { client, locale } = useShopify();
@@ -1711,1213 +1684,1349 @@ function useProductsByHandles(options = {}) {
1711
1684
  metafieldIdentifiers
1712
1685
  });
1713
1686
  },
1714
- swrOptions || {
1715
- revalidateOnFocus: false
1687
+ {
1688
+ revalidateOnFocus: false,
1689
+ ...swrOptions
1716
1690
  }
1717
1691
  );
1718
1692
  }
1719
- function getFirstAvailableVariant(product) {
1720
- const availableVariant = product.variants.find((v) => v.availableForSale);
1721
- return availableVariant || product.variants[0];
1722
- }
1723
- function getVariantFromSelectedOptions(product, selectedOptions) {
1724
- return product.variants.find((variant) => {
1725
- return variant.selectedOptions.every((option) => {
1726
- return selectedOptions[option.name] === option.value;
1727
- });
1728
- });
1729
- }
1730
- function useVariant({
1731
- product,
1732
- selectedOptions
1693
+
1694
+ // src/hooks/member/plus/use-plus-member-variants.ts
1695
+ function usePlusMemberVariants({
1696
+ memberSetting
1733
1697
  }) {
1734
- const [variant, setVariant] = useState(
1735
- product ? getFirstAvailableVariant(product) : void 0
1736
- );
1737
- useEffect(() => {
1738
- if (!product) {
1739
- setVariant(void 0);
1740
- return;
1741
- }
1742
- const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
1743
- if (newVariant && newVariant.id !== variant?.id) {
1744
- setVariant(newVariant);
1745
- } else if (!newVariant) {
1746
- setVariant(getFirstAvailableVariant(product));
1747
- }
1748
- }, [selectedOptions, product, variant?.id]);
1749
- return variant;
1750
- }
1751
- var FAKE_PRICE = 999999999e-2;
1752
- function formatPrice({
1753
- amount,
1754
- currencyCode,
1755
- locale,
1756
- maximumFractionDigits,
1757
- minimumFractionDigits,
1758
- removeTrailingZeros
1759
- }) {
1760
- const formatter = new Intl.NumberFormat(locale, {
1761
- style: "currency",
1762
- currency: currencyCode,
1763
- maximumFractionDigits: maximumFractionDigits ?? 2,
1764
- minimumFractionDigits: minimumFractionDigits ?? 2
1698
+ const plusMonthly = memberSetting?.plus_monthly_product;
1699
+ const plusAnnual = memberSetting?.plus_annual_product;
1700
+ const plusMemberHandles = useMemo(() => {
1701
+ return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
1702
+ }, [plusMonthly?.handle, plusAnnual?.handle]);
1703
+ const { data: plusMemberProducts = [] } = useProductsByHandles({
1704
+ handles: plusMemberHandles
1765
1705
  });
1766
- let formatted = formatter.format(amount);
1767
- if (removeTrailingZeros) {
1768
- formatted = formatted.replace(/\.00$/, "");
1769
- }
1770
- return formatted;
1771
- }
1772
- function formatVariantPrice({
1773
- amount,
1774
- baseAmount,
1775
- currencyCode,
1776
- locale,
1777
- maximumFractionDigits,
1778
- minimumFractionDigits,
1779
- removeTrailingZeros
1780
- }) {
1706
+ const monthlyProduct = useMemo(() => {
1707
+ return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
1708
+ }, [plusMemberProducts, plusMonthly]);
1709
+ const annualProduct = useMemo(() => {
1710
+ return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
1711
+ }, [plusMemberProducts, plusAnnual]);
1712
+ const monthlyVariant = useMemo(() => {
1713
+ return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
1714
+ }, [monthlyProduct, plusMonthly]);
1715
+ const annualVariant = useMemo(() => {
1716
+ return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
1717
+ }, [annualProduct, plusAnnual]);
1781
1718
  return {
1782
- price: formatPrice({
1783
- amount,
1784
- currencyCode,
1785
- locale,
1786
- maximumFractionDigits,
1787
- minimumFractionDigits,
1788
- removeTrailingZeros
1789
- }),
1790
- basePrice: formatPrice({
1791
- amount: baseAmount,
1792
- currencyCode,
1793
- locale,
1794
- maximumFractionDigits,
1795
- minimumFractionDigits,
1796
- removeTrailingZeros
1797
- })
1719
+ monthlyVariant: monthlyVariant ? {
1720
+ ...monthlyVariant,
1721
+ product: monthlyProduct
1722
+ } : void 0,
1723
+ annualVariant: annualVariant ? {
1724
+ ...annualVariant,
1725
+ product: annualProduct
1726
+ } : void 0
1798
1727
  };
1799
1728
  }
1800
- function usePrice({
1801
- amount,
1802
- baseAmount,
1803
- currencyCode,
1804
- soldOutDescription = "",
1805
- maximumFractionDigits,
1806
- minimumFractionDigits,
1807
- removeTrailingZeros
1808
- }) {
1809
- const { locale } = useShopify();
1810
- const value = useMemo(() => {
1811
- if (typeof amount !== "number" || !currencyCode) {
1812
- return "";
1813
- }
1814
- if (soldOutDescription && amount >= FAKE_PRICE) {
1815
- return soldOutDescription;
1729
+ var useAvailableDeliveryCoupon = ({
1730
+ profile
1731
+ }) => {
1732
+ const { data: availableDeliveryCoupon, isLoading } = useSWR(
1733
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
1734
+ async ([apiPath]) => {
1735
+ return fetch(apiPath).then((res) => res.json());
1816
1736
  }
1817
- return baseAmount ? formatVariantPrice({
1818
- amount,
1819
- baseAmount,
1820
- currencyCode,
1821
- locale,
1822
- maximumFractionDigits,
1823
- minimumFractionDigits,
1824
- removeTrailingZeros
1825
- }) : formatPrice({
1826
- amount,
1827
- currencyCode,
1828
- locale,
1829
- maximumFractionDigits,
1830
- minimumFractionDigits,
1831
- removeTrailingZeros
1737
+ );
1738
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
1739
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
1740
+ return {
1741
+ nddCoupon,
1742
+ tddCoupon,
1743
+ isLoading
1744
+ };
1745
+ };
1746
+
1747
+ // src/hooks/member/plus/use-shipping-methods.ts
1748
+ function useShippingMethods(options) {
1749
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
1750
+ const isPlus = profile?.isPlus || false;
1751
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
1752
+ const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
1753
+ const nddOverweight = useMemo(() => {
1754
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
1755
+ }, [shippingMethod?.overWeight_ndd, variant?.weight]);
1756
+ const tddOverweight = useMemo(() => {
1757
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
1758
+ }, [shippingMethod?.overWeight_tdd, variant?.weight]);
1759
+ const paymentShippingMethods = useMemo(() => {
1760
+ const weight = variant?.weight || 0;
1761
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
1762
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1763
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
1764
+ }) || [];
1765
+ return methods.map((method) => {
1766
+ let disabled = false;
1767
+ const selectedFreeMember = selectedPlusMemberMode === "free";
1768
+ if (method.__mode === "ndd" /* NDD */) {
1769
+ disabled = selectedFreeMember || nddOverweight;
1770
+ } else if (method.__mode === "tdd" /* TDD */) {
1771
+ disabled = selectedFreeMember || tddOverweight;
1772
+ }
1773
+ return {
1774
+ ...method,
1775
+ id: method.__mode + method.__code,
1776
+ useCoupon: false,
1777
+ subtitle: plus_shipping?.directly || "",
1778
+ disabled
1779
+ };
1832
1780
  });
1833
1781
  }, [
1834
- amount,
1835
- baseAmount,
1836
- currencyCode,
1837
- locale,
1838
- maximumFractionDigits,
1839
- minimumFractionDigits,
1840
- soldOutDescription,
1841
- removeTrailingZeros
1782
+ nddOverweight,
1783
+ plus_shipping?.directly,
1784
+ plus_shipping?.shipping_methods,
1785
+ selectedPlusMemberMode,
1786
+ tddOverweight,
1787
+ variant?.weight
1842
1788
  ]);
1843
- const result = useMemo(() => {
1844
- const free = Boolean(amount && amount <= 0);
1845
- return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
1846
- }, [value, amount]);
1847
- return result;
1848
- }
1849
- function optionsConstructor(selectedOptions) {
1850
- return selectedOptions.reduce((acc, option) => {
1851
- acc[option.name] = option.value;
1852
- return acc;
1853
- }, {});
1854
- }
1855
- function decodeShopifyId(gid) {
1856
- try {
1857
- const base64 = gid.split("/").pop() || "";
1858
- return atob(base64);
1859
- } catch {
1860
- return gid;
1861
- }
1862
- }
1863
- function useSelectedOptions(product, sku) {
1864
- const [options, setOptions] = useState({});
1865
- useEffect(() => {
1866
- if (!product || !product.variants.length) {
1867
- setOptions({});
1868
- return;
1869
- }
1870
- let variant = product.variants[0];
1871
- if (typeof window !== "undefined") {
1872
- const searchParams = new URLSearchParams(window.location.search);
1873
- const variantIdParam = searchParams.get("variant");
1874
- if (variantIdParam) {
1875
- const foundVariant = product.variants.find((v) => {
1876
- if (sku) return v.sku === sku;
1877
- return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
1878
- });
1879
- if (foundVariant) {
1880
- variant = foundVariant;
1881
- }
1789
+ const nddPrice = useMemo(() => {
1790
+ const weight = variant?.weight || 0;
1791
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1792
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1793
+ return __mode === "ndd" && fitWeight;
1794
+ });
1795
+ return nddMethod?.price || 0;
1796
+ }, [variant?.weight, paymentShippingMethods]);
1797
+ const tddPrice = useMemo(() => {
1798
+ const weight = variant?.weight || 0;
1799
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1800
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1801
+ return __mode === "tdd" && fitWeight;
1802
+ });
1803
+ return tddMethod?.price || 0;
1804
+ }, [variant?.weight, paymentShippingMethods]);
1805
+ const freeShippingMethods = useMemo(() => {
1806
+ const weight = variant?.weight || 0;
1807
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
1808
+ if (__mode === "free" /* FREE */) {
1809
+ return true;
1882
1810
  }
1811
+ if (isPlus) {
1812
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
1813
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1814
+ return hasCoupon && fitWeight && !__plus;
1815
+ } else {
1816
+ return __plus;
1817
+ }
1818
+ }) || [];
1819
+ if (isPlus) {
1820
+ methods = methods.sort((a, b) => {
1821
+ if (b.__mode === "free" /* FREE */) return -1;
1822
+ return 0;
1823
+ });
1883
1824
  }
1884
- if (variant) {
1885
- const newOptions = optionsConstructor(variant.selectedOptions);
1886
- setOptions(newOptions);
1887
- }
1888
- }, [product, sku]);
1889
- return [options, setOptions];
1890
- }
1891
- function decodeShopifyId2(gid) {
1892
- try {
1893
- const parts = gid.split("/");
1894
- return parts[parts.length - 1] || gid;
1895
- } catch {
1896
- return gid;
1897
- }
1898
- }
1899
- function useProductUrl(otherQuery) {
1900
- const { routerAdapter } = useShopify();
1901
- return useCallback(
1902
- ({ product, variant }) => {
1903
- if (!product) return "";
1904
- const queryParams = new URLSearchParams();
1905
- if (variant?.id) {
1906
- const variantId = decodeShopifyId2(variant.id);
1907
- if (variantId) {
1908
- queryParams.set("variant", variantId);
1825
+ return methods.map((method) => {
1826
+ let price = 0;
1827
+ let coupon;
1828
+ let disabled;
1829
+ if (method.__mode !== "free" /* FREE */) {
1830
+ switch (method.__mode) {
1831
+ case "tdd":
1832
+ price = tddPrice;
1833
+ coupon = tddCoupon || nddCoupon;
1834
+ break;
1835
+ case "ndd":
1836
+ price = nddPrice;
1837
+ coupon = nddCoupon;
1838
+ break;
1839
+ }
1840
+ disabled = selectedPlusMemberMode === "free";
1841
+ if (method.__mode === "ndd" /* NDD */) {
1842
+ disabled = disabled || nddOverweight;
1843
+ } else if (method.__mode === "tdd" /* TDD */) {
1844
+ disabled = disabled || tddOverweight;
1909
1845
  }
1910
1846
  }
1911
- if (otherQuery) {
1912
- Object.entries(otherQuery).forEach(([key, value]) => {
1913
- queryParams.set(key, value);
1914
- });
1915
- }
1916
- const queryString = queryParams.toString();
1917
- const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
1918
- if (routerAdapter?.getLocalizedPath) {
1919
- return routerAdapter.getLocalizedPath(path);
1847
+ return {
1848
+ ...method,
1849
+ id: method.__mode + method.__code,
1850
+ useCoupon: true,
1851
+ disabled,
1852
+ coupon,
1853
+ price
1854
+ };
1855
+ });
1856
+ }, [
1857
+ variant?.weight,
1858
+ plus_shipping?.shipping_methods,
1859
+ isPlus,
1860
+ nddCoupon,
1861
+ tddCoupon,
1862
+ selectedPlusMemberMode,
1863
+ tddPrice,
1864
+ nddPrice,
1865
+ nddOverweight,
1866
+ tddOverweight
1867
+ ]);
1868
+ return {
1869
+ freeShippingMethods,
1870
+ paymentShippingMethods,
1871
+ nddOverweight,
1872
+ tddOverweight,
1873
+ nddCoupon,
1874
+ tddCoupon,
1875
+ isLoadingCoupon: isLoading
1876
+ };
1877
+ }
1878
+ var useReplaceCartPlusMember = () => {
1879
+ const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
1880
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1881
+ const { cart } = useCartContext();
1882
+ const plusMonthly = plusMemberMetafields?.plus_monthly_product;
1883
+ const plusAnnual = plusMemberMetafields?.plus_annual_product;
1884
+ const handler = useCallback(async () => {
1885
+ const plusMonthlyInCart = cart?.lineItems.find(
1886
+ (item) => item.variant?.sku === plusMonthly?.sku
1887
+ );
1888
+ const plusAnnualInCart = cart?.lineItems.find(
1889
+ (item) => item.variant?.sku === plusAnnual?.sku
1890
+ );
1891
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
1892
+ await removeCartLines2({
1893
+ lineIds: [plusMonthlyInCart.id]
1894
+ });
1895
+ } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
1896
+ await removeCartLines2({
1897
+ lineIds: [plusAnnualInCart.id]
1898
+ });
1899
+ }
1900
+ }, [
1901
+ cart?.lineItems,
1902
+ selectedPlusMemberMode,
1903
+ plusMonthly?.sku,
1904
+ plusAnnual?.sku,
1905
+ removeCartLines2
1906
+ ]);
1907
+ return handler;
1908
+ };
1909
+ var usePlusMemberCheckoutCustomAttributes = ({
1910
+ disableShipping = false,
1911
+ isPresaleContains = false
1912
+ }) => {
1913
+ const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
1914
+ return useMemo(() => {
1915
+ const checkoutCustomAttributes = [
1916
+ {
1917
+ key: "_last_url",
1918
+ value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
1920
1919
  }
1921
- return path;
1920
+ ];
1921
+ checkoutCustomAttributes.push({
1922
+ key: "_checkout_delivery_custom",
1923
+ value: JSON.stringify({
1924
+ allow_nextday_delivery: true,
1925
+ allow_thirdday_delivery: true,
1926
+ selected_delivery_option: {
1927
+ code: selectedShippingMethod?.__code,
1928
+ mode: selectedShippingMethod?.__mode
1929
+ },
1930
+ is_presale: isPresaleContains,
1931
+ discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
1932
+ plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
1933
+ is_prime: profile?.isPlus
1934
+ })
1935
+ });
1936
+ if (disableShipping) {
1937
+ checkoutCustomAttributes.push({
1938
+ key: "_hide_shipping",
1939
+ value: "true"
1940
+ });
1941
+ }
1942
+ return checkoutCustomAttributes;
1943
+ }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1944
+ };
1945
+ function useRemoveCartLines(options) {
1946
+ const { client, locale, cartCookieAdapter } = useShopify();
1947
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1948
+ const removeLines = useCallback(
1949
+ async (_key, { arg }) => {
1950
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1951
+ let updatedCart = await removeCartLines(client, {
1952
+ cartId,
1953
+ lineIds,
1954
+ metafieldIdentifiers,
1955
+ cookieAdapter: cartCookieAdapter
1956
+ });
1957
+ if (updatedCart && autoRemoveInvalidCodes) {
1958
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1959
+ if (unApplicableCodes.length > 0) {
1960
+ if (onCodesRemoved) {
1961
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1962
+ if (handledCart) {
1963
+ updatedCart = handledCart;
1964
+ }
1965
+ } else {
1966
+ updatedCart = await updateCartCodes(client, {
1967
+ cartId: updatedCart.id,
1968
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1969
+ metafieldIdentifiers,
1970
+ cookieAdapter: cartCookieAdapter
1971
+ }) || updatedCart;
1972
+ }
1973
+ }
1974
+ }
1975
+ if (updatedCart) {
1976
+ mutateCart(updatedCart);
1977
+ }
1978
+ return updatedCart;
1922
1979
  },
1923
- [routerAdapter, otherQuery]
1980
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1924
1981
  );
1982
+ return useSWRMutation("remove-cart-lines", removeLines, options);
1925
1983
  }
1926
- function decodeShopifyId3(gid) {
1927
- try {
1928
- const parts = gid.split("/");
1929
- return parts[parts.length - 1] || gid;
1930
- } catch {
1931
- return gid;
1932
- }
1933
- }
1934
- function useUpdateVariantQuery(variant) {
1984
+
1985
+ // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1986
+ function useAutoRemovePlusMemberInCart({
1987
+ cart,
1988
+ profile,
1989
+ memberSetting
1990
+ }) {
1991
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1992
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1935
1993
  useEffect(() => {
1936
- if (!variant || typeof window === "undefined") {
1937
- return;
1994
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
1995
+ const removePlusProduct = async (productType) => {
1996
+ if (!productType) return;
1997
+ const product = cart.lineItems?.find(
1998
+ (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
1999
+ );
2000
+ if (product) {
2001
+ await removeCartLines2({
2002
+ lineIds: [product.id]
2003
+ });
2004
+ }
2005
+ };
2006
+ if (profile?.isMonthlyPlus) {
2007
+ removePlusProduct(plus_monthly_product);
1938
2008
  }
1939
- const searchParams = new URLSearchParams(window.location.search);
1940
- const currentVariantId = searchParams.get("variant");
1941
- const newVariantId = decodeShopifyId3(variant.id);
1942
- if (newVariantId && currentVariantId !== newVariantId) {
1943
- searchParams.set("variant", newVariantId);
1944
- const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
1945
- window.history.replaceState({}, "", newUrl);
2009
+ if (profile?.isAnnualPlus) {
2010
+ removePlusProduct(plus_annual_product);
1946
2011
  }
1947
- }, [variant]);
2012
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
1948
2013
  }
1949
- function getVariantMediaList({
1950
- product,
1951
- variant
2014
+ function hasPlusMemberInCart({
2015
+ memberSetting,
2016
+ cart
1952
2017
  }) {
1953
- if (variant.image?.url) {
1954
- const variantMediaId = variant.image.url;
1955
- const variantMedia = product.media.filter((media) => {
1956
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
1957
- return media.previewImage?.url === variantMediaId;
1958
- }
1959
- return false;
1960
- });
1961
- if (variantMedia.length > 0) {
1962
- const otherMedia = product.media.filter((media) => {
1963
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
1964
- return media.previewImage.url !== variantMediaId;
1965
- }
1966
- return true;
1967
- });
1968
- return [...variantMedia, ...otherMedia];
1969
- }
2018
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2019
+ if (!cart?.lineItems) {
2020
+ return {
2021
+ hasPlusMember: false,
2022
+ hasMonthlyPlus: false,
2023
+ hasAnnualPlus: false
2024
+ };
1970
2025
  }
1971
- return product.media;
2026
+ const monthlyPlusItem = cart.lineItems.find(
2027
+ (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
2028
+ );
2029
+ const annualPlusItem = cart.lineItems.find(
2030
+ (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
2031
+ );
2032
+ const hasMonthlyPlus = !!monthlyPlusItem;
2033
+ const hasAnnualPlus = !!annualPlusItem;
2034
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
2035
+ return {
2036
+ hasPlusMember,
2037
+ hasMonthlyPlus,
2038
+ hasAnnualPlus,
2039
+ monthlyPlusItem,
2040
+ annualPlusItem
2041
+ };
1972
2042
  }
1973
- function useVariantMedia({
1974
- product,
1975
- variant
2043
+ function useHasPlusMemberInCart({
2044
+ memberSetting,
2045
+ cart
1976
2046
  }) {
1977
- const [imageList, setImageList] = useState([]);
1978
- const [sceneList, setSceneList] = useState([]);
1979
- const [videoList, setVideoList] = useState([]);
1980
- useEffect(() => {
1981
- if (!product || !variant) {
1982
- setImageList([]);
1983
- setSceneList([]);
1984
- setVideoList([]);
1985
- return;
1986
- }
1987
- const mediaList = getVariantMediaList({ product, variant });
1988
- const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
1989
- const videos = mediaList.filter(
1990
- (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
1991
- );
1992
- setImageList(images.length > 0 && images[0] ? [images[0]] : []);
1993
- setSceneList(images.length > 1 ? images.slice(1) : []);
1994
- setVideoList(videos);
1995
- }, [product, variant]);
2047
+ return useMemo(
2048
+ () => hasPlusMemberInCart({
2049
+ memberSetting,
2050
+ cart
2051
+ }),
2052
+ [memberSetting, cart]
2053
+ );
2054
+ }
2055
+ function hasPlusMemberInLines({
2056
+ memberSetting,
2057
+ lines
2058
+ }) {
2059
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2060
+ if (!lines || lines.length === 0) {
2061
+ return {
2062
+ hasPlusMember: false,
2063
+ hasMonthlyPlus: false,
2064
+ hasAnnualPlus: false
2065
+ };
2066
+ }
2067
+ const monthlyPlusLine = lines.find((line) => {
2068
+ const variantHandle = line.variant?.product?.handle;
2069
+ const variantSku = line.variant?.sku;
2070
+ return variantHandle === plus_monthly_product?.handle && variantSku === plus_monthly_product?.sku;
2071
+ });
2072
+ const annualPlusLine = lines.find((line) => {
2073
+ const variantHandle = line.variant?.product?.handle;
2074
+ const variantSku = line.variant?.sku;
2075
+ return variantHandle === plus_annual_product?.handle && variantSku === plus_annual_product?.sku;
2076
+ });
2077
+ const hasMonthlyPlus = !!monthlyPlusLine;
2078
+ const hasAnnualPlus = !!annualPlusLine;
2079
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1996
2080
  return {
1997
- productList: imageList,
1998
- sceneList,
1999
- videoList
2081
+ hasPlusMember,
2082
+ hasMonthlyPlus,
2083
+ hasAnnualPlus,
2084
+ monthlyPlusLine,
2085
+ annualPlusLine
2000
2086
  };
2001
2087
  }
2002
- function useCollection(options = {}) {
2003
- const { client, locale } = useShopify();
2004
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2005
- return useSWR(
2006
- handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2007
- () => getCollection(client, {
2008
- handle,
2009
- locale,
2010
- metafieldIdentifiers
2088
+ function useHasPlusMemberInLines({
2089
+ memberSetting,
2090
+ lines
2091
+ }) {
2092
+ return useMemo(
2093
+ () => hasPlusMemberInLines({
2094
+ memberSetting,
2095
+ lines
2011
2096
  }),
2012
- swrOptions
2097
+ [memberSetting, lines]
2013
2098
  );
2014
2099
  }
2015
- function useAllCollections(options = {}) {
2016
- const { client, locale } = useShopify();
2017
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2018
- return useSWR(
2019
- ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2020
- () => getAllCollections(client, {
2021
- locale,
2022
- first,
2023
- query,
2024
- sortKey,
2025
- reverse,
2026
- metafieldIdentifiers
2027
- }),
2028
- swrOptions
2029
- );
2030
- }
2031
- function useCollections(options = {}) {
2032
- const { client, locale } = useShopify();
2033
- const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2034
- return useSWR(
2035
- ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2036
- () => getCollections(client, {
2037
- locale,
2038
- first,
2039
- after,
2040
- query,
2041
- sortKey,
2042
- reverse,
2043
- metafieldIdentifiers
2044
- }),
2045
- swrOptions
2046
- );
2047
- }
2048
- function useBlog(options = {}) {
2049
- const { client, locale } = useShopify();
2050
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2051
- return useSWR(
2052
- handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2053
- () => getBlog(client, { handle, locale, metafieldIdentifiers }),
2054
- swrOptions
2055
- );
2056
- }
2057
- function useAllBlogs(options = {}) {
2058
- const { client, locale } = useShopify();
2059
- const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2060
- return useSWR(
2061
- ["all-blogs", locale, first, query, metafieldIdentifiers],
2062
- () => getAllBlogs(client, {
2063
- locale,
2064
- first,
2065
- query,
2066
- metafieldIdentifiers
2067
- }),
2068
- swrOptions
2069
- );
2070
- }
2071
- function useArticle(options = {}) {
2072
- const { client, locale } = useShopify();
2073
- const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2074
- return useSWR(
2075
- blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2076
- () => getArticle(client, {
2077
- blogHandle,
2078
- articleHandle,
2079
- locale,
2080
- metafieldIdentifiers
2081
- }),
2082
- swrOptions
2083
- );
2100
+ function usePlusMemberNeedAddToCart({
2101
+ cart,
2102
+ profile
2103
+ }) {
2104
+ const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
2105
+ const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2106
+ memberSetting: plusMemberMetafields,
2107
+ cart
2108
+ });
2109
+ const plusMemberVariant = useMemo(() => {
2110
+ if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
2111
+ return void 0;
2112
+ }
2113
+ if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2114
+ return void 0;
2115
+ }
2116
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2117
+ return void 0;
2118
+ }
2119
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2120
+ return void 0;
2121
+ }
2122
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2123
+ return void 0;
2124
+ }
2125
+ return selectedPlusMemberVariant;
2126
+ }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2127
+ return plusMemberVariant;
2084
2128
  }
2085
- function useArticles(options = {}) {
2086
- const { client, locale } = useShopify();
2087
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2088
- return useSWR(
2089
- ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2090
- () => getArticles(client, {
2091
- locale,
2092
- first,
2093
- query,
2094
- sortKey,
2095
- reverse,
2096
- metafieldIdentifiers
2097
- }),
2098
- swrOptions
2129
+ var PlusMemberProvider = ({
2130
+ variant,
2131
+ product,
2132
+ memberSetting,
2133
+ initialSelectedPlusMemberMode = "free",
2134
+ profile,
2135
+ children
2136
+ }) => {
2137
+ const [selectedPlusMemberMode, setSelectedPlusMemberMode] = useState(
2138
+ initialSelectedPlusMemberMode
2099
2139
  );
2100
- }
2101
- function useArticlesInBlog(options = {}) {
2102
- const { client, locale } = useShopify();
2103
- const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2104
- return useSWR(
2105
- blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2106
- () => getArticlesInBlog(client, {
2107
- blogHandle,
2108
- locale,
2109
- first,
2110
- sortKey,
2111
- reverse,
2112
- metafieldIdentifiers
2113
- }),
2114
- swrOptions
2140
+ const [selectedShippingMethod, setSelectedShippingMethod] = useState();
2141
+ const [showMoreShippingMethod, setShowMoreShippingMethod] = useState(false);
2142
+ const [showPlusMemberBenefit, setShowPlusMemberBenefit] = useState(false);
2143
+ const shippingMethodsContext = useShippingMethods({
2144
+ variant,
2145
+ plusMemberMetafields: memberSetting,
2146
+ selectedPlusMemberMode,
2147
+ profile
2148
+ });
2149
+ const { monthlyVariant, annualVariant } = usePlusMemberVariants({
2150
+ memberSetting
2151
+ });
2152
+ const selectedPlusMemberVariant = useMemo(() => {
2153
+ if (selectedPlusMemberMode === "free" /* FREE */) {
2154
+ return void 0;
2155
+ }
2156
+ return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
2157
+ }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
2158
+ return /* @__PURE__ */ jsx(
2159
+ PlusMemberContext.Provider,
2160
+ {
2161
+ value: {
2162
+ variant,
2163
+ plusMemberMetafields: memberSetting,
2164
+ selectedPlusMemberMode,
2165
+ setSelectedPlusMemberMode,
2166
+ selectedShippingMethod,
2167
+ setSelectedShippingMethod,
2168
+ shippingMethodsContext,
2169
+ showMoreShippingMethod,
2170
+ setShowMoreShippingMethod,
2171
+ selectedPlusMemberVariant,
2172
+ product,
2173
+ showPlusMemberBenefit,
2174
+ setShowPlusMemberBenefit,
2175
+ profile
2176
+ },
2177
+ children
2178
+ }
2115
2179
  );
2116
- }
2117
- async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2118
- if (!searchQuery) {
2119
- return void 0;
2120
- }
2121
- const query = (
2122
- /* GraphQL */
2123
- `
2124
- query search($query: String!, $first: Int!, $types: [SearchType!])
2125
- @inContext(language: $language) {
2126
- search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2127
- totalCount
2128
- edges {
2129
- node {
2130
- ... on Article {
2131
- __typename
2132
- id
2133
- handle
2134
- title
2135
- excerpt
2136
- image {
2137
- url
2138
- altText
2139
- }
2140
- }
2141
- ... on Page {
2142
- __typename
2143
- id
2144
- handle
2145
- title
2146
- }
2147
- ... on Product {
2148
- __typename
2149
- id
2150
- handle
2151
- title
2152
- description
2153
- featuredImage {
2154
- url
2155
- altText
2180
+ };
2181
+
2182
+ // src/hooks/cart/use-add-to-cart.ts
2183
+ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2184
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
2185
+ const { cart, addCustomAttributes, memberSetting, profile, customer } = useCartContext();
2186
+ const { trigger: applyCartCodes } = useApplyCartCodes();
2187
+ const { trigger: removeInvalidCodes } = useRemoveCartCodes();
2188
+ const { trigger: addCartLines2 } = useAddCartLines();
2189
+ const { trigger: createCart4 } = useCreateCart({
2190
+ updateCookie: true
2191
+ });
2192
+ const { hasPlusMember } = useHasPlusMemberInCart({
2193
+ memberSetting,
2194
+ cart
2195
+ });
2196
+ const { attributes: cartAttributes } = useCartAttributes({
2197
+ profile,
2198
+ customer,
2199
+ cart,
2200
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2201
+ });
2202
+ const addToCart = useCallback(
2203
+ async (_key, { arg }) => {
2204
+ const {
2205
+ lineItems,
2206
+ cartId: providedCartId,
2207
+ discountCodes,
2208
+ gtmParams = {},
2209
+ buyerIdentity,
2210
+ needCreateCart = false,
2211
+ onCodesInvalid,
2212
+ replaceExistingCodes,
2213
+ customAttributes
2214
+ } = arg;
2215
+ if (!lineItems || lineItems.length === 0) {
2216
+ return;
2217
+ }
2218
+ performanceAdapter?.addToCartStart();
2219
+ const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
2220
+ const lines = linesWithFunctionAttributes.map((item) => ({
2221
+ merchandiseId: item.variant?.id || "",
2222
+ quantity: item.quantity || 1,
2223
+ attributes: item.attributes,
2224
+ sellingPlanId: item.sellingPlanId
2225
+ })).filter((item) => item.merchandiseId && item.quantity);
2226
+ if (lines.length === 0) {
2227
+ return;
2228
+ }
2229
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
2230
+ let resultCart = null;
2231
+ if (!cartId) {
2232
+ resultCart = await createCart4({
2233
+ lines,
2234
+ buyerIdentity,
2235
+ discountCodes,
2236
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2237
+ // 初次加购时,就把所有 cart attributes 带上
2238
+ });
2239
+ } else {
2240
+ resultCart = await addCartLines2({
2241
+ cartId,
2242
+ lines
2243
+ });
2244
+ console.log("npm addCartLines resultCart", resultCart);
2245
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
2246
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
2247
+ if (unapplicableCodes.length > 0) {
2248
+ if (onCodesInvalid) {
2249
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
2250
+ if (handledCart) {
2251
+ resultCart = handledCart;
2156
2252
  }
2253
+ } else {
2254
+ await removeInvalidCodes({
2255
+ discountCodes: unapplicableCodes
2256
+ });
2157
2257
  }
2158
2258
  }
2159
2259
  }
2160
- pageInfo {
2161
- hasNextPage
2162
- endCursor
2260
+ if (resultCart && discountCodes && discountCodes.length > 0) {
2261
+ applyCartCodes({
2262
+ replaceExistingCodes,
2263
+ discountCodes
2264
+ });
2265
+ }
2266
+ if (customAttributes && customAttributes.length > 0) {
2267
+ addCustomAttributes(customAttributes);
2163
2268
  }
2164
2269
  }
2165
- }
2166
- `
2270
+ if (withTrack) {
2271
+ trackAddToCartGA({
2272
+ lineItems,
2273
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2274
+ });
2275
+ trackAddToCartFBQ({ lineItems });
2276
+ }
2277
+ performanceAdapter?.addToCartEnd();
2278
+ return resultCart;
2279
+ },
2280
+ [
2281
+ client,
2282
+ locale,
2283
+ cartCookieAdapter,
2284
+ userAdapter,
2285
+ cart,
2286
+ withTrack,
2287
+ performanceAdapter,
2288
+ createCart4,
2289
+ addCartLines2,
2290
+ applyCartCodes,
2291
+ removeInvalidCodes,
2292
+ addCustomAttributes,
2293
+ config
2294
+ ]
2167
2295
  );
2168
- const data = await client.query(query, {
2169
- query: searchQuery,
2170
- first,
2171
- types
2172
- });
2173
- if (!data || !data.search) {
2174
- return void 0;
2175
- }
2176
- const items = data.search.edges?.map((edge) => {
2177
- const node = edge.node;
2178
- const item = {
2179
- type: node.__typename.toUpperCase(),
2180
- id: node.id,
2181
- handle: node.handle,
2182
- title: node.title
2183
- };
2184
- if (node.__typename === "Product") {
2185
- item.description = node.description;
2186
- item.image = node.featuredImage ? {
2187
- url: node.featuredImage.url,
2188
- altText: node.featuredImage.altText
2189
- } : void 0;
2190
- } else if (node.__typename === "Article") {
2191
- item.description = node.excerpt;
2192
- item.image = node.image ? {
2193
- url: node.image.url,
2194
- altText: node.image.altText
2195
- } : void 0;
2196
- }
2197
- return item;
2198
- }) || [];
2199
- return {
2200
- items,
2201
- totalCount: data.search.totalCount || 0,
2202
- pageInfo: data.search.pageInfo
2203
- };
2296
+ return useSWRMutation("add-to-cart", addToCart, swrOptions);
2204
2297
  }
2205
- function useSearch(options = {}) {
2206
- const { client, locale } = useShopify();
2207
- const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2208
- return useSWR(
2209
- query ? ["search", locale, query, first, types] : null,
2210
- () => performSearch(client, locale, query, first, types),
2211
- swrOptions
2298
+ function useUpdateCartLines(options) {
2299
+ const { client, locale, cartCookieAdapter } = useShopify();
2300
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
2301
+ const updateLines = useCallback(
2302
+ async (_key, { arg }) => {
2303
+ const updatedCart = await updateCartLines(client, {
2304
+ ...arg,
2305
+ metafieldIdentifiers,
2306
+ cookieAdapter: cartCookieAdapter
2307
+ });
2308
+ if (updatedCart) {
2309
+ mutateCart(updatedCart);
2310
+ }
2311
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
2312
+ return updatedCart;
2313
+ },
2314
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2212
2315
  );
2316
+ return useSWRMutation("update-cart-lines", updateLines, options);
2213
2317
  }
2214
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
2215
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2216
- const query = (
2217
- /* GraphQL */
2218
- `
2219
- query getSiteInfo(
2220
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2221
- ) @inContext(language: $language) {
2222
- shop {
2223
- name
2224
- description
2225
- primaryDomain {
2226
- url
2227
- host
2318
+ function useUpdateCartAttributes({
2319
+ mutate,
2320
+ metafieldIdentifiers,
2321
+ disabled = false,
2322
+ swrOptions
2323
+ }) {
2324
+ const { client, locale, cartCookieAdapter } = useShopify();
2325
+ const updateAttributes = useCallback(
2326
+ async (_key, { arg }) => {
2327
+ if (disabled) {
2328
+ return void 0;
2329
+ }
2330
+ const updatedCart = await updateCartAttributes(client, {
2331
+ ...arg,
2332
+ metafieldIdentifiers,
2333
+ cookieAdapter: cartCookieAdapter
2334
+ });
2335
+ if (updatedCart) {
2336
+ mutate(updatedCart);
2337
+ }
2338
+ return updatedCart;
2339
+ },
2340
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
2341
+ );
2342
+ return useSWRMutation("update-cart-attributes", updateAttributes, swrOptions);
2343
+ }
2344
+ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2345
+ const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2346
+ const { profile, customer, memberSetting } = useCartContext();
2347
+ const isLoggedIn = userAdapter?.isLoggedIn || false;
2348
+ const buyNow = useCallback(
2349
+ async (_key, { arg }) => {
2350
+ const {
2351
+ lineItems,
2352
+ discountCodes,
2353
+ gtmParams = {},
2354
+ buyerIdentity,
2355
+ fbqTrackConfig,
2356
+ customAttributes,
2357
+ metafieldIdentifiers,
2358
+ redirectToCheckout = true
2359
+ } = arg;
2360
+ if (!lineItems || lineItems.length === 0) {
2361
+ return;
2362
+ }
2363
+ const { hasPlusMember } = hasPlusMemberInLines({
2364
+ memberSetting,
2365
+ lines: lineItems
2366
+ });
2367
+ const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2368
+ const cartAttributes = getCartAttributes({
2369
+ profile,
2370
+ customer,
2371
+ memberType,
2372
+ currentUrl: window.location.href
2373
+ });
2374
+ const linesWithFunctionAttributes = getLinesWithAttributes({
2375
+ lineItems
2376
+ });
2377
+ const lines = linesWithFunctionAttributes.map((item) => ({
2378
+ merchandiseId: item.variant?.id || "",
2379
+ quantity: item.quantity || 1,
2380
+ attributes: item.attributes,
2381
+ sellingPlanId: item.sellingPlanId
2382
+ })).filter((item) => item.merchandiseId);
2383
+ if (lines.length === 0) {
2384
+ return;
2385
+ }
2386
+ const resultCart = await createCart(client, {
2387
+ lines,
2388
+ metafieldIdentifiers,
2389
+ cookieAdapter: cartCookieAdapter,
2390
+ buyerIdentity,
2391
+ discountCodes,
2392
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2393
+ });
2394
+ if (!resultCart) {
2395
+ throw new Error("Failed to create cart for buy now");
2396
+ }
2397
+ if (withTrack && resultCart.lineItems) {
2398
+ trackBuyNowGA({
2399
+ lineItems,
2400
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2401
+ });
2402
+ if (fbqTrackConfig) {
2403
+ trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
2228
2404
  }
2229
- brand {
2230
- logo {
2231
- image {
2232
- url
2233
- }
2234
- }
2235
- colors {
2236
- primary {
2237
- background
2238
- }
2239
- secondary {
2240
- background
2241
- }
2405
+ }
2406
+ if (redirectToCheckout) {
2407
+ if (resultCart.url) {
2408
+ if (typeof window !== "undefined") {
2409
+ window.location.href = resultCart.url;
2242
2410
  }
2411
+ } else {
2412
+ throw new Error("Failed to get checkout URL");
2243
2413
  }
2244
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2245
2414
  }
2246
- }
2247
- `
2415
+ return resultCart;
2416
+ },
2417
+ [client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
2248
2418
  );
2249
- const variables = {};
2250
- if (hasMetafields) {
2251
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2252
- }
2253
- const data = await client.query(query, variables);
2254
- if (!data || !data.shop) {
2255
- return void 0;
2256
- }
2257
- const shop = data.shop;
2258
- const metafields = shop.metafields?.reduce((acc, mf) => {
2259
- if (mf && mf.key) {
2260
- acc[mf.key] = mf.value;
2261
- }
2262
- return acc;
2263
- }, {});
2264
- return {
2265
- name: shop.name,
2266
- description: shop.description,
2267
- primaryDomain: shop.primaryDomain,
2268
- brand: shop.brand ? {
2269
- logo: shop.brand.logo,
2270
- colors: shop.brand.colors ? {
2271
- primary: shop.brand.colors.primary?.background,
2272
- secondary: shop.brand.colors.secondary?.background
2273
- } : void 0
2274
- } : void 0,
2275
- metafields
2276
- };
2419
+ return useSWRMutation("buy-now", buyNow, swrOptions);
2277
2420
  }
2278
- function useSite(options = {}) {
2421
+
2422
+ // src/hooks/cart/types/price-discount.ts
2423
+ var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
2424
+ PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
2425
+ PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
2426
+ return PriceDiscountType2;
2427
+ })(PriceDiscountType || {});
2428
+ var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
2429
+ PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
2430
+ PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
2431
+ return PriceBasePriceType2;
2432
+ })(PriceBasePriceType || {});
2433
+ function useProduct(options = {}) {
2279
2434
  const { client, locale } = useShopify();
2280
- const { metafieldIdentifiers, ...swrOptions } = options;
2435
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2281
2436
  return useSWR(
2282
- ["site", locale, metafieldIdentifiers],
2283
- () => getSiteInfo(client, locale, metafieldIdentifiers),
2437
+ handle ? ["product", locale, handle, metafieldIdentifiers] : null,
2438
+ () => getProduct(client, {
2439
+ handle,
2440
+ locale,
2441
+ metafieldIdentifiers
2442
+ }),
2284
2443
  swrOptions
2285
2444
  );
2286
2445
  }
2287
-
2288
- // src/hooks/member/plus/types.ts
2289
- var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
2290
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
2291
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
2292
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
2293
- return PLUS_MEMBER_TYPE2;
2294
- })(PLUS_MEMBER_TYPE || {});
2295
- var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
2296
- PlusMemberMode2["MONTHLY"] = "monthly";
2297
- PlusMemberMode2["ANNUAL"] = "annual";
2298
- return PlusMemberMode2;
2299
- })(PlusMemberMode || {});
2300
- var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
2301
- DeliveryPlusType2["FREE"] = "free";
2302
- DeliveryPlusType2["MONTHLY"] = "monthly";
2303
- DeliveryPlusType2["ANNUAL"] = "annual";
2304
- return DeliveryPlusType2;
2305
- })(DeliveryPlusType || {});
2306
- var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
2307
- ShippingMethodMode2["FREE"] = "free";
2308
- ShippingMethodMode2["TDD"] = "tdd";
2309
- ShippingMethodMode2["NDD"] = "ndd";
2310
- return ShippingMethodMode2;
2311
- })(ShippingMethodMode || {});
2312
- var createInitialValue = () => ({
2313
- zipCode: "",
2314
- plusMemberMetafields: {},
2315
- setZipCode: () => {
2316
- },
2317
- allowNextDayDelivery: false,
2318
- setAllowNextDayDelivery: () => {
2319
- },
2320
- allowThirdDayDelivery: false,
2321
- setAllowThirdDayDelivery: () => {
2322
- },
2323
- selectedPlusMemberMode: "free",
2324
- setSelectedPlusMemberMode: () => {
2325
- },
2326
- showAreaCheckModal: false,
2327
- setShowAreaCheckModal: () => {
2328
- },
2329
- selectedShippingMethod: void 0,
2330
- setSelectedShippingMethod: () => {
2331
- },
2332
- showTip: false,
2333
- setShowTip: () => {
2334
- },
2335
- showMoreShippingMethod: false,
2336
- setShowMoreShippingMethod: () => {
2337
- },
2338
- variant: {},
2339
- product: {},
2340
- shippingMethodsContext: {
2341
- freeShippingMethods: [],
2342
- paymentShippingMethods: [],
2343
- nddOverweight: false,
2344
- tddOverweight: false
2345
- },
2346
- selectedPlusMemberProduct: null,
2347
- plusMemberProducts: [],
2348
- showPlusMemberBenefit: false,
2349
- setShowPlusMemberBenefit: () => {
2350
- },
2351
- deleteMarginBottom: false,
2352
- setDeleteMarginBottom: () => {
2353
- },
2354
- profile: void 0,
2355
- locale: void 0
2356
- });
2357
- var PlusMemberContext = createContext(createInitialValue());
2358
- function usePlusMemberContext() {
2359
- return useContext(PlusMemberContext);
2360
- }
2361
- function usePlusMonthlyProductVariant() {
2362
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2363
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2364
- const plusMonthlyProductVariant = useMemo(() => {
2365
- const product = plusMemberProducts?.find(
2366
- (item) => item?.handle === plusMonthly?.handle
2367
- );
2368
- const productVariant = product?.variants?.find(
2369
- (item) => item.sku === plusMonthly?.sku
2370
- );
2371
- return productVariant;
2372
- }, [plusMemberProducts, plusMonthly]);
2373
- return plusMonthlyProductVariant;
2446
+ function useAllProducts(options = {}) {
2447
+ const { client, locale } = useShopify();
2448
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2449
+ return useSWR(
2450
+ ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2451
+ () => getAllProducts(client, {
2452
+ locale,
2453
+ first,
2454
+ query,
2455
+ sortKey,
2456
+ reverse,
2457
+ metafieldIdentifiers
2458
+ }),
2459
+ swrOptions
2460
+ );
2374
2461
  }
2375
- function usePlusAnnualProductVariant() {
2376
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2377
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2378
- const plusAnnualProductVariant = useMemo(() => {
2379
- const product = plusMemberProducts?.find(
2380
- (item) => item?.handle === plusAnnual?.handle
2381
- );
2382
- const productVariant = product?.variants?.find(
2383
- (item) => item.sku === plusAnnual?.sku
2384
- );
2385
- return productVariant;
2386
- }, [plusMemberProducts, plusAnnual]);
2387
- return plusAnnualProductVariant;
2462
+ function getFirstAvailableVariant(product) {
2463
+ const availableVariant = product.variants.find((v) => v.availableForSale);
2464
+ return availableVariant || product.variants[0];
2388
2465
  }
2389
- function useShippingMethods(options) {
2390
- const {
2391
- variant,
2392
- plusMemberMetafields,
2393
- selectedPlusMemberMode,
2394
- isPlus = false,
2395
- nddCoupon,
2396
- tddCoupon
2397
- } = options;
2398
- const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2399
- const nddOverweight = useMemo(() => {
2400
- return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
2401
- }, [shippingMethod?.overWeight_ndd, variant?.weight]);
2402
- const tddOverweight = useMemo(() => {
2403
- return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
2404
- }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2405
- const paymentShippingMethods = useMemo(() => {
2406
- const weight = variant?.weight || 0;
2407
- const methods = plus_shipping?.shipping_methods?.filter(
2408
- ({ weight_low, weight_high, __mode, __plus }) => {
2409
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2410
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2411
- }
2412
- ) || [];
2413
- return methods.map((method) => {
2414
- let disabled = false;
2415
- const selectedFreeMember = selectedPlusMemberMode === "free";
2416
- if (method.__mode === "ndd" /* NDD */) {
2417
- disabled = selectedFreeMember || nddOverweight;
2418
- } else if (method.__mode === "tdd" /* TDD */) {
2419
- disabled = selectedFreeMember || tddOverweight;
2420
- }
2421
- return {
2422
- ...method,
2423
- id: method.__mode + method.__code,
2424
- useCoupon: false,
2425
- subtitle: plus_shipping?.directly || "",
2426
- disabled
2427
- };
2466
+ function getVariantFromSelectedOptions(product, selectedOptions) {
2467
+ return product.variants.find((variant) => {
2468
+ return variant.selectedOptions.every((option) => {
2469
+ return selectedOptions[option.name] === option.value;
2428
2470
  });
2429
- }, [
2430
- nddOverweight,
2431
- plus_shipping?.directly,
2432
- plus_shipping?.shipping_methods,
2433
- selectedPlusMemberMode,
2434
- tddOverweight,
2435
- variant?.weight
2436
- ]);
2437
- const nddPrice = useMemo(() => {
2438
- const weight = variant?.weight || 0;
2439
- const nddMethod = paymentShippingMethods.find(
2440
- ({ __mode, weight_high, weight_low }) => {
2441
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2442
- return __mode === "ndd" && fitWeight;
2443
- }
2444
- );
2445
- return nddMethod?.price || 0;
2446
- }, [variant?.weight, paymentShippingMethods]);
2447
- const tddPrice = useMemo(() => {
2448
- const weight = variant?.weight || 0;
2449
- const tddMethod = paymentShippingMethods.find(
2450
- ({ __mode, weight_high, weight_low }) => {
2451
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2452
- return __mode === "tdd" && fitWeight;
2453
- }
2454
- );
2455
- return tddMethod?.price || 0;
2456
- }, [variant?.weight, paymentShippingMethods]);
2457
- const freeShippingMethods = useMemo(() => {
2458
- const weight = variant?.weight || 0;
2459
- let methods = plus_shipping?.shipping_methods?.filter(
2460
- ({ __mode, __plus, weight_low, weight_high }) => {
2461
- if (__mode === "free" /* FREE */) {
2462
- return true;
2463
- }
2464
- if (isPlus) {
2465
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2466
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2467
- return hasCoupon && fitWeight && !__plus;
2468
- } else {
2469
- return __plus;
2470
- }
2471
- }
2472
- ) || [];
2473
- if (isPlus) {
2474
- methods = methods.sort((a, b) => {
2475
- if (b.__mode === "free" /* FREE */) return -1;
2476
- return 0;
2477
- });
2471
+ });
2472
+ }
2473
+ function useVariant({
2474
+ product,
2475
+ selectedOptions
2476
+ }) {
2477
+ const [variant, setVariant] = useState(
2478
+ product ? getFirstAvailableVariant(product) : void 0
2479
+ );
2480
+ useEffect(() => {
2481
+ if (!product) {
2482
+ setVariant(void 0);
2483
+ return;
2484
+ }
2485
+ const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
2486
+ if (newVariant && newVariant.id !== variant?.id) {
2487
+ setVariant(newVariant);
2488
+ } else if (!newVariant) {
2489
+ setVariant(getFirstAvailableVariant(product));
2490
+ }
2491
+ }, [selectedOptions, product, variant?.id]);
2492
+ return variant;
2493
+ }
2494
+ var FAKE_PRICE = 999999999e-2;
2495
+ function formatPrice({
2496
+ amount,
2497
+ currencyCode,
2498
+ locale,
2499
+ maximumFractionDigits,
2500
+ minimumFractionDigits,
2501
+ removeTrailingZeros
2502
+ }) {
2503
+ const formatter = new Intl.NumberFormat(locale, {
2504
+ style: "currency",
2505
+ currency: currencyCode,
2506
+ maximumFractionDigits: maximumFractionDigits ?? 2,
2507
+ minimumFractionDigits: minimumFractionDigits ?? 2
2508
+ });
2509
+ let formatted = formatter.format(amount);
2510
+ if (removeTrailingZeros) {
2511
+ formatted = formatted.replace(/\.00$/, "");
2512
+ }
2513
+ return formatted;
2514
+ }
2515
+ function formatVariantPrice({
2516
+ amount,
2517
+ baseAmount,
2518
+ currencyCode,
2519
+ locale,
2520
+ maximumFractionDigits,
2521
+ minimumFractionDigits,
2522
+ removeTrailingZeros
2523
+ }) {
2524
+ return {
2525
+ price: formatPrice({
2526
+ amount,
2527
+ currencyCode,
2528
+ locale,
2529
+ maximumFractionDigits,
2530
+ minimumFractionDigits,
2531
+ removeTrailingZeros
2532
+ }),
2533
+ basePrice: formatPrice({
2534
+ amount: baseAmount,
2535
+ currencyCode,
2536
+ locale,
2537
+ maximumFractionDigits,
2538
+ minimumFractionDigits,
2539
+ removeTrailingZeros
2540
+ })
2541
+ };
2542
+ }
2543
+ function usePrice({
2544
+ amount,
2545
+ baseAmount,
2546
+ currencyCode,
2547
+ soldOutDescription = "",
2548
+ maximumFractionDigits,
2549
+ minimumFractionDigits,
2550
+ removeTrailingZeros
2551
+ }) {
2552
+ const { locale } = useShopify();
2553
+ const value = useMemo(() => {
2554
+ if (typeof amount !== "number" || !currencyCode) {
2555
+ return "";
2478
2556
  }
2479
- return methods.map((method) => {
2480
- let price = 0;
2481
- let coupon;
2482
- let disabled;
2483
- if (method.__mode !== "free" /* FREE */) {
2484
- switch (method.__mode) {
2485
- case "tdd":
2486
- price = tddPrice;
2487
- coupon = tddCoupon || nddCoupon;
2488
- break;
2489
- case "ndd":
2490
- price = nddPrice;
2491
- coupon = nddCoupon;
2492
- break;
2493
- }
2494
- disabled = selectedPlusMemberMode === "free";
2495
- if (method.__mode === "ndd" /* NDD */) {
2496
- disabled = disabled || nddOverweight;
2497
- } else if (method.__mode === "tdd" /* TDD */) {
2498
- disabled = disabled || tddOverweight;
2499
- }
2500
- }
2501
- return {
2502
- ...method,
2503
- id: method.__mode + method.__code,
2504
- useCoupon: true,
2505
- disabled,
2506
- coupon,
2507
- price
2508
- };
2557
+ if (soldOutDescription && amount >= FAKE_PRICE) {
2558
+ return soldOutDescription;
2559
+ }
2560
+ return baseAmount ? formatVariantPrice({
2561
+ amount,
2562
+ baseAmount,
2563
+ currencyCode,
2564
+ locale,
2565
+ maximumFractionDigits,
2566
+ minimumFractionDigits,
2567
+ removeTrailingZeros
2568
+ }) : formatPrice({
2569
+ amount,
2570
+ currencyCode,
2571
+ locale,
2572
+ maximumFractionDigits,
2573
+ minimumFractionDigits,
2574
+ removeTrailingZeros
2509
2575
  });
2510
2576
  }, [
2511
- variant?.weight,
2512
- plus_shipping?.shipping_methods,
2513
- isPlus,
2514
- nddCoupon,
2515
- tddCoupon,
2516
- selectedPlusMemberMode,
2517
- tddPrice,
2518
- nddPrice,
2519
- nddOverweight,
2520
- tddOverweight
2577
+ amount,
2578
+ baseAmount,
2579
+ currencyCode,
2580
+ locale,
2581
+ maximumFractionDigits,
2582
+ minimumFractionDigits,
2583
+ soldOutDescription,
2584
+ removeTrailingZeros
2521
2585
  ]);
2522
- return {
2523
- freeShippingMethods,
2524
- paymentShippingMethods,
2525
- nddOverweight,
2526
- tddOverweight
2527
- };
2586
+ const result = useMemo(() => {
2587
+ const free = Boolean(amount && amount <= 0);
2588
+ return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
2589
+ }, [value, amount]);
2590
+ return result;
2528
2591
  }
2529
- function useShippingMethodAvailableCheck() {
2530
- const {
2531
- zipCode,
2532
- allowNextDayDelivery,
2533
- allowThirdDayDelivery,
2534
- selectedShippingMethod,
2535
- setSelectedShippingMethod,
2536
- setShowTip,
2537
- shippingMethodsContext
2538
- } = usePlusMemberContext();
2592
+ function optionsConstructor(selectedOptions) {
2593
+ return selectedOptions.reduce((acc, option) => {
2594
+ acc[option.name] = option.value;
2595
+ return acc;
2596
+ }, {});
2597
+ }
2598
+ function decodeShopifyId(gid) {
2599
+ try {
2600
+ const base64 = gid.split("/").pop() || "";
2601
+ return atob(base64);
2602
+ } catch {
2603
+ return gid;
2604
+ }
2605
+ }
2606
+ function useSelectedOptions(product, sku) {
2607
+ const [options, setOptions] = useState({});
2539
2608
  useEffect(() => {
2540
- const freeShippingMethod = shippingMethodsContext.freeShippingMethods[0];
2541
- const standardShippingMethod = shippingMethodsContext.freeShippingMethods?.find(
2542
- (item) => item.__mode === "free" /* FREE */
2543
- );
2544
- const freeTDD = shippingMethodsContext.freeShippingMethods.find(
2545
- (item) => item.__mode === "tdd" /* TDD */
2546
- );
2547
- const paymentTDD = shippingMethodsContext.paymentShippingMethods.find(
2548
- (item) => item.__mode === "tdd" /* TDD */
2549
- );
2550
- if (zipCode) {
2551
- console.log(
2552
- "allowNextDayDelivery, allowThirdDayDelivery:",
2553
- allowNextDayDelivery,
2554
- allowThirdDayDelivery
2555
- );
2556
- if (!allowNextDayDelivery && !allowThirdDayDelivery) {
2557
- setShowTip(true);
2558
- setSelectedShippingMethod(standardShippingMethod);
2559
- } else {
2560
- if (selectedShippingMethod?.__mode === "ndd" /* NDD */ && !allowNextDayDelivery) {
2561
- setShowTip(true);
2562
- if (allowThirdDayDelivery) {
2563
- if (selectedShippingMethod.useCoupon) {
2564
- const method = freeTDD || freeShippingMethod;
2565
- if (method) setSelectedShippingMethod(method);
2566
- } else {
2567
- const method = paymentTDD || freeShippingMethod;
2568
- if (method) setSelectedShippingMethod(method);
2569
- }
2570
- } else {
2571
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2572
- }
2573
- } else if (
2574
- // TDD 无法使用
2575
- selectedShippingMethod?.__mode === "tdd" /* TDD */ && !allowThirdDayDelivery
2576
- ) {
2577
- setShowTip(true);
2578
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2609
+ if (!product || !product.variants.length) {
2610
+ setOptions({});
2611
+ return;
2612
+ }
2613
+ let variant = product.variants[0];
2614
+ if (typeof window !== "undefined") {
2615
+ const searchParams = new URLSearchParams(window.location.search);
2616
+ const variantIdParam = searchParams.get("variant");
2617
+ if (variantIdParam) {
2618
+ const foundVariant = product.variants.find((v) => {
2619
+ if (sku) return v.sku === sku;
2620
+ return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
2621
+ });
2622
+ if (foundVariant) {
2623
+ variant = foundVariant;
2579
2624
  }
2580
2625
  }
2581
2626
  }
2582
- }, [
2583
- allowNextDayDelivery,
2584
- allowThirdDayDelivery,
2585
- zipCode,
2586
- shippingMethodsContext,
2587
- selectedShippingMethod,
2588
- setSelectedShippingMethod,
2589
- setShowTip
2590
- ]);
2591
- }
2592
- var useReplaceCartPlusMember = () => {
2593
- const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
2594
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2595
- const { cart } = useCartContext();
2596
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2597
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2598
- const handler = useCallback(async () => {
2599
- const plusMonthlyInCart = cart?.lineItems.find(
2600
- (item) => item.variant?.sku === plusMonthly?.sku
2601
- );
2602
- const plusAnnualInCart = cart?.lineItems.find(
2603
- (item) => item.variant?.sku === plusAnnual?.sku
2604
- );
2605
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
2606
- await removeCartLines2({
2607
- lineIds: [plusMonthlyInCart.id]
2608
- });
2609
- } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
2610
- await removeCartLines2({
2611
- lineIds: [plusAnnualInCart.id]
2612
- });
2627
+ if (variant) {
2628
+ const newOptions = optionsConstructor(variant.selectedOptions);
2629
+ setOptions(newOptions);
2613
2630
  }
2614
- }, [
2615
- cart?.lineItems,
2616
- selectedPlusMemberMode,
2617
- plusMonthly?.sku,
2618
- plusAnnual?.sku,
2619
- removeCartLines2
2620
- ]);
2621
- return handler;
2622
- };
2623
- var usePlusMemberDeliveryCodes = ({
2624
- deliveryData
2625
- }) => {
2626
- return useMemo(
2627
- () => deliveryData?.deliveryCustomData?.discount_code,
2628
- [deliveryData]
2629
- );
2630
- };
2631
- function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2632
- const { client, locale, cartCookieAdapter } = useShopify();
2633
- const updateDeliveryOptions = useCallback(
2634
- async (_key, { arg }) => {
2635
- const updatedCart = await updateCartDeliveryOptions(client, {
2636
- ...arg,
2637
- metafieldIdentifiers,
2638
- cookieAdapter: cartCookieAdapter
2639
- });
2640
- console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2641
- if (updatedCart) {
2642
- mutate(updatedCart);
2631
+ }, [product, sku]);
2632
+ return [options, setOptions];
2633
+ }
2634
+ function decodeShopifyId2(gid) {
2635
+ try {
2636
+ const parts = gid.split("/");
2637
+ return parts[parts.length - 1] || gid;
2638
+ } catch {
2639
+ return gid;
2640
+ }
2641
+ }
2642
+ function useProductUrl(otherQuery) {
2643
+ const { routerAdapter } = useShopify();
2644
+ return useCallback(
2645
+ ({ product, variant }) => {
2646
+ if (!product) return "";
2647
+ const queryParams = new URLSearchParams();
2648
+ if (variant?.id) {
2649
+ const variantId = decodeShopifyId2(variant.id);
2650
+ if (variantId) {
2651
+ queryParams.set("variant", variantId);
2652
+ }
2653
+ }
2654
+ if (otherQuery) {
2655
+ Object.entries(otherQuery).forEach(([key, value]) => {
2656
+ queryParams.set(key, value);
2657
+ });
2658
+ }
2659
+ const queryString = queryParams.toString();
2660
+ const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
2661
+ if (routerAdapter?.getLocalizedPath) {
2662
+ return routerAdapter.getLocalizedPath(path);
2643
2663
  }
2644
- return updatedCart;
2664
+ return path;
2645
2665
  },
2646
- [client, locale, cartCookieAdapter, mutate]
2666
+ [routerAdapter, otherQuery]
2647
2667
  );
2648
- return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2649
2668
  }
2650
-
2651
- // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2652
- var useUpdatePlusMemberDeliveryOptions = ({
2653
- deliveryData,
2654
- options
2655
- }) => {
2656
- const { cart, mutateCart: mutate, metafieldIdentifiers } = useCartContext();
2657
- const { trigger: updateCartDeliveryOptions2, isMutating } = useUpdateCartDeliveryOptions(
2658
- mutate,
2659
- metafieldIdentifiers
2660
- );
2661
- const deliveryOptions = useMemo(() => {
2662
- const deliveryGroupId = cart?.deliveryGroups?.[0]?.id;
2663
- const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option;
2664
- if (!deliveryGroupId || !selectedOptionCode) {
2665
- return [];
2666
- }
2667
- const deliveryGroup = cart?.deliveryGroups?.find((group) => group?.id === deliveryGroupId);
2668
- const matchedOption = deliveryGroup?.deliveryOptions?.find(
2669
- (option) => option?.code === selectedOptionCode
2670
- );
2671
- if (!matchedOption?.handle) {
2672
- return [];
2673
- }
2674
- return [
2675
- {
2676
- deliveryGroupId,
2677
- deliveryOptionHandle: matchedOption.handle
2678
- }
2679
- ];
2680
- }, [deliveryData, cart]);
2681
- const handler = useCallback(async () => {
2682
- const updatedCart = await updateCartDeliveryOptions2({
2683
- selectedDeliveryOptions: deliveryOptions
2684
- });
2685
- if (updatedCart && mutate) {
2686
- mutate(updatedCart);
2669
+ function decodeShopifyId3(gid) {
2670
+ try {
2671
+ const parts = gid.split("/");
2672
+ return parts[parts.length - 1] || gid;
2673
+ } catch {
2674
+ return gid;
2675
+ }
2676
+ }
2677
+ function useUpdateVariantQuery(variant) {
2678
+ useEffect(() => {
2679
+ if (!variant || typeof window === "undefined") {
2680
+ return;
2687
2681
  }
2688
- return updatedCart;
2689
- }, [deliveryOptions, mutate, updateCartDeliveryOptions2]);
2690
- return useSWRMutation("update-cart-delivery-options", handler, options);
2691
- };
2692
- var usePlusMemberItemCustomAttributes = ({
2693
- deliveryData
2694
- }) => {
2695
- const { deliveryCustomData } = deliveryData || {};
2696
- return useMemo(() => {
2697
- const itemCustomAttributes = [];
2698
- if (deliveryCustomData?.is_presale) {
2699
- itemCustomAttributes.push({
2700
- key: "_is_presale",
2701
- value: "true"
2702
- });
2682
+ const searchParams = new URLSearchParams(window.location.search);
2683
+ const currentVariantId = searchParams.get("variant");
2684
+ const newVariantId = decodeShopifyId3(variant.id);
2685
+ if (newVariantId && currentVariantId !== newVariantId) {
2686
+ searchParams.set("variant", newVariantId);
2687
+ const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
2688
+ window.history.replaceState({}, "", newUrl);
2703
2689
  }
2704
- return itemCustomAttributes;
2705
- }, [deliveryCustomData]);
2706
- };
2707
- var usePlusMemberCheckoutCustomAttributes = ({
2708
- deliveryData,
2690
+ }, [variant]);
2691
+ }
2692
+ function getVariantMediaList({
2709
2693
  product,
2710
- variant,
2711
- customer,
2712
- isShowShippingBenefits
2713
- }) => {
2714
- const { deliveryCustomData } = deliveryData || {};
2715
- const { profile } = usePlusMemberContext();
2716
- const userType = useMemo(() => {
2717
- const customerInfo = customer;
2718
- if (!customerInfo) {
2719
- return "new_user_unlogin";
2720
- }
2721
- if (customer) {
2722
- const { orders = {} } = customer;
2723
- const edgesLength = orders?.edges?.length;
2724
- if (edgesLength === 1) {
2725
- return "old_user_orders_once";
2726
- } else if (edgesLength && edgesLength > 1) {
2727
- return "old_user_orders_twice";
2728
- }
2729
- }
2730
- return "new_user_login";
2731
- }, [customer]);
2732
- return useMemo(() => {
2733
- const checkoutCustomAttributes = [
2734
- {
2735
- key: "_token",
2736
- value: profile?.token || ""
2737
- },
2738
- {
2739
- key: "_last_url",
2740
- value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2741
- },
2742
- {
2743
- key: "_user_type",
2744
- value: userType
2694
+ variant
2695
+ }) {
2696
+ if (variant.image?.url) {
2697
+ const variantMediaId = variant.image.url;
2698
+ const variantMedia = product.media.filter((media) => {
2699
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2700
+ return media.previewImage?.url === variantMediaId;
2745
2701
  }
2746
- ];
2747
- if (profile) {
2748
- checkoutCustomAttributes.push({
2749
- key: "_login_user",
2750
- value: "1"
2751
- });
2752
- }
2753
- if (deliveryCustomData) {
2754
- checkoutCustomAttributes.push({
2755
- key: "_checkout_delivery_custom",
2756
- value: JSON.stringify({
2757
- ...deliveryCustomData,
2758
- is_prime: profile?.isPlus
2759
- })
2760
- });
2761
- }
2762
- if (variant?.metafields?.presell) {
2763
- checkoutCustomAttributes.push({
2764
- key: "_presale",
2765
- value: "true"
2766
- });
2767
- }
2768
- if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2769
- checkoutCustomAttributes.push({
2770
- key: "_hide_shipping",
2771
- value: "true"
2702
+ return false;
2703
+ });
2704
+ if (variantMedia.length > 0) {
2705
+ const otherMedia = product.media.filter((media) => {
2706
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2707
+ return media.previewImage.url !== variantMediaId;
2708
+ }
2709
+ return true;
2772
2710
  });
2711
+ return [...variantMedia, ...otherMedia];
2773
2712
  }
2774
- return checkoutCustomAttributes;
2775
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2776
- };
2777
- function useAutoRemovePlusMemberInCart({
2778
- cart,
2779
- profile,
2780
- memberSetting
2713
+ }
2714
+ return product.media;
2715
+ }
2716
+ function useVariantMedia({
2717
+ product,
2718
+ variant
2781
2719
  }) {
2782
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2783
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2720
+ const [imageList, setImageList] = useState([]);
2721
+ const [sceneList, setSceneList] = useState([]);
2722
+ const [videoList, setVideoList] = useState([]);
2784
2723
  useEffect(() => {
2785
- if (!cart || !plus_monthly_product || !plus_annual_product) return;
2786
- const removePlusProduct = async (productType) => {
2787
- if (!productType) return;
2788
- const product = cart.lineItems?.find(
2789
- (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2790
- );
2791
- if (product) {
2792
- await removeCartLines2({
2793
- lineIds: [product.id]
2794
- });
2724
+ if (!product || !variant) {
2725
+ setImageList([]);
2726
+ setSceneList([]);
2727
+ setVideoList([]);
2728
+ return;
2729
+ }
2730
+ const mediaList = getVariantMediaList({ product, variant });
2731
+ const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
2732
+ const videos = mediaList.filter(
2733
+ (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
2734
+ );
2735
+ setImageList(images.length > 0 && images[0] ? [images[0]] : []);
2736
+ setSceneList(images.length > 1 ? images.slice(1) : []);
2737
+ setVideoList(videos);
2738
+ }, [product, variant]);
2739
+ return {
2740
+ productList: imageList,
2741
+ sceneList,
2742
+ videoList
2743
+ };
2744
+ }
2745
+ function useCollection(options = {}) {
2746
+ const { client, locale } = useShopify();
2747
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2748
+ return useSWR(
2749
+ handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2750
+ () => getCollection(client, {
2751
+ handle,
2752
+ locale,
2753
+ metafieldIdentifiers
2754
+ }),
2755
+ swrOptions
2756
+ );
2757
+ }
2758
+ function useAllCollections(options = {}) {
2759
+ const { client, locale } = useShopify();
2760
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2761
+ return useSWR(
2762
+ ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2763
+ () => getAllCollections(client, {
2764
+ locale,
2765
+ first,
2766
+ query,
2767
+ sortKey,
2768
+ reverse,
2769
+ metafieldIdentifiers
2770
+ }),
2771
+ swrOptions
2772
+ );
2773
+ }
2774
+ function useCollections(options = {}) {
2775
+ const { client, locale } = useShopify();
2776
+ const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2777
+ return useSWR(
2778
+ ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2779
+ () => getCollections(client, {
2780
+ locale,
2781
+ first,
2782
+ after,
2783
+ query,
2784
+ sortKey,
2785
+ reverse,
2786
+ metafieldIdentifiers
2787
+ }),
2788
+ swrOptions
2789
+ );
2790
+ }
2791
+ function useBlog(options = {}) {
2792
+ const { client, locale } = useShopify();
2793
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2794
+ return useSWR(
2795
+ handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2796
+ () => getBlog(client, { handle, locale, metafieldIdentifiers }),
2797
+ swrOptions
2798
+ );
2799
+ }
2800
+ function useAllBlogs(options = {}) {
2801
+ const { client, locale } = useShopify();
2802
+ const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2803
+ return useSWR(
2804
+ ["all-blogs", locale, first, query, metafieldIdentifiers],
2805
+ () => getAllBlogs(client, {
2806
+ locale,
2807
+ first,
2808
+ query,
2809
+ metafieldIdentifiers
2810
+ }),
2811
+ swrOptions
2812
+ );
2813
+ }
2814
+ function useArticle(options = {}) {
2815
+ const { client, locale } = useShopify();
2816
+ const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2817
+ return useSWR(
2818
+ blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2819
+ () => getArticle(client, {
2820
+ blogHandle,
2821
+ articleHandle,
2822
+ locale,
2823
+ metafieldIdentifiers
2824
+ }),
2825
+ swrOptions
2826
+ );
2827
+ }
2828
+ function useArticles(options = {}) {
2829
+ const { client, locale } = useShopify();
2830
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2831
+ return useSWR(
2832
+ ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2833
+ () => getArticles(client, {
2834
+ locale,
2835
+ first,
2836
+ query,
2837
+ sortKey,
2838
+ reverse,
2839
+ metafieldIdentifiers
2840
+ }),
2841
+ swrOptions
2842
+ );
2843
+ }
2844
+ function useArticlesInBlog(options = {}) {
2845
+ const { client, locale } = useShopify();
2846
+ const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2847
+ return useSWR(
2848
+ blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2849
+ () => getArticlesInBlog(client, {
2850
+ blogHandle,
2851
+ locale,
2852
+ first,
2853
+ sortKey,
2854
+ reverse,
2855
+ metafieldIdentifiers
2856
+ }),
2857
+ swrOptions
2858
+ );
2859
+ }
2860
+ async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2861
+ if (!searchQuery) {
2862
+ return void 0;
2863
+ }
2864
+ const query = (
2865
+ /* GraphQL */
2866
+ `
2867
+ query search($query: String!, $first: Int!, $types: [SearchType!])
2868
+ @inContext(language: $language) {
2869
+ search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2870
+ totalCount
2871
+ edges {
2872
+ node {
2873
+ ... on Article {
2874
+ __typename
2875
+ id
2876
+ handle
2877
+ title
2878
+ excerpt
2879
+ image {
2880
+ url
2881
+ altText
2882
+ }
2883
+ }
2884
+ ... on Page {
2885
+ __typename
2886
+ id
2887
+ handle
2888
+ title
2889
+ }
2890
+ ... on Product {
2891
+ __typename
2892
+ id
2893
+ handle
2894
+ title
2895
+ description
2896
+ featuredImage {
2897
+ url
2898
+ altText
2899
+ }
2900
+ }
2901
+ }
2902
+ }
2903
+ pageInfo {
2904
+ hasNextPage
2905
+ endCursor
2906
+ }
2795
2907
  }
2796
- };
2797
- if (profile?.isMonthlyPlus) {
2798
- removePlusProduct(plus_monthly_product);
2799
- }
2800
- if (profile?.isAnnualPlus) {
2801
- removePlusProduct(plus_annual_product);
2802
2908
  }
2803
- }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2804
- }
2805
- function useAddPlusMemberProductsToCart({
2806
- cart,
2807
- profile
2808
- }) {
2809
- const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2810
- const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2811
- memberSetting: plusMemberMetafields,
2812
- cart
2909
+ `
2910
+ );
2911
+ const data = await client.query(query, {
2912
+ query: searchQuery,
2913
+ first,
2914
+ types
2813
2915
  });
2814
- const plusMemberProduct = useMemo(() => {
2815
- if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2816
- return void 0;
2817
- }
2818
- if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2819
- return void 0;
2820
- }
2821
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2822
- return void 0;
2823
- }
2824
- if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2825
- return void 0;
2826
- }
2827
- if (!profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2828
- return void 0;
2916
+ if (!data || !data.search) {
2917
+ return void 0;
2918
+ }
2919
+ const items = data.search.edges?.map((edge) => {
2920
+ const node = edge.node;
2921
+ const item = {
2922
+ type: node.__typename.toUpperCase(),
2923
+ id: node.id,
2924
+ handle: node.handle,
2925
+ title: node.title
2926
+ };
2927
+ if (node.__typename === "Product") {
2928
+ item.description = node.description;
2929
+ item.image = node.featuredImage ? {
2930
+ url: node.featuredImage.url,
2931
+ altText: node.featuredImage.altText
2932
+ } : void 0;
2933
+ } else if (node.__typename === "Article") {
2934
+ item.description = node.excerpt;
2935
+ item.image = node.image ? {
2936
+ url: node.image.url,
2937
+ altText: node.image.altText
2938
+ } : void 0;
2829
2939
  }
2830
- return selectedPlusMemberProduct;
2831
- }, [
2832
- selectedPlusMemberMode,
2833
- selectedPlusMemberProduct?.variant,
2834
- selectedPlusMemberProduct?.product,
2835
- hasMonthlyPlus,
2836
- hasAnnualPlus
2837
- ]);
2838
- return plusMemberProduct;
2940
+ return item;
2941
+ }) || [];
2942
+ return {
2943
+ items,
2944
+ totalCount: data.search.totalCount || 0,
2945
+ pageInfo: data.search.pageInfo
2946
+ };
2839
2947
  }
2840
- var PlusMemberProvider = ({
2841
- variant,
2842
- product,
2843
- memberSetting,
2844
- initialSelectedPlusMemberMode = "free",
2845
- profile,
2846
- locale,
2847
- children
2848
- }) => {
2849
- const [zipCode, setZipCode] = useState("");
2850
- const [showTip, setShowTip] = useState(false);
2851
- const [selectedPlusMemberMode, setSelectedPlusMemberMode] = useState(
2852
- initialSelectedPlusMemberMode
2948
+ function useSearch(options = {}) {
2949
+ const { client, locale } = useShopify();
2950
+ const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2951
+ return useSWR(
2952
+ query ? ["search", locale, query, first, types] : null,
2953
+ () => performSearch(client, locale, query, first, types),
2954
+ swrOptions
2853
2955
  );
2854
- const [selectedShippingMethod, setSelectedShippingMethod] = useState();
2855
- const [allowNextDayDelivery, setAllowNextDayDelivery] = useState(false);
2856
- const [allowThirdDayDelivery, setAllowThirdDayDelivery] = useState(false);
2857
- const [showAreaCheckModal, setShowAreaCheckModal] = useState(false);
2858
- const [showMoreShippingMethod, setShowMoreShippingMethod] = useState(false);
2859
- const [showPlusMemberBenefit, setShowPlusMemberBenefit] = useState(false);
2860
- const [deleteMarginBottom, setDeleteMarginBottom] = useState(false);
2861
- const shippingMethodsContext = useShippingMethods({
2862
- variant,
2863
- plusMemberMetafields: memberSetting,
2864
- selectedPlusMemberMode});
2865
- const plusMemberHandles = useMemo(() => {
2866
- return [
2867
- memberSetting?.plus_monthly_product?.handle,
2868
- memberSetting?.plus_annual_product?.handle
2869
- ].filter(Boolean);
2870
- }, [memberSetting]);
2871
- const { data: plusMemberProducts = [] } = useProductsByHandles({
2872
- handles: plusMemberHandles
2873
- });
2874
- const selectedPlusMemberProduct = useMemo(() => {
2875
- if (selectedPlusMemberMode === "free" /* FREE */) {
2876
- return null;
2956
+ }
2957
+ async function getSiteInfo(client, locale, metafieldIdentifiers) {
2958
+ const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2959
+ const query = (
2960
+ /* GraphQL */
2961
+ `
2962
+ query getSiteInfo(
2963
+ ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2964
+ ) @inContext(language: $language) {
2965
+ shop {
2966
+ name
2967
+ description
2968
+ primaryDomain {
2969
+ url
2970
+ host
2971
+ }
2972
+ brand {
2973
+ logo {
2974
+ image {
2975
+ url
2976
+ }
2977
+ }
2978
+ colors {
2979
+ primary {
2980
+ background
2981
+ }
2982
+ secondary {
2983
+ background
2984
+ }
2985
+ }
2986
+ }
2987
+ ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2988
+ }
2877
2989
  }
2878
- const handle = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.handle : memberSetting?.plus_annual_product?.handle;
2879
- const sku = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.sku : memberSetting?.plus_annual_product?.sku;
2880
- const product2 = plusMemberProducts?.find((p) => p.handle === handle);
2881
- const variant2 = product2?.variants?.find((v) => v.sku === sku);
2882
- return product2 && variant2 ? { product: product2, variant: variant2 } : null;
2883
- }, [plusMemberProducts, memberSetting, selectedPlusMemberMode]);
2884
- return /* @__PURE__ */ jsx(
2885
- PlusMemberContext.Provider,
2886
- {
2887
- value: {
2888
- variant,
2889
- zipCode,
2890
- setZipCode,
2891
- allowNextDayDelivery,
2892
- setAllowNextDayDelivery,
2893
- allowThirdDayDelivery,
2894
- setAllowThirdDayDelivery,
2895
- plusMemberMetafields: memberSetting,
2896
- selectedPlusMemberMode,
2897
- setSelectedPlusMemberMode,
2898
- showAreaCheckModal,
2899
- setShowAreaCheckModal,
2900
- selectedShippingMethod,
2901
- setSelectedShippingMethod,
2902
- shippingMethodsContext,
2903
- showTip,
2904
- setShowTip,
2905
- showMoreShippingMethod,
2906
- setShowMoreShippingMethod,
2907
- selectedPlusMemberProduct,
2908
- plusMemberProducts,
2909
- product,
2910
- showPlusMemberBenefit,
2911
- setShowPlusMemberBenefit,
2912
- deleteMarginBottom,
2913
- setDeleteMarginBottom,
2914
- profile,
2915
- locale
2916
- },
2917
- children
2990
+ `
2991
+ );
2992
+ const variables = {};
2993
+ if (hasMetafields) {
2994
+ variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2995
+ }
2996
+ const data = await client.query(query, variables);
2997
+ if (!data || !data.shop) {
2998
+ return void 0;
2999
+ }
3000
+ const shop = data.shop;
3001
+ const metafields = shop.metafields?.reduce((acc, mf) => {
3002
+ if (mf && mf.key) {
3003
+ acc[mf.key] = mf.value;
2918
3004
  }
3005
+ return acc;
3006
+ }, {});
3007
+ return {
3008
+ name: shop.name,
3009
+ description: shop.description,
3010
+ primaryDomain: shop.primaryDomain,
3011
+ brand: shop.brand ? {
3012
+ logo: shop.brand.logo,
3013
+ colors: shop.brand.colors ? {
3014
+ primary: shop.brand.colors.primary?.background,
3015
+ secondary: shop.brand.colors.secondary?.background
3016
+ } : void 0
3017
+ } : void 0,
3018
+ metafields
3019
+ };
3020
+ }
3021
+ function useSite(options = {}) {
3022
+ const { client, locale } = useShopify();
3023
+ const { metafieldIdentifiers, ...swrOptions } = options;
3024
+ return useSWR(
3025
+ ["site", locale, metafieldIdentifiers],
3026
+ () => getSiteInfo(client, locale, metafieldIdentifiers),
3027
+ swrOptions
2919
3028
  );
2920
- };
3029
+ }
2921
3030
  function useIntersection(targetRef, options) {
2922
3031
  const {
2923
3032
  callback,
@@ -3111,7 +3220,7 @@ function CartProvider({
3111
3220
  }) {
3112
3221
  const { client, cartCookieAdapter } = useShopify();
3113
3222
  const [customAttributes, setCustomAttributes] = useState([]);
3114
- const [customAttributesNeedDelete, setCustomAttributesNeedDelete] = useState(
3223
+ const [customAttributesNeedRemove, setCustomAttributesNeedRemove] = useState(
3115
3224
  []
3116
3225
  );
3117
3226
  const [isCodeChanging, setIsCodeChanging] = useState(false);
@@ -3139,15 +3248,34 @@ function CartProvider({
3139
3248
  refreshDeps: [locale]
3140
3249
  }
3141
3250
  );
3142
- const { trigger: updateAttributes } = useUpdateCartAttributes(mutateCart, metafieldIdentifiers);
3143
- const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
3251
+ const { trigger: updateAttributes } = useUpdateCartAttributes({
3252
+ mutate: mutateCart,
3253
+ metafieldIdentifiers,
3254
+ disabled: isCartLoading
3255
+ });
3256
+ const { hasPlusMember } = useHasPlusMemberInCart({
3257
+ memberSetting,
3258
+ cart
3259
+ });
3260
+ const { attributes: commonAttributes } = useCartAttributes({
3261
+ profile,
3262
+ customer,
3263
+ cart,
3264
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
3265
+ });
3144
3266
  useRequest(
3145
3267
  () => {
3146
- const newAttributes = [...attributes, ...customAttributes];
3147
- const needUpdate = cart && !checkAttributesUpdateNeeded(
3268
+ const filteredSameCommonAttributes = commonAttributes.filter(
3269
+ (attr) => !customAttributes.some((a) => a.key === attr.key)
3270
+ );
3271
+ const newAttributes = [
3272
+ ...filteredSameCommonAttributes,
3273
+ ...customAttributes
3274
+ ];
3275
+ const needUpdate = cart && checkAttributesUpdateNeeded(
3148
3276
  cart.customAttributes,
3149
3277
  newAttributes,
3150
- customAttributesNeedDelete
3278
+ customAttributesNeedRemove
3151
3279
  );
3152
3280
  if (needUpdate) {
3153
3281
  return updateAttributes({ attributes: newAttributes });
@@ -3160,44 +3288,39 @@ function CartProvider({
3160
3288
  // 1 秒内只触发最后一次更新
3161
3289
  throttleTrailing: true,
3162
3290
  throttleLeading: false,
3163
- refreshDeps: [attributes, customAttributes]
3291
+ refreshDeps: [commonAttributes, customAttributes, customAttributesNeedRemove]
3164
3292
  }
3165
3293
  );
3166
3294
  useUpdateLineCodeAmountAttributes({
3167
3295
  cart,
3168
3296
  mutateCart,
3169
3297
  isCartLoading: isCartLoading || isCodeChanging,
3170
- setLoadingState
3298
+ setLoadingState,
3299
+ metafieldIdentifiers
3171
3300
  });
3172
3301
  const removeCustomAttributes = useCallback(
3173
- (attributes2) => {
3174
- setCustomAttributesNeedDelete(attributes2);
3302
+ (attributes) => {
3303
+ setCustomAttributesNeedRemove(attributes);
3175
3304
  },
3176
- [setCustomAttributesNeedDelete]
3305
+ [setCustomAttributesNeedRemove]
3177
3306
  );
3178
3307
  const addCustomAttributes = useCallback(
3179
- (attributes2) => {
3180
- const sameAttributes = attributes2.filter(
3181
- (attr) => customAttributes.some((a) => a.key === attr.key)
3182
- );
3183
- if (sameAttributes.length) {
3184
- setCustomAttributes((prev) => {
3185
- const removedAttributes = prev.filter(
3186
- (attr) => !sameAttributes.some((a) => a.key === attr.key)
3187
- );
3188
- return [...removedAttributes, ...attributes2];
3189
- });
3190
- } else {
3191
- setCustomAttributes((prev) => [...prev, ...attributes2]);
3192
- }
3308
+ (attributes) => {
3309
+ setCustomAttributes((oldCustomAttributes) => {
3310
+ const filteredSameAttributes = oldCustomAttributes.filter(
3311
+ (attr) => !attributes.some((a) => a.key === attr.key)
3312
+ );
3313
+ return [...filteredSameAttributes, ...attributes];
3314
+ });
3193
3315
  },
3194
- [customAttributes]
3316
+ [setCustomAttributes]
3195
3317
  );
3196
3318
  const functionAutoFreeGiftResult = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer);
3197
3319
  const scriptAutoFreeGiftResult = useScriptAutoFreeGift({
3198
3320
  campaign: gradientGiftsConfig || null,
3199
3321
  _giveaway: CUSTOMER_SCRIPT_GIFT_KEY,
3200
- cart
3322
+ cart,
3323
+ profile
3201
3324
  });
3202
3325
  const formattedScriptGifts = useMemo(() => {
3203
3326
  return formatScriptAutoFreeGift({
@@ -3248,16 +3371,23 @@ function CartProvider({
3248
3371
  );
3249
3372
  return result;
3250
3373
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
3374
+ const totalQuantity = useMemo(() => {
3375
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
3376
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3377
+ return cartLinesCount + giftLinesCount;
3378
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
3251
3379
  const value = useMemo(
3252
3380
  () => ({
3381
+ totalQuantity,
3253
3382
  cart,
3254
3383
  isCartLoading,
3255
3384
  triggerFetch: fetchCart,
3256
3385
  mutateCart,
3257
3386
  addCustomAttributes,
3258
3387
  removeCustomAttributes,
3259
- setCustomAttributes,
3260
3388
  locale,
3389
+ profile,
3390
+ customer,
3261
3391
  isCodeChanging,
3262
3392
  setIsCodeChanging,
3263
3393
  autoFreeGiftConfig,
@@ -3273,10 +3403,12 @@ function CartProvider({
3273
3403
  scriptAutoFreeGiftResult,
3274
3404
  setScriptAutoFreeGift,
3275
3405
  giftNeedAddToCartLines,
3276
- metafieldIdentifiers
3406
+ metafieldIdentifiers,
3407
+ memberSetting
3277
3408
  }),
3278
3409
  [
3279
3410
  cart,
3411
+ totalQuantity,
3280
3412
  isCartLoading,
3281
3413
  fetchCart,
3282
3414
  mutateCart,
@@ -3296,19 +3428,22 @@ function CartProvider({
3296
3428
  scriptAutoFreeGiftResult,
3297
3429
  setScriptAutoFreeGift,
3298
3430
  giftNeedAddToCartLines,
3299
- metafieldIdentifiers
3431
+ metafieldIdentifiers,
3432
+ customer,
3433
+ profile,
3434
+ memberSetting
3300
3435
  ]
3301
3436
  );
3302
3437
  return /* @__PURE__ */ jsx(CartContext.Provider, { value, children });
3303
3438
  }
3304
- function useCartContext() {
3439
+ function useCartContext(options) {
3305
3440
  const context = useContext(CartContext);
3306
- if (!context) {
3441
+ if (!context && !options?.optional) {
3307
3442
  throw new Error("useCartContext must be used within a CartProvider");
3308
3443
  }
3309
3444
  return context;
3310
3445
  }
3311
3446
 
3312
- 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, useUpdatePlusMemberDeliveryOptions, useUpdateVariantQuery, useVariant, useVariantMedia };
3447
+ export { BrowserPerformanceAdapter, BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, CartProvider, DeliveryPlusType, MAIN_PRODUCT_CODE, MEMBER_PRICE_ATTRIBUTE_KEY, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, ShopifyContext, ShopifyProvider, SpendMoneyType, browserCartCookieAdapter, browserCookieAdapter, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, gaTrack, getCachedGeoLocation, getCartAttributes, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, getUserType, hasPlusMemberInCart, hasPlusMemberInLines, 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, useHasPlusMemberInLines, useIntersection, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberNeedAddToCart, usePlusMemberVariants, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethods, useShopify, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3313
3448
  //# sourceMappingURL=index.mjs.map
3314
3449
  //# sourceMappingURL=index.mjs.map