@anker-in/shopify-react 0.1.1-beta.8 → 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.
@@ -6,6 +6,7 @@ var shopifySdk = require('@anker-in/shopify-sdk');
6
6
  var Cookies5 = require('js-cookie');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var Decimal2 = require('decimal.js');
9
+ var shopifyCore = require('@anker-in/shopify-core');
9
10
  var useSWR = require('swr');
10
11
  var ahooks = require('ahooks');
11
12
 
@@ -69,6 +70,7 @@ var CUSTOMER_ATTRIBUTE_KEY = "_discounts_function_env";
69
70
  var CUSTOMER_SCRIPT_GIFT_KEY = "_giveaway_gradient_gifts";
70
71
  var CODE_AMOUNT_KEY = "_sku_code_money";
71
72
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
73
+ var MEMBER_PRICE_ATTRIBUTE_KEY = "_member_price";
72
74
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
73
75
 
74
76
  // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
@@ -77,9 +79,10 @@ function normalizeAddToCartLines(lines) {
77
79
  const variant = line.variant;
78
80
  const product = variant.product;
79
81
  const quantity = line.quantity || 1;
80
- const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
81
- const subtotalAmount = price * quantity;
82
- const totalAmount = subtotalAmount;
82
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
83
+ const finalPrice = variant.finalPrice?.amount === void 0 ? originalPrice : Number(variant.finalPrice?.amount);
84
+ const subtotalAmount = originalPrice * quantity;
85
+ const totalAmount = finalPrice * quantity;
83
86
  return {
84
87
  id: `temp-line-${index}-${variant.id}`,
85
88
  // Temporary ID for pre-cart lines
@@ -93,7 +96,7 @@ function normalizeAddToCartLines(lines) {
93
96
  customAttributes: line.attributes || [],
94
97
  variant: {
95
98
  id: variant.id,
96
- price,
99
+ price: finalPrice,
97
100
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
98
101
  sku: variant.sku || "",
99
102
  name: variant.title || "",
@@ -124,15 +127,16 @@ function createMockCartFromLines(lines, existingCart) {
124
127
  const normalizedLines = normalizeAddToCartLines(lines);
125
128
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
126
129
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
130
+ const currency = lines[0]?.variant?.price?.currencyCode;
127
131
  return {
128
132
  id: existingCart?.id || "temp-cart-id",
129
133
  customerId: existingCart?.customerId,
130
134
  email: existingCart?.email,
131
135
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
132
- currency: existingCart?.currency || { code: "USD" },
136
+ currency: existingCart?.currency || { code: currency },
133
137
  taxesIncluded: existingCart?.taxesIncluded,
134
138
  lineItems: normalizedLines,
135
- totallineItemsDiscount: 0,
139
+ totalLineItemsDiscount: 0,
136
140
  orderDiscounts: 0,
137
141
  lineItemsSubtotalPrice: subtotalPrice,
138
142
  subtotalPrice,
@@ -163,22 +167,12 @@ var getQuery = () => {
163
167
  }
164
168
  return theRequest;
165
169
  };
166
- function atobID(id) {
167
- if (id && typeof id === "string" && id.includes("/")) {
168
- return id.split("/").pop()?.split("?")?.shift();
169
- } else {
170
- return id;
171
- }
172
- }
173
- function btoaID(id, type = "ProductVariant") {
174
- return `gid://shopify/${type}/${id}`;
175
- }
176
170
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
177
171
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
178
172
  const matchedList = cartData?.lineItems?.filter((line) => {
179
173
  const { is_gift } = getDiscountEnvAttributeValue(line.customAttributes);
180
174
  return isAllStoreVariant ? !is_gift : variant_list?.find((item) => {
181
- return !is_gift && atobID(line.variantId) === item;
175
+ return !is_gift && shopifyCore.atobID(line.variantId) === item;
182
176
  });
183
177
  });
184
178
  return matchedList?.reduce((acc, line) => {
@@ -196,14 +190,6 @@ var getDiscountEnvAttributeValue = (attributes = []) => {
196
190
  const attr = attributes.find((attr2) => attr2.key === CUSTOMER_ATTRIBUTE_KEY);
197
191
  return safeParse(attr?.value ?? "") ?? {};
198
192
  };
199
- var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
200
- return oldAttributes.some((attr) => {
201
- const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
202
- return newAttr ? newAttr.value !== attr.value : true;
203
- }) || newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || customAttributesNeedRemove.some(
204
- (removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
205
- );
206
- };
207
193
  var containsAll = (source, requiredItems = []) => {
208
194
  if (!requiredItems?.length) return true;
209
195
  const sourceSet = new Set(source);
@@ -404,43 +390,29 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
404
390
  }
405
391
  return { activeCampaign: null, subtotal: 0 };
406
392
  }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
407
- const { qualifyingGift, nextTierGoal } = react.useMemo(() => {
393
+ const { qualifyingTier, nextTierGoal, actualThreshold, currentCurrency } = react.useMemo(() => {
408
394
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
409
- return { qualifyingGift: null, nextTierGoal: null };
395
+ return { qualifyingTier: null, nextTierGoal: null, actualThreshold: 0, currentCurrency: "" };
410
396
  }
411
397
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
412
- const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
413
- const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
414
- if (!qualifyingTier) {
415
- return { qualifyingGift: null, nextTierGoal: nextGoal || null };
416
- }
417
- const formattedGift = {
418
- tier: qualifyingTier,
419
- itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
420
- const giftProduct = reward?.variant_list?.[0];
421
- if (!giftProduct) return null;
422
- return {
423
- variant: {
424
- id: btoaID(giftProduct.variant_id),
425
- handle: giftProduct.handle,
426
- sku: giftProduct.sku
427
- },
428
- quantity: reward?.get_unit || 1,
429
- attributes: [
430
- {
431
- key: CUSTOMER_ATTRIBUTE_KEY,
432
- value: JSON.stringify({
433
- is_gift: true,
434
- rule_id: activeCampaign.rule_id,
435
- spend_sum_money: qualifyingTier.spend_sum_money
436
- })
437
- }
438
- ]
439
- };
440
- }).filter((item) => item !== null)
398
+ const currentCurrency2 = effectiveCart?.currency?.code || "";
399
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency2);
400
+ const getThresholdAmount = (tier) => {
401
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency2]?.value) {
402
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency2].value);
403
+ }
404
+ return Number(tier.spend_sum_money || 0);
441
405
  };
442
- return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
443
- }, [activeCampaign, subtotal]);
406
+ const qualifyingTier2 = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
407
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
408
+ const actualThreshold2 = qualifyingTier2 ? getThresholdAmount(qualifyingTier2) : 0;
409
+ return {
410
+ qualifyingTier: qualifyingTier2,
411
+ nextTierGoal: nextGoal || null,
412
+ actualThreshold: actualThreshold2,
413
+ currentCurrency: currentCurrency2
414
+ };
415
+ }, [activeCampaign, subtotal, effectiveCart]);
444
416
  const giftHandles = react.useMemo(() => {
445
417
  const giftVariant = autoFreeGiftConfig.map(
446
418
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -456,24 +428,82 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
456
428
  }
457
429
  return true;
458
430
  }, [giftHandles]);
459
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
460
- const res = await shopifySdk.getProductsByHandles(client, {
461
- handles: giftHandles,
462
- locale
463
- });
464
- const result = Array.isArray(res) ? res : [];
465
- giftProductsCache.current = {
466
- data: result,
467
- giftHandles: [...giftHandles]
468
- };
469
- return result;
470
- });
431
+ const { data: giftProductsResult } = useSWR__default.default(
432
+ shouldFetch ? giftHandles : null,
433
+ async () => {
434
+ const res = await shopifySdk.getProductsByHandles(client, {
435
+ handles: giftHandles,
436
+ locale
437
+ });
438
+ const result = Array.isArray(res) ? res : [];
439
+ giftProductsCache.current = {
440
+ data: result,
441
+ giftHandles: [...giftHandles]
442
+ };
443
+ return result;
444
+ },
445
+ {
446
+ revalidateOnFocus: false
447
+ }
448
+ );
471
449
  const finalGiftProductsResult = react.useMemo(() => {
472
450
  if (giftProductsCache.current && !shouldFetch) {
473
451
  return giftProductsCache.current.data || void 0;
474
452
  }
475
453
  return giftProductsResult;
476
454
  }, [giftProductsResult, shouldFetch]);
455
+ const qualifyingGift = react.useMemo(() => {
456
+ if (!qualifyingTier || !activeCampaign) {
457
+ return null;
458
+ }
459
+ const itemsToAdd = qualifyingTier.reward_list?.map((reward) => {
460
+ if (!reward.variant_list || reward.variant_list.length === 0) {
461
+ return null;
462
+ }
463
+ let selectedGiftProduct = null;
464
+ for (const giftVariant of reward.variant_list) {
465
+ const productInfo = finalGiftProductsResult?.find(
466
+ (p) => p.handle === giftVariant.handle
467
+ );
468
+ if (productInfo) {
469
+ const variantInfo = productInfo.variants?.find((v) => v.sku === giftVariant.sku);
470
+ if (variantInfo?.availableForSale) {
471
+ selectedGiftProduct = giftVariant;
472
+ break;
473
+ }
474
+ }
475
+ }
476
+ if (!selectedGiftProduct) {
477
+ selectedGiftProduct = reward.variant_list[0];
478
+ }
479
+ return {
480
+ variant: {
481
+ id: shopifyCore.btoaID(selectedGiftProduct.variant_id),
482
+ handle: selectedGiftProduct.handle,
483
+ sku: selectedGiftProduct.sku
484
+ },
485
+ quantity: reward?.get_unit || 1,
486
+ attributes: [
487
+ {
488
+ key: CUSTOMER_ATTRIBUTE_KEY,
489
+ value: JSON.stringify({
490
+ is_gift: true,
491
+ rule_id: activeCampaign.rule_id,
492
+ spend_sum_money: actualThreshold,
493
+ // 使用实际的门槛金额(多币种支持)
494
+ currency_code: currentCurrency
495
+ // 记录当前币种
496
+ })
497
+ }
498
+ ]
499
+ };
500
+ }).filter((item) => item !== null);
501
+ const formattedGift = {
502
+ tier: qualifyingTier,
503
+ itemsToAdd
504
+ };
505
+ return formattedGift;
506
+ }, [qualifyingTier, activeCampaign, finalGiftProductsResult, actualThreshold, currentCurrency]);
477
507
  return {
478
508
  qualifyingGift,
479
509
  nextTierGoal,
@@ -487,7 +517,8 @@ var useScriptAutoFreeGift = ({
487
517
  _giveaway,
488
518
  cart,
489
519
  locale: providedLocale,
490
- lines
520
+ lines,
521
+ profile
491
522
  }) => {
492
523
  const { client, locale: contextLocale } = useShopify();
493
524
  const locale = providedLocale || contextLocale;
@@ -511,8 +542,9 @@ var useScriptAutoFreeGift = ({
511
542
  const utmCampaign = Cookies5__default.default.get("utm_campaign") || query?.utm_campaign;
512
543
  if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
513
544
  return false;
545
+ if (campaign.requireLogin && !profile?.email) return false;
514
546
  return true;
515
- }, [campaign]);
547
+ }, [campaign, profile]);
516
548
  const [upgrade_multiple, upgrade_value] = react.useMemo(() => {
517
549
  let upgrade_multiple2 = 1;
518
550
  let upgrade_value2 = 0;
@@ -520,12 +552,14 @@ var useScriptAutoFreeGift = ({
520
552
  upgrade_multiple2 = 1.2;
521
553
  upgrade_value2 = 40;
522
554
  }
523
- effectiveCart?.lineItems?.forEach(({ customAttributes }) => {
524
- customAttributes?.forEach(({ key, value }) => {
525
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
526
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
527
- });
528
- });
555
+ effectiveCart?.lineItems?.forEach(
556
+ ({ customAttributes }) => {
557
+ customAttributes?.forEach(({ key, value }) => {
558
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
559
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
560
+ });
561
+ }
562
+ );
529
563
  return [upgrade_multiple2, upgrade_value2];
530
564
  }, [effectiveCart?.lineItems, points_subscribe]);
531
565
  const breakpoints = react.useMemo(() => {
@@ -590,18 +624,24 @@ var useScriptAutoFreeGift = ({
590
624
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
591
625
  return [currentLevel, nextLevel];
592
626
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
593
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
594
- const res = await shopifySdk.getProductsByHandles(client, {
595
- handles: giftHandles,
596
- locale
597
- });
598
- const result = Array.isArray(res) ? res : [];
599
- giftProductsCache.current = {
600
- data: result,
601
- giftHandles: [...giftHandles]
602
- };
603
- return result;
604
- });
627
+ const { data: giftProductsResult } = useSWR__default.default(
628
+ shouldFetch ? giftHandles : null,
629
+ async () => {
630
+ const res = await shopifySdk.getProductsByHandles(client, {
631
+ handles: giftHandles,
632
+ locale
633
+ });
634
+ const result = Array.isArray(res) ? res : [];
635
+ giftProductsCache.current = {
636
+ data: result,
637
+ giftHandles: [...giftHandles]
638
+ };
639
+ return result;
640
+ },
641
+ {
642
+ revalidateOnFocus: false
643
+ }
644
+ );
605
645
  const finalGiftProductsResult = react.useMemo(() => {
606
646
  if (giftProductsCache.current && !shouldFetch) {
607
647
  return giftProductsCache.current.data || void 0;
@@ -634,16 +674,19 @@ var useScriptAutoFreeGift = ({
634
674
  };
635
675
  };
636
676
  var CartContext = react.createContext(null);
637
- function useCartContext() {
677
+ function useCartContext(options) {
638
678
  const context = react.useContext(CartContext);
639
- if (!context) {
679
+ if (!context && true) {
640
680
  throw new Error("useCartContext must be used within a CartProvider");
641
681
  }
642
682
  return context;
643
683
  }
644
684
 
645
685
  // src/hooks/cart/use-create-cart.ts
646
- function useCreateCart(options) {
686
+ function useCreateCart({
687
+ updateCookie = false,
688
+ options
689
+ }) {
647
690
  const { client, locale, cartCookieAdapter } = useShopify();
648
691
  const { mutateCart, metafieldIdentifiers } = useCartContext();
649
692
  const createNewCart = react.useCallback(
@@ -651,7 +694,8 @@ function useCreateCart(options) {
651
694
  let newCart = await shopifySdk.createCart(client, {
652
695
  ...arg,
653
696
  metafieldIdentifiers,
654
- cookieAdapter: cartCookieAdapter
697
+ cookieAdapter: cartCookieAdapter,
698
+ updateCookie
655
699
  });
656
700
  if (newCart) {
657
701
  const unApplicableCodes = newCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
@@ -678,11 +722,23 @@ function useAddCartLines(options) {
678
722
  const { mutateCart, metafieldIdentifiers } = useCartContext();
679
723
  const addLines = react.useCallback(
680
724
  async (_key, { arg }) => {
681
- let updatedCart = await shopifySdk.addCartLines(client, {
682
- ...arg,
683
- metafieldIdentifiers,
684
- cookieAdapter: cartCookieAdapter
685
- });
725
+ const { cartId, lines } = arg;
726
+ const id = cartId || cartCookieAdapter?.getCartId(locale);
727
+ let updatedCart;
728
+ if (!id) {
729
+ updatedCart = await shopifySdk.createCart(client, {
730
+ lines,
731
+ metafieldIdentifiers,
732
+ cookieAdapter: cartCookieAdapter
733
+ });
734
+ } else {
735
+ updatedCart = await shopifySdk.addCartLines(client, {
736
+ cartId: id,
737
+ lines,
738
+ metafieldIdentifiers,
739
+ cookieAdapter: cartCookieAdapter
740
+ });
741
+ }
686
742
  if (updatedCart) {
687
743
  const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
688
744
  if (unApplicableCodes.length > 0) {
@@ -729,7 +785,7 @@ var trackAddToCartGA = ({
729
785
  const currencyCode = variant.product?.price?.currencyCode;
730
786
  const totalPrice = lineItems?.reduce(
731
787
  (prev, { variant: variant2 }) => prev.plus(
732
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
788
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
733
789
  ),
734
790
  new Decimal2__default.default(0)
735
791
  ).toNumber();
@@ -762,10 +818,10 @@ var trackBuyNowGA = ({
762
818
  return;
763
819
  }
764
820
  const { variant } = lineItems[0];
765
- const currencyCode = variant.price?.currencyCode;
821
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
766
822
  const totalPrice = lineItems?.reduce(
767
823
  (prev, { variant: variant2 }) => prev.plus(
768
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
824
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
769
825
  ),
770
826
  new Decimal2__default.default(0)
771
827
  ).toNumber();
@@ -839,7 +895,7 @@ function useApplyCartCodes(options) {
839
895
  if (!discountCodes?.length) {
840
896
  throw new Error("Invalid input used for this operation: Miss discountCode");
841
897
  }
842
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
898
+ const cartId = providedCartId || cart?.id;
843
899
  if (!cartId) {
844
900
  return void 0;
845
901
  }
@@ -852,12 +908,18 @@ function useApplyCartCodes(options) {
852
908
  cookieAdapter: cartCookieAdapter,
853
909
  metafieldIdentifiers
854
910
  });
911
+ const unApplicableCodes = discountCodes.filter(
912
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
913
+ );
914
+ if (unApplicableCodes.length) {
915
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
916
+ }
855
917
  if (updatedCart) {
856
918
  mutateCart(updatedCart);
857
919
  }
858
920
  return updatedCart;
859
921
  },
860
- [client, locale, cartCookieAdapter, mutateCart, cart]
922
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
861
923
  );
862
924
  return useSWRMutation__default.default("apply-codes", applyCodes, options);
863
925
  }
@@ -867,7 +929,7 @@ function useRemoveCartCodes(options) {
867
929
  const removeCodes = react.useCallback(
868
930
  async (_key, { arg }) => {
869
931
  const { cartId: providedCartId, discountCodes } = arg;
870
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
932
+ const cartId = providedCartId || cart?.id;
871
933
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
872
934
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
873
935
  const updatedCart = await shopifySdk.updateCartCodes(client, {
@@ -881,225 +943,96 @@ function useRemoveCartCodes(options) {
881
943
  }
882
944
  return updatedCart;
883
945
  },
884
- [client, locale, cartCookieAdapter, mutateCart, cart]
946
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
885
947
  );
886
948
  return useSWRMutation__default.default("remove-codes", removeCodes, options);
887
949
  }
888
-
889
- // src/hooks/cart/use-add-to-cart.ts
890
- function useAddToCart({ withTrack = true } = {}, swrOptions) {
891
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
892
- const { cart } = useCartContext();
893
- const { trigger: applyCartCodes } = useApplyCartCodes();
894
- const { trigger: removeInvalidCodes } = useRemoveCartCodes();
895
- const { trigger: addCartLines2 } = useAddCartLines();
896
- const addToCart = react.useCallback(
897
- async (_key, { arg }) => {
898
- const {
899
- lineItems,
900
- cartId: providedCartId,
901
- discountCodes,
902
- gtmParams = {},
903
- buyerIdentity,
904
- needCreateCart = false,
905
- onCodesInvalid,
906
- replaceExistingCodes
907
- } = arg;
908
- if (!lineItems || lineItems.length === 0) {
909
- return;
910
- }
911
- const lines = lineItems.map((item) => ({
912
- merchandiseId: item.variant?.id || "",
913
- quantity: item.quantity || 1,
914
- attributes: item.attributes,
915
- sellingPlanId: item.sellingPlanId
916
- })).filter((item) => item.merchandiseId && item.quantity);
917
- if (lines.length === 0) {
918
- return;
919
- }
920
- const cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
921
- let resultCart = await addCartLines2({
922
- cartId,
923
- lines,
924
- buyerIdentity
925
- });
926
- if (!resultCart) {
927
- return void 0;
928
- }
929
- console.log("npm addCartLines resultCart", resultCart);
930
- if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
931
- const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
932
- if (unapplicableCodes.length > 0) {
933
- if (onCodesInvalid) {
934
- const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
935
- if (handledCart) {
936
- resultCart = handledCart;
937
- }
938
- } else {
939
- await removeInvalidCodes({
940
- discountCodes: unapplicableCodes
941
- });
942
- }
943
- }
944
- }
945
- if (discountCodes && discountCodes.length > 0) {
946
- applyCartCodes({
947
- replaceExistingCodes,
948
- discountCodes
949
- });
950
- }
951
- if (withTrack) {
952
- trackAddToCartGA({
953
- lineItems,
954
- gtmParams: { ...gtmParams, brand: config.getBrand() }
955
- });
956
- trackAddToCartFBQ({ lineItems });
957
- }
958
- return resultCart;
959
- },
960
- [client, locale, cartCookieAdapter, userAdapter, cart, withTrack]
950
+ var initSameLinesAttributes = ({
951
+ cart,
952
+ line
953
+ }) => {
954
+ const sameLineInCart = cart?.lineItems.find(
955
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
961
956
  );
962
- return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
963
- }
964
- function useUpdateCartLines(options) {
965
- const { client, locale, cartCookieAdapter } = useShopify();
966
- const { mutateCart, metafieldIdentifiers } = useCartContext();
967
- const updateLines = react.useCallback(
968
- async (_key, { arg }) => {
969
- const updatedCart = await shopifySdk.updateCartLines(client, {
970
- ...arg,
971
- metafieldIdentifiers,
972
- cookieAdapter: cartCookieAdapter
973
- });
974
- if (updatedCart) {
975
- mutateCart(updatedCart);
976
- }
977
- return updatedCart;
978
- },
979
- [client, locale, cartCookieAdapter, mutateCart]
957
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
958
+ (attr) => attr.key === CODE_AMOUNT_KEY
980
959
  );
981
- return useSWRMutation__default.default("update-cart-lines", updateLines, options);
982
- }
983
- function useRemoveCartLines(options) {
984
- const { client, locale, cartCookieAdapter } = useShopify();
985
- const { mutateCart, metafieldIdentifiers } = useCartContext();
986
- const removeLines = react.useCallback(
987
- async (_key, { arg }) => {
988
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
989
- let updatedCart = await shopifySdk.removeCartLines(client, {
990
- cartId,
991
- lineIds,
992
- metafieldIdentifiers,
993
- cookieAdapter: cartCookieAdapter
994
- });
995
- if (updatedCart && autoRemoveInvalidCodes) {
996
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
997
- if (unApplicableCodes.length > 0) {
998
- if (onCodesRemoved) {
999
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1000
- if (handledCart) {
1001
- updatedCart = handledCart;
1002
- }
1003
- } else {
1004
- updatedCart = await shopifySdk.updateCartCodes(client, {
1005
- cartId: updatedCart.id,
1006
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1007
- metafieldIdentifiers,
1008
- cookieAdapter: cartCookieAdapter
1009
- }) || updatedCart;
1010
- }
1011
- }
1012
- }
1013
- if (updatedCart) {
1014
- mutateCart(updatedCart);
1015
- }
1016
- return updatedCart;
1017
- },
1018
- [client, locale, cartCookieAdapter, mutateCart]
960
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
961
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
1019
962
  );
1020
- return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1021
- }
1022
- function useUpdateCartAttributes(mutate, metafieldIdentifiers, options) {
1023
- const { client, locale, cartCookieAdapter } = useShopify();
1024
- const updateAttributes = react.useCallback(
1025
- async (_key, { arg }) => {
1026
- const updatedCart = await shopifySdk.updateCartAttributes(client, {
1027
- ...arg,
1028
- metafieldIdentifiers,
1029
- cookieAdapter: cartCookieAdapter
1030
- });
1031
- console.log("useUpdateCartAttributes updatedCart", updatedCart);
1032
- if (updatedCart) {
1033
- mutate(updatedCart);
963
+ let functionAttribute = null;
964
+ try {
965
+ functionAttribute = sameLineInCart?.customAttributes?.find(
966
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
967
+ );
968
+ } catch (error) {
969
+ }
970
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
971
+ return {
972
+ ...line,
973
+ attributes: [
974
+ ...line.attributes || [],
975
+ codeAmountAttribute,
976
+ functionAttribute,
977
+ scriptCodeAmountAttribute
978
+ ].filter(Boolean)
979
+ };
980
+ }
981
+ return line;
982
+ };
983
+ var initDiscountAttributes = ({ line }) => {
984
+ let itemAttributes = line.attributes || [];
985
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
986
+ if (!functionEnvAttribute) {
987
+ itemAttributes = itemAttributes.concat([
988
+ {
989
+ key: CUSTOMER_ATTRIBUTE_KEY,
990
+ value: JSON.stringify({
991
+ is_gift: false,
992
+ discounted_amount: line.variant?.finalPrice?.amount === void 0 ? Number(line.variant?.price?.amount) * (line.quantity || 1) : Number(line.variant?.finalPrice?.amount) * (line.quantity || 1)
993
+ })
1034
994
  }
1035
- return updatedCart;
1036
- },
1037
- [client, locale, cartCookieAdapter, mutate]
995
+ ]);
996
+ }
997
+ const memberPriceAttribute = itemAttributes.find(
998
+ (attr) => attr.key === MEMBER_PRICE_ATTRIBUTE_KEY
1038
999
  );
1039
- return useSWRMutation__default.default("update-cart-attributes", updateAttributes, options);
1040
- }
1041
- function useBuyNow({ withTrack = true } = {}, swrOptions) {
1042
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
1043
- const isLoggedIn = userAdapter?.isLoggedIn || false;
1044
- const buyNow = react.useCallback(
1045
- async (_key, { arg }) => {
1046
- const {
1047
- lineItems,
1048
- discountCodes,
1049
- gtmParams = {},
1050
- buyerIdentity,
1051
- fbqTrackConfig,
1052
- customAttributes,
1053
- metafieldIdentifiers,
1054
- redirectToCheckout
1055
- } = arg;
1056
- if (!lineItems || lineItems.length === 0) {
1057
- return;
1000
+ const coupon = line.coupon;
1001
+ if (!memberPriceAttribute && coupon) {
1002
+ itemAttributes = itemAttributes.concat([
1003
+ {
1004
+ key: MEMBER_PRICE_ATTRIBUTE_KEY,
1005
+ value: JSON.stringify({ code: coupon.code })
1058
1006
  }
1059
- const lines = lineItems.map((item) => ({
1060
- merchandiseId: item.variant?.id || "",
1061
- quantity: item.quantity || 1,
1062
- attributes: item.attributes,
1063
- sellingPlanId: item.sellingPlanId
1064
- })).filter((item) => item.merchandiseId && item.quantity);
1065
- if (lines.length === 0) {
1066
- return;
1007
+ ]);
1008
+ }
1009
+ const couponDiscountAttribute = itemAttributes.find(
1010
+ (attr) => attr.key === CODE_AMOUNT_KEY || attr.key === SCRIPT_CODE_AMOUNT_KEY
1011
+ );
1012
+ if (!couponDiscountAttribute && coupon && Number(coupon?.amount) > 0) {
1013
+ itemAttributes = itemAttributes.concat([
1014
+ {
1015
+ key: CODE_AMOUNT_KEY,
1016
+ value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
1017
+ },
1018
+ {
1019
+ key: SCRIPT_CODE_AMOUNT_KEY,
1020
+ value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
1067
1021
  }
1068
- const resultCart = await shopifySdk.createCart(client, {
1069
- lines,
1070
- metafieldIdentifiers,
1071
- cookieAdapter: cartCookieAdapter,
1072
- buyerIdentity,
1073
- discountCodes,
1074
- customAttributes
1075
- });
1076
- if (!resultCart) {
1077
- throw new Error("Failed to create cart for buy now");
1078
- }
1079
- if (withTrack && resultCart.lineItems) {
1080
- trackBuyNowGA({
1081
- lineItems,
1082
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1083
- });
1084
- if (fbqTrackConfig) {
1085
- trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
1086
- }
1087
- }
1088
- if (redirectToCheckout) {
1089
- if (resultCart.url) {
1090
- if (typeof window !== "undefined") {
1091
- window.location.href = resultCart.url;
1092
- }
1093
- } else {
1094
- throw new Error("Failed to get checkout URL");
1095
- }
1096
- }
1097
- return resultCart;
1098
- },
1099
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
1100
- );
1101
- return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
1102
- }
1022
+ ]);
1023
+ }
1024
+ return { ...line, attributes: itemAttributes };
1025
+ };
1026
+ var getLinesWithAttributes = ({
1027
+ cart,
1028
+ lineItems
1029
+ }) => {
1030
+ return lineItems.map((line) => {
1031
+ const sameLine = initSameLinesAttributes({ cart, line });
1032
+ const functionLine = initDiscountAttributes({ line: sameLine });
1033
+ return functionLine;
1034
+ });
1035
+ };
1103
1036
  function useCalcGiftsFromLines({
1104
1037
  lines,
1105
1038
  customer,
@@ -1116,30 +1049,55 @@ function useCalcGiftsFromLines({
1116
1049
  lines
1117
1050
  });
1118
1051
  const allGiftLines = react.useMemo(() => {
1119
- const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || [];
1120
- const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((product) => {
1121
- const giftProduct = scriptGift.giftProductsResult?.find(
1122
- (p) => p.handle === product.handle
1052
+ const functionGiftLines = (functionGift.qualifyingGift?.itemsToAdd || []).map((item) => {
1053
+ const product = functionGift.giftProductsResult?.find(
1054
+ (product2) => product2.handle === item.variant.handle
1055
+ );
1056
+ const variants = product?.variants;
1057
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.variant.sku) : void 0;
1058
+ if (!variant) {
1059
+ console.warn(
1060
+ `Function gift: Variant not found for handle=${item.variant.handle}, sku=${item.variant.sku}`
1061
+ );
1062
+ return null;
1063
+ }
1064
+ return {
1065
+ variant: {
1066
+ ...variant,
1067
+ product
1068
+ },
1069
+ quantity: item.quantity ?? 1,
1070
+ attributes: item.attributes
1071
+ };
1072
+ }).filter((item) => item !== null);
1073
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((item) => {
1074
+ const product = scriptGift.giftProductsResult?.find(
1075
+ (product2) => product2.handle === item.handle
1123
1076
  );
1124
- const variant = giftProduct?.variants?.[0];
1077
+ const variants = product?.variants;
1078
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1079
+ if (!variant) {
1080
+ console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1081
+ return null;
1082
+ }
1125
1083
  return {
1126
1084
  variant: {
1127
- id: variant?.id || "",
1128
- handle: product.handle,
1129
- sku: product.sku
1085
+ ...variant,
1086
+ product
1130
1087
  },
1131
1088
  quantity: 1,
1132
1089
  attributes: [
1133
1090
  {
1134
1091
  key: scriptGiveawayKey,
1135
- value: "true"
1092
+ value: scriptGiveawayKey
1136
1093
  }
1137
1094
  ]
1138
1095
  };
1139
- }).filter((item) => item.variant.id) : [];
1096
+ }).filter((item) => item !== null) : [];
1140
1097
  return [...functionGiftLines, ...scriptGiftLines];
1141
1098
  }, [
1142
1099
  functionGift.qualifyingGift,
1100
+ functionGift.giftProductsResult,
1143
1101
  scriptGift.freeGiftLevel,
1144
1102
  scriptGift.giftProductsResult,
1145
1103
  scriptGiveawayKey
@@ -1174,7 +1132,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1174
1132
  const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
1175
1133
  const dealsType = "";
1176
1134
  const { activeCampaign, subtotal } = react.useMemo(() => {
1177
- for (const campaign of orderDiscountConfig) {
1135
+ for (const campaign of orderDiscountConfig || []) {
1178
1136
  const { rule_conditions = [], result_detail } = campaign;
1179
1137
  const { main_product, order_discount_conf } = result_detail || {};
1180
1138
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
@@ -1204,9 +1162,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1204
1162
  discountAmount: 0
1205
1163
  };
1206
1164
  }
1207
- const tieredDiscounts = activeCampaign.result_detail.order_discount_conf.tiered_discounts;
1208
- const qualifyingTier = [...tieredDiscounts].reverse().find((tier) => subtotal >= Number(tier.amount));
1209
- const nextGoal = tieredDiscounts.find((tier) => subtotal < Number(tier.amount));
1165
+ const currentCurrency = cart?.currency?.code || "";
1166
+ console.log("currentCurrency", cart, currentCurrency);
1167
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1168
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1169
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1170
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1210
1171
  if (!qualifyingTier) {
1211
1172
  return {
1212
1173
  qualifyingDiscount: null,
@@ -1243,43 +1204,10 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1243
1204
  isLoading: isCustomerLoading
1244
1205
  };
1245
1206
  };
1246
- function useHasPlusMemberInCart({
1247
- memberSetting,
1248
- cart
1249
- }) {
1250
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1251
- return react.useMemo(() => {
1252
- if (!cart?.lineItems) {
1253
- return {
1254
- hasPlusMember: false,
1255
- hasMonthlyPlus: false,
1256
- hasAnnualPlus: false
1257
- };
1258
- }
1259
- const monthlyPlusItem = cart.lineItems.find(
1260
- (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1261
- );
1262
- const annualPlusItem = cart.lineItems.find(
1263
- (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1264
- );
1265
- const hasMonthlyPlus = !!monthlyPlusItem;
1266
- const hasAnnualPlus = !!annualPlusItem;
1267
- const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1268
- return {
1269
- hasPlusMember,
1270
- hasMonthlyPlus,
1271
- hasAnnualPlus,
1272
- monthlyPlusItem,
1273
- annualPlusItem
1274
- };
1275
- }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1276
- }
1277
-
1278
- // src/hooks/cart/feature/use-cart-attributes.ts
1279
1207
  var getReferralAttributes = () => {
1280
- const inviteCode = Cookies5__default.default.get("invite_code");
1281
- const playModeId = Cookies5__default.default.get("playModeId");
1282
- const popup = Cookies5__default.default.get("_popup");
1208
+ const inviteCode = shopifySdk.getLocalStorage("inviteCode") || Cookies5__default.default.get("inviteCode");
1209
+ const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
1210
+ const popup = shopifySdk.getLocalStorage("_popup") || Cookies5__default.default.get("_popup");
1283
1211
  if (inviteCode && playModeId) {
1284
1212
  return popup ? [
1285
1213
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1292,121 +1220,130 @@ var getReferralAttributes = () => {
1292
1220
  }
1293
1221
  return [];
1294
1222
  };
1223
+ var getUserType = (customer) => {
1224
+ let userInfo = Cookies5__default.default.get("userInfo");
1225
+ if (userInfo) {
1226
+ userInfo = JSON.parse(userInfo);
1227
+ let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1228
+ userInfo.setId = arr[arr.length - 1];
1229
+ }
1230
+ const customerInfo = userInfo || customer;
1231
+ if (!customerInfo) {
1232
+ return "new_user_unlogin";
1233
+ }
1234
+ if (customer) {
1235
+ const { orders = {} } = customer;
1236
+ if (orders?.edges?.length === 1) {
1237
+ return "old_user_orders_once";
1238
+ } else if (orders?.edges?.length > 1) {
1239
+ return "old_user_orders_twice";
1240
+ }
1241
+ }
1242
+ return "new_user_login";
1243
+ };
1244
+ function getCartAttributes({
1245
+ profile,
1246
+ customer,
1247
+ cart,
1248
+ memberType,
1249
+ currentUrl = ""
1250
+ }) {
1251
+ const userType = getUserType(customer);
1252
+ const memberAttributes = [
1253
+ {
1254
+ key: "_token",
1255
+ value: profile?.token
1256
+ },
1257
+ {
1258
+ key: "_member_type",
1259
+ value: memberType ?? String(profile?.memberType ?? 0)
1260
+ },
1261
+ {
1262
+ key: "_user_type",
1263
+ value: userType
1264
+ },
1265
+ {
1266
+ key: "_is_login",
1267
+ value: profile?.token ? "true" : "false"
1268
+ }
1269
+ ];
1270
+ if (profile?.token) {
1271
+ memberAttributes.push({
1272
+ key: "_login_user",
1273
+ value: "1"
1274
+ });
1275
+ }
1276
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1277
+ const functionAttributes = [
1278
+ {
1279
+ key: CUSTOMER_ATTRIBUTE_KEY,
1280
+ value: JSON.stringify({
1281
+ discount_code: discountCodes,
1282
+ user_tags: customer?.tags || []
1283
+ })
1284
+ }
1285
+ ];
1286
+ const presellAttributes = [
1287
+ {
1288
+ key: "_presale",
1289
+ value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1290
+ }
1291
+ ];
1292
+ const weightAttributes = [
1293
+ {
1294
+ key: "_weight",
1295
+ value: cart?.lineItems.reduce((acc, item) => {
1296
+ return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1297
+ }, 0).toString()
1298
+ },
1299
+ {
1300
+ key: "_app_source_name",
1301
+ value: "dtc"
1302
+ }
1303
+ ];
1304
+ const trackingAttributes = [
1305
+ {
1306
+ key: "utm_params",
1307
+ value: currentUrl
1308
+ }
1309
+ ];
1310
+ const commonAttributes = [
1311
+ ...memberAttributes,
1312
+ ...functionAttributes,
1313
+ ...presellAttributes,
1314
+ ...weightAttributes,
1315
+ ...trackingAttributes,
1316
+ ...getReferralAttributes()
1317
+ ].filter((item) => item?.value);
1318
+ const extraAttributesInCart = cart?.customAttributes?.filter(
1319
+ (item) => !commonAttributes.some((attr) => attr.key === item.key)
1320
+ ) || [];
1321
+ return [...commonAttributes, ...extraAttributesInCart].filter((item) => item?.value);
1322
+ }
1295
1323
  var useCartAttributes = ({
1296
1324
  profile,
1297
1325
  customer,
1298
1326
  cart,
1299
- memberSetting
1327
+ memberType
1300
1328
  }) => {
1301
1329
  const [currentUrl, setCurrentUrl] = react.useState("");
1302
- const { hasPlusMember } = useHasPlusMemberInCart({
1303
- memberSetting,
1304
- cart
1305
- });
1306
1330
  react.useEffect(() => {
1307
1331
  setCurrentUrl(window.location.href);
1308
1332
  }, []);
1309
- const userType = react.useMemo(() => {
1310
- let userInfo = Cookies5__default.default.get("userInfo");
1311
- if (userInfo) {
1312
- userInfo = JSON.parse(userInfo);
1313
- let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1314
- userInfo.setId = arr[arr.length - 1];
1315
- }
1316
- const customerInfo = userInfo || customer;
1317
- if (!customerInfo) {
1318
- return "new_user_unlogin";
1319
- }
1320
- if (customer) {
1321
- const { orders = {} } = customer;
1322
- if (orders?.edges?.length === 1) {
1323
- return "old_user_orders_once";
1324
- } else if (orders?.edges?.length > 1) {
1325
- return "old_user_orders_twice";
1326
- }
1327
- }
1328
- return "new_user_login";
1329
- }, [customer]);
1330
- const memberAttributes = react.useMemo(() => {
1331
- return [
1332
- {
1333
- key: "_token",
1334
- value: profile?.token
1335
- //是否登录
1336
- },
1337
- {
1338
- key: "_member_type",
1339
- value: hasPlusMember ? "2" : profile?.memberType
1340
- //:0(游客),1(普通会员),2(付费会员)
1341
- },
1342
- {
1343
- key: "_user_type",
1344
- value: userType
1345
- // n
1346
- },
1347
- {
1348
- key: "_is_login",
1349
- value: profile?.token ? "true" : "false"
1350
- }
1351
- ];
1352
- }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1353
- const functionAttributes = react.useMemo(() => {
1354
- const hasFunctionEnvAttribute = cart?.lineItems.some(
1355
- (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1356
- );
1357
- const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1358
- return hasFunctionEnvAttribute ? [
1359
- {
1360
- key: "_discounts_function_env",
1361
- value: JSON.stringify({
1362
- discount_code: discountCodes,
1363
- user_tags: customer?.tags || []
1364
- })
1365
- }
1366
- ] : [];
1367
- }, [cart]);
1368
- const presellAttributes = react.useMemo(() => {
1369
- return [
1370
- {
1371
- key: "_presale",
1372
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1373
- }
1374
- ];
1375
- }, [cart]);
1376
- const weightAttributes = react.useMemo(() => {
1377
- return [
1378
- {
1379
- key: "_weight",
1380
- value: cart?.lineItems.reduce((acc, item) => {
1381
- return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1382
- }, 0).toString()
1383
- },
1384
- {
1385
- key: "_app_source_name",
1386
- value: "dtc"
1387
- }
1388
- ];
1389
- }, [cart]);
1390
- const trackingAttributes = react.useMemo(() => {
1391
- return [
1392
- {
1393
- key: "utm_params",
1394
- value: currentUrl
1395
- }
1396
- ];
1397
- }, [currentUrl]);
1333
+ const attributes = react.useMemo(() => {
1334
+ return getCartAttributes({
1335
+ profile,
1336
+ customer,
1337
+ cart,
1338
+ memberType,
1339
+ currentUrl
1340
+ });
1341
+ }, [profile, customer, cart, memberType, currentUrl]);
1398
1342
  return react.useMemo(
1399
1343
  () => ({
1400
- attributes: [
1401
- ...memberAttributes,
1402
- ...functionAttributes,
1403
- ...presellAttributes,
1404
- ...weightAttributes,
1405
- ...trackingAttributes,
1406
- ...getReferralAttributes()
1407
- ].filter((item) => item?.value)
1344
+ attributes
1408
1345
  }),
1409
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1346
+ [attributes]
1410
1347
  );
1411
1348
  };
1412
1349
  var DEFAULT_MIN = 1;
@@ -1469,7 +1406,7 @@ var useUpdateLineCodeAmountAttributes = ({
1469
1406
  );
1470
1407
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1471
1408
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1472
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1409
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1473
1410
  attrNeedUpdate.push({
1474
1411
  key: CUSTOMER_ATTRIBUTE_KEY,
1475
1412
  value: JSON.stringify({
@@ -1508,29 +1445,22 @@ var useUpdateLineCodeAmountAttributes = ({
1508
1445
  }).filter(
1509
1446
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1510
1447
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1448
+ let lineId = line.id;
1449
+ let attributes = line.customAttributes || [];
1450
+ if (attrNeedDelete.length) {
1451
+ attributes = attributes.filter(
1452
+ (attr) => !attrNeedDelete.includes(attr.key)
1453
+ );
1454
+ }
1511
1455
  if (attrNeedUpdate.length) {
1512
- return {
1513
- id: line.id,
1514
- attributes: [
1515
- ...line.customAttributes?.filter(
1516
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1517
- ) || [],
1518
- ...attrNeedUpdate
1519
- ]
1520
- };
1521
- } else if (attrNeedDelete.length) {
1522
- return {
1523
- id: line.id,
1524
- attributes: line.customAttributes?.filter(
1525
- (attr) => !attrNeedDelete.includes(attr.key)
1526
- ) || []
1527
- };
1528
- } else {
1529
- return {
1530
- id: line.id,
1531
- attributes: line.customAttributes || []
1532
- };
1456
+ attributes = attributes.filter(
1457
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1458
+ ).concat(attrNeedUpdate);
1533
1459
  }
1460
+ return {
1461
+ id: lineId,
1462
+ attributes
1463
+ };
1534
1464
  }),
1535
1465
  [cart?.lineItems, mainProductDiscountCodes]
1536
1466
  );
@@ -1565,45 +1495,61 @@ var useUpdateLineCodeAmountAttributes = ({
1565
1495
  }, [loading, setLoadingState]);
1566
1496
  };
1567
1497
 
1568
- // src/hooks/cart/types/price-discount.ts
1569
- var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
1570
- PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1571
- PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1572
- return PriceDiscountType2;
1573
- })(PriceDiscountType || {});
1574
- var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
1575
- PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
1576
- PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
1577
- return PriceBasePriceType2;
1578
- })(PriceBasePriceType || {});
1579
- function useProduct(options = {}) {
1580
- const { client, locale } = useShopify();
1581
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
1582
- return useSWR__default.default(
1583
- handle ? ["product", locale, handle, metafieldIdentifiers] : null,
1584
- () => shopifySdk.getProduct(client, {
1585
- handle,
1586
- locale,
1587
- metafieldIdentifiers
1588
- }),
1589
- swrOptions
1590
- );
1591
- }
1592
- function useAllProducts(options = {}) {
1593
- const { client, locale } = useShopify();
1594
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
1595
- return useSWR__default.default(
1596
- ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
1597
- () => shopifySdk.getAllProducts(client, {
1598
- locale,
1599
- first,
1600
- query,
1601
- sortKey,
1602
- reverse,
1603
- metafieldIdentifiers
1604
- }),
1605
- swrOptions
1606
- );
1498
+ // src/hooks/member/plus/types.ts
1499
+ var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
1500
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
1501
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
1502
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
1503
+ return PLUS_MEMBER_TYPE2;
1504
+ })(PLUS_MEMBER_TYPE || {});
1505
+ var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
1506
+ PlusMemberMode2["MONTHLY"] = "monthly";
1507
+ PlusMemberMode2["ANNUAL"] = "annual";
1508
+ return PlusMemberMode2;
1509
+ })(PlusMemberMode || {});
1510
+ var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
1511
+ DeliveryPlusType2["FREE"] = "free";
1512
+ DeliveryPlusType2["MONTHLY"] = "monthly";
1513
+ DeliveryPlusType2["ANNUAL"] = "annual";
1514
+ return DeliveryPlusType2;
1515
+ })(DeliveryPlusType || {});
1516
+ var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
1517
+ ShippingMethodMode2["FREE"] = "free";
1518
+ ShippingMethodMode2["TDD"] = "tdd";
1519
+ ShippingMethodMode2["NDD"] = "ndd";
1520
+ return ShippingMethodMode2;
1521
+ })(ShippingMethodMode || {});
1522
+ var createInitialValue = () => ({
1523
+ plusMemberMetafields: {},
1524
+ selectedPlusMemberMode: "free",
1525
+ setSelectedPlusMemberMode: () => {
1526
+ },
1527
+ selectedShippingMethod: void 0,
1528
+ setSelectedShippingMethod: () => {
1529
+ },
1530
+ showMoreShippingMethod: false,
1531
+ setShowMoreShippingMethod: () => {
1532
+ },
1533
+ variant: {},
1534
+ product: {},
1535
+ shippingMethodsContext: {
1536
+ freeShippingMethods: [],
1537
+ paymentShippingMethods: [],
1538
+ nddOverweight: false,
1539
+ tddOverweight: false,
1540
+ nddCoupon: void 0,
1541
+ tddCoupon: void 0,
1542
+ isLoadingCoupon: false
1543
+ },
1544
+ selectedPlusMemberVariant: void 0,
1545
+ showPlusMemberBenefit: false,
1546
+ setShowPlusMemberBenefit: () => {
1547
+ },
1548
+ profile: void 0
1549
+ });
1550
+ var PlusMemberContext = react.createContext(createInitialValue());
1551
+ function usePlusMemberContext() {
1552
+ return react.useContext(PlusMemberContext);
1607
1553
  }
1608
1554
  function useProductsByHandles(options = {}) {
1609
1555
  const { client, locale } = useShopify();
@@ -1623,41 +1569,811 @@ function useProductsByHandles(options = {}) {
1623
1569
  metafieldIdentifiers
1624
1570
  });
1625
1571
  },
1626
- swrOptions || {
1627
- revalidateOnFocus: false
1572
+ {
1573
+ revalidateOnFocus: false,
1574
+ ...swrOptions
1628
1575
  }
1629
1576
  );
1630
1577
  }
1631
- function getFirstAvailableVariant(product) {
1632
- const availableVariant = product.variants.find((v) => v.availableForSale);
1633
- return availableVariant || product.variants[0];
1634
- }
1635
- function getVariantFromSelectedOptions(product, selectedOptions) {
1636
- return product.variants.find((variant) => {
1637
- return variant.selectedOptions.every((option) => {
1638
- return selectedOptions[option.name] === option.value;
1639
- });
1578
+
1579
+ // src/hooks/member/plus/use-plus-member-variants.ts
1580
+ function usePlusMemberVariants({
1581
+ memberSetting
1582
+ }) {
1583
+ const plusMonthly = memberSetting?.plus_monthly_product;
1584
+ const plusAnnual = memberSetting?.plus_annual_product;
1585
+ const plusMemberHandles = react.useMemo(() => {
1586
+ return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
1587
+ }, [plusMonthly?.handle, plusAnnual?.handle]);
1588
+ const { data: plusMemberProducts = [] } = useProductsByHandles({
1589
+ handles: plusMemberHandles
1640
1590
  });
1591
+ const monthlyProduct = react.useMemo(() => {
1592
+ return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
1593
+ }, [plusMemberProducts, plusMonthly]);
1594
+ const annualProduct = react.useMemo(() => {
1595
+ return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
1596
+ }, [plusMemberProducts, plusAnnual]);
1597
+ const monthlyVariant = react.useMemo(() => {
1598
+ return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
1599
+ }, [monthlyProduct, plusMonthly]);
1600
+ const annualVariant = react.useMemo(() => {
1601
+ return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
1602
+ }, [annualProduct, plusAnnual]);
1603
+ return {
1604
+ monthlyVariant: monthlyVariant ? {
1605
+ ...monthlyVariant,
1606
+ product: monthlyProduct
1607
+ } : void 0,
1608
+ annualVariant: annualVariant ? {
1609
+ ...annualVariant,
1610
+ product: annualProduct
1611
+ } : void 0
1612
+ };
1641
1613
  }
1642
- function useVariant({
1643
- product,
1644
- selectedOptions
1645
- }) {
1646
- const [variant, setVariant] = react.useState(
1647
- product ? getFirstAvailableVariant(product) : void 0
1648
- );
1649
- react.useEffect(() => {
1650
- if (!product) {
1651
- setVariant(void 0);
1652
- return;
1653
- }
1654
- const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
1655
- if (newVariant && newVariant.id !== variant?.id) {
1656
- setVariant(newVariant);
1657
- } else if (!newVariant) {
1658
- setVariant(getFirstAvailableVariant(product));
1614
+ var useAvailableDeliveryCoupon = ({
1615
+ profile
1616
+ }) => {
1617
+ const { data: availableDeliveryCoupon, isLoading } = useSWR__default.default(
1618
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
1619
+ async ([apiPath]) => {
1620
+ return fetch(apiPath).then((res) => res.json());
1659
1621
  }
1660
- }, [selectedOptions, product, variant?.id]);
1622
+ );
1623
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
1624
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
1625
+ return {
1626
+ nddCoupon,
1627
+ tddCoupon,
1628
+ isLoading
1629
+ };
1630
+ };
1631
+
1632
+ // src/hooks/member/plus/use-shipping-methods.ts
1633
+ function useShippingMethods(options) {
1634
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
1635
+ const isPlus = profile?.isPlus || false;
1636
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
1637
+ const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
1638
+ const nddOverweight = react.useMemo(() => {
1639
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
1640
+ }, [shippingMethod?.overWeight_ndd, variant?.weight]);
1641
+ const tddOverweight = react.useMemo(() => {
1642
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
1643
+ }, [shippingMethod?.overWeight_tdd, variant?.weight]);
1644
+ const paymentShippingMethods = react.useMemo(() => {
1645
+ const weight = variant?.weight || 0;
1646
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
1647
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1648
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
1649
+ }) || [];
1650
+ return methods.map((method) => {
1651
+ let disabled = false;
1652
+ const selectedFreeMember = selectedPlusMemberMode === "free";
1653
+ if (method.__mode === "ndd" /* NDD */) {
1654
+ disabled = selectedFreeMember || nddOverweight;
1655
+ } else if (method.__mode === "tdd" /* TDD */) {
1656
+ disabled = selectedFreeMember || tddOverweight;
1657
+ }
1658
+ return {
1659
+ ...method,
1660
+ id: method.__mode + method.__code,
1661
+ useCoupon: false,
1662
+ subtitle: plus_shipping?.directly || "",
1663
+ disabled
1664
+ };
1665
+ });
1666
+ }, [
1667
+ nddOverweight,
1668
+ plus_shipping?.directly,
1669
+ plus_shipping?.shipping_methods,
1670
+ selectedPlusMemberMode,
1671
+ tddOverweight,
1672
+ variant?.weight
1673
+ ]);
1674
+ const nddPrice = react.useMemo(() => {
1675
+ const weight = variant?.weight || 0;
1676
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1677
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1678
+ return __mode === "ndd" && fitWeight;
1679
+ });
1680
+ return nddMethod?.price || 0;
1681
+ }, [variant?.weight, paymentShippingMethods]);
1682
+ const tddPrice = react.useMemo(() => {
1683
+ const weight = variant?.weight || 0;
1684
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1685
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1686
+ return __mode === "tdd" && fitWeight;
1687
+ });
1688
+ return tddMethod?.price || 0;
1689
+ }, [variant?.weight, paymentShippingMethods]);
1690
+ const freeShippingMethods = react.useMemo(() => {
1691
+ const weight = variant?.weight || 0;
1692
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
1693
+ if (__mode === "free" /* FREE */) {
1694
+ return true;
1695
+ }
1696
+ if (isPlus) {
1697
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
1698
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1699
+ return hasCoupon && fitWeight && !__plus;
1700
+ } else {
1701
+ return __plus;
1702
+ }
1703
+ }) || [];
1704
+ if (isPlus) {
1705
+ methods = methods.sort((a, b) => {
1706
+ if (b.__mode === "free" /* FREE */) return -1;
1707
+ return 0;
1708
+ });
1709
+ }
1710
+ return methods.map((method) => {
1711
+ let price = 0;
1712
+ let coupon;
1713
+ let disabled;
1714
+ if (method.__mode !== "free" /* FREE */) {
1715
+ switch (method.__mode) {
1716
+ case "tdd":
1717
+ price = tddPrice;
1718
+ coupon = tddCoupon || nddCoupon;
1719
+ break;
1720
+ case "ndd":
1721
+ price = nddPrice;
1722
+ coupon = nddCoupon;
1723
+ break;
1724
+ }
1725
+ disabled = selectedPlusMemberMode === "free";
1726
+ if (method.__mode === "ndd" /* NDD */) {
1727
+ disabled = disabled || nddOverweight;
1728
+ } else if (method.__mode === "tdd" /* TDD */) {
1729
+ disabled = disabled || tddOverweight;
1730
+ }
1731
+ }
1732
+ return {
1733
+ ...method,
1734
+ id: method.__mode + method.__code,
1735
+ useCoupon: true,
1736
+ disabled,
1737
+ coupon,
1738
+ price
1739
+ };
1740
+ });
1741
+ }, [
1742
+ variant?.weight,
1743
+ plus_shipping?.shipping_methods,
1744
+ isPlus,
1745
+ nddCoupon,
1746
+ tddCoupon,
1747
+ selectedPlusMemberMode,
1748
+ tddPrice,
1749
+ nddPrice,
1750
+ nddOverweight,
1751
+ tddOverweight
1752
+ ]);
1753
+ return {
1754
+ freeShippingMethods,
1755
+ paymentShippingMethods,
1756
+ nddOverweight,
1757
+ tddOverweight,
1758
+ nddCoupon,
1759
+ tddCoupon,
1760
+ isLoadingCoupon: isLoading
1761
+ };
1762
+ }
1763
+ var useReplaceCartPlusMember = () => {
1764
+ const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
1765
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1766
+ const { cart } = useCartContext();
1767
+ const plusMonthly = plusMemberMetafields?.plus_monthly_product;
1768
+ const plusAnnual = plusMemberMetafields?.plus_annual_product;
1769
+ const handler = react.useCallback(async () => {
1770
+ const plusMonthlyInCart = cart?.lineItems.find(
1771
+ (item) => item.variant?.sku === plusMonthly?.sku
1772
+ );
1773
+ const plusAnnualInCart = cart?.lineItems.find(
1774
+ (item) => item.variant?.sku === plusAnnual?.sku
1775
+ );
1776
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
1777
+ await removeCartLines2({
1778
+ lineIds: [plusMonthlyInCart.id]
1779
+ });
1780
+ } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
1781
+ await removeCartLines2({
1782
+ lineIds: [plusAnnualInCart.id]
1783
+ });
1784
+ }
1785
+ }, [
1786
+ cart?.lineItems,
1787
+ selectedPlusMemberMode,
1788
+ plusMonthly?.sku,
1789
+ plusAnnual?.sku,
1790
+ removeCartLines2
1791
+ ]);
1792
+ return handler;
1793
+ };
1794
+ var usePlusMemberCheckoutCustomAttributes = ({
1795
+ disableShipping = false,
1796
+ isPresaleContains = false
1797
+ }) => {
1798
+ const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
1799
+ return react.useMemo(() => {
1800
+ const checkoutCustomAttributes = [
1801
+ {
1802
+ key: "_last_url",
1803
+ value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
1804
+ }
1805
+ ];
1806
+ checkoutCustomAttributes.push({
1807
+ key: "_checkout_delivery_custom",
1808
+ value: JSON.stringify({
1809
+ allow_nextday_delivery: true,
1810
+ allow_thirdday_delivery: true,
1811
+ selected_delivery_option: {
1812
+ code: selectedShippingMethod?.__code,
1813
+ mode: selectedShippingMethod?.__mode
1814
+ },
1815
+ is_presale: isPresaleContains,
1816
+ discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
1817
+ plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
1818
+ is_prime: profile?.isPlus
1819
+ })
1820
+ });
1821
+ if (disableShipping) {
1822
+ checkoutCustomAttributes.push({
1823
+ key: "_hide_shipping",
1824
+ value: "true"
1825
+ });
1826
+ }
1827
+ return checkoutCustomAttributes;
1828
+ }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1829
+ };
1830
+ function useRemoveCartLines(options) {
1831
+ const { client, locale, cartCookieAdapter } = useShopify();
1832
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1833
+ const removeLines = react.useCallback(
1834
+ async (_key, { arg }) => {
1835
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1836
+ let updatedCart = await shopifySdk.removeCartLines(client, {
1837
+ cartId,
1838
+ lineIds,
1839
+ metafieldIdentifiers,
1840
+ cookieAdapter: cartCookieAdapter
1841
+ });
1842
+ if (updatedCart && autoRemoveInvalidCodes) {
1843
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1844
+ if (unApplicableCodes.length > 0) {
1845
+ if (onCodesRemoved) {
1846
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1847
+ if (handledCart) {
1848
+ updatedCart = handledCart;
1849
+ }
1850
+ } else {
1851
+ updatedCart = await shopifySdk.updateCartCodes(client, {
1852
+ cartId: updatedCart.id,
1853
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1854
+ metafieldIdentifiers,
1855
+ cookieAdapter: cartCookieAdapter
1856
+ }) || updatedCart;
1857
+ }
1858
+ }
1859
+ }
1860
+ if (updatedCart) {
1861
+ mutateCart(updatedCart);
1862
+ }
1863
+ return updatedCart;
1864
+ },
1865
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1866
+ );
1867
+ return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1868
+ }
1869
+
1870
+ // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1871
+ function useAutoRemovePlusMemberInCart({
1872
+ cart,
1873
+ profile,
1874
+ memberSetting
1875
+ }) {
1876
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1877
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1878
+ react.useEffect(() => {
1879
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
1880
+ const removePlusProduct = async (productType) => {
1881
+ if (!productType) return;
1882
+ const product = cart.lineItems?.find(
1883
+ (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
1884
+ );
1885
+ if (product) {
1886
+ await removeCartLines2({
1887
+ lineIds: [product.id]
1888
+ });
1889
+ }
1890
+ };
1891
+ if (profile?.isMonthlyPlus) {
1892
+ removePlusProduct(plus_monthly_product);
1893
+ }
1894
+ if (profile?.isAnnualPlus) {
1895
+ removePlusProduct(plus_annual_product);
1896
+ }
1897
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
1898
+ }
1899
+ function hasPlusMemberInCart({
1900
+ memberSetting,
1901
+ cart
1902
+ }) {
1903
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1904
+ if (!cart?.lineItems) {
1905
+ return {
1906
+ hasPlusMember: false,
1907
+ hasMonthlyPlus: false,
1908
+ hasAnnualPlus: false
1909
+ };
1910
+ }
1911
+ const monthlyPlusItem = cart.lineItems.find(
1912
+ (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1913
+ );
1914
+ const annualPlusItem = cart.lineItems.find(
1915
+ (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1916
+ );
1917
+ const hasMonthlyPlus = !!monthlyPlusItem;
1918
+ const hasAnnualPlus = !!annualPlusItem;
1919
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1920
+ return {
1921
+ hasPlusMember,
1922
+ hasMonthlyPlus,
1923
+ hasAnnualPlus,
1924
+ monthlyPlusItem,
1925
+ annualPlusItem
1926
+ };
1927
+ }
1928
+ function useHasPlusMemberInCart({
1929
+ memberSetting,
1930
+ cart
1931
+ }) {
1932
+ return react.useMemo(
1933
+ () => hasPlusMemberInCart({
1934
+ memberSetting,
1935
+ cart
1936
+ }),
1937
+ [memberSetting, cart]
1938
+ );
1939
+ }
1940
+ function hasPlusMemberInLines({
1941
+ memberSetting,
1942
+ lines
1943
+ }) {
1944
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1945
+ if (!lines || lines.length === 0) {
1946
+ return {
1947
+ hasPlusMember: false,
1948
+ hasMonthlyPlus: false,
1949
+ hasAnnualPlus: false
1950
+ };
1951
+ }
1952
+ const monthlyPlusLine = lines.find((line) => {
1953
+ const variantHandle = line.variant?.product?.handle;
1954
+ const variantSku = line.variant?.sku;
1955
+ return variantHandle === plus_monthly_product?.handle && variantSku === plus_monthly_product?.sku;
1956
+ });
1957
+ const annualPlusLine = lines.find((line) => {
1958
+ const variantHandle = line.variant?.product?.handle;
1959
+ const variantSku = line.variant?.sku;
1960
+ return variantHandle === plus_annual_product?.handle && variantSku === plus_annual_product?.sku;
1961
+ });
1962
+ const hasMonthlyPlus = !!monthlyPlusLine;
1963
+ const hasAnnualPlus = !!annualPlusLine;
1964
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1965
+ return {
1966
+ hasPlusMember,
1967
+ hasMonthlyPlus,
1968
+ hasAnnualPlus,
1969
+ monthlyPlusLine,
1970
+ annualPlusLine
1971
+ };
1972
+ }
1973
+ function useHasPlusMemberInLines({
1974
+ memberSetting,
1975
+ lines
1976
+ }) {
1977
+ return react.useMemo(
1978
+ () => hasPlusMemberInLines({
1979
+ memberSetting,
1980
+ lines
1981
+ }),
1982
+ [memberSetting, lines]
1983
+ );
1984
+ }
1985
+ function usePlusMemberNeedAddToCart({
1986
+ cart,
1987
+ profile
1988
+ }) {
1989
+ const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
1990
+ const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
1991
+ memberSetting: plusMemberMetafields,
1992
+ cart
1993
+ });
1994
+ const plusMemberVariant = react.useMemo(() => {
1995
+ if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
1996
+ return void 0;
1997
+ }
1998
+ if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
1999
+ return void 0;
2000
+ }
2001
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2002
+ return void 0;
2003
+ }
2004
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2005
+ return void 0;
2006
+ }
2007
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2008
+ return void 0;
2009
+ }
2010
+ return selectedPlusMemberVariant;
2011
+ }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2012
+ return plusMemberVariant;
2013
+ }
2014
+ var PlusMemberProvider = ({
2015
+ variant,
2016
+ product,
2017
+ memberSetting,
2018
+ initialSelectedPlusMemberMode = "free",
2019
+ profile,
2020
+ children
2021
+ }) => {
2022
+ const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2023
+ initialSelectedPlusMemberMode
2024
+ );
2025
+ const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2026
+ const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2027
+ const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2028
+ const shippingMethodsContext = useShippingMethods({
2029
+ variant,
2030
+ plusMemberMetafields: memberSetting,
2031
+ selectedPlusMemberMode,
2032
+ profile
2033
+ });
2034
+ const { monthlyVariant, annualVariant } = usePlusMemberVariants({
2035
+ memberSetting
2036
+ });
2037
+ const selectedPlusMemberVariant = react.useMemo(() => {
2038
+ if (selectedPlusMemberMode === "free" /* FREE */) {
2039
+ return void 0;
2040
+ }
2041
+ return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
2042
+ }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
2043
+ return /* @__PURE__ */ jsxRuntime.jsx(
2044
+ PlusMemberContext.Provider,
2045
+ {
2046
+ value: {
2047
+ variant,
2048
+ plusMemberMetafields: memberSetting,
2049
+ selectedPlusMemberMode,
2050
+ setSelectedPlusMemberMode,
2051
+ selectedShippingMethod,
2052
+ setSelectedShippingMethod,
2053
+ shippingMethodsContext,
2054
+ showMoreShippingMethod,
2055
+ setShowMoreShippingMethod,
2056
+ selectedPlusMemberVariant,
2057
+ product,
2058
+ showPlusMemberBenefit,
2059
+ setShowPlusMemberBenefit,
2060
+ profile
2061
+ },
2062
+ children
2063
+ }
2064
+ );
2065
+ };
2066
+
2067
+ // src/hooks/cart/use-add-to-cart.ts
2068
+ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2069
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
2070
+ const { cart, addCustomAttributes, memberSetting, profile, customer } = useCartContext();
2071
+ const { trigger: applyCartCodes } = useApplyCartCodes();
2072
+ const { trigger: removeInvalidCodes } = useRemoveCartCodes();
2073
+ const { trigger: addCartLines2 } = useAddCartLines();
2074
+ const { trigger: createCart4 } = useCreateCart({
2075
+ updateCookie: true
2076
+ });
2077
+ const { hasPlusMember } = useHasPlusMemberInCart({
2078
+ memberSetting,
2079
+ cart
2080
+ });
2081
+ const { attributes: cartAttributes } = useCartAttributes({
2082
+ profile,
2083
+ customer,
2084
+ cart,
2085
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2086
+ });
2087
+ const addToCart = react.useCallback(
2088
+ async (_key, { arg }) => {
2089
+ const {
2090
+ lineItems,
2091
+ cartId: providedCartId,
2092
+ discountCodes,
2093
+ gtmParams = {},
2094
+ buyerIdentity,
2095
+ needCreateCart = false,
2096
+ onCodesInvalid,
2097
+ replaceExistingCodes,
2098
+ customAttributes
2099
+ } = arg;
2100
+ if (!lineItems || lineItems.length === 0) {
2101
+ return;
2102
+ }
2103
+ performanceAdapter?.addToCartStart();
2104
+ const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
2105
+ const lines = linesWithFunctionAttributes.map((item) => ({
2106
+ merchandiseId: item.variant?.id || "",
2107
+ quantity: item.quantity || 1,
2108
+ attributes: item.attributes,
2109
+ sellingPlanId: item.sellingPlanId
2110
+ })).filter((item) => item.merchandiseId && item.quantity);
2111
+ if (lines.length === 0) {
2112
+ return;
2113
+ }
2114
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
2115
+ let resultCart = null;
2116
+ if (!cartId) {
2117
+ resultCart = await createCart4({
2118
+ lines,
2119
+ buyerIdentity,
2120
+ discountCodes,
2121
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2122
+ // 初次加购时,就把所有 cart attributes 带上
2123
+ });
2124
+ } else {
2125
+ resultCart = await addCartLines2({
2126
+ cartId,
2127
+ lines
2128
+ });
2129
+ console.log("npm addCartLines resultCart", resultCart);
2130
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
2131
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
2132
+ if (unapplicableCodes.length > 0) {
2133
+ if (onCodesInvalid) {
2134
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
2135
+ if (handledCart) {
2136
+ resultCart = handledCart;
2137
+ }
2138
+ } else {
2139
+ await removeInvalidCodes({
2140
+ discountCodes: unapplicableCodes
2141
+ });
2142
+ }
2143
+ }
2144
+ }
2145
+ if (resultCart && discountCodes && discountCodes.length > 0) {
2146
+ applyCartCodes({
2147
+ replaceExistingCodes,
2148
+ discountCodes
2149
+ });
2150
+ }
2151
+ if (customAttributes && customAttributes.length > 0) {
2152
+ addCustomAttributes(customAttributes);
2153
+ }
2154
+ }
2155
+ if (withTrack) {
2156
+ trackAddToCartGA({
2157
+ lineItems,
2158
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2159
+ });
2160
+ trackAddToCartFBQ({ lineItems });
2161
+ }
2162
+ performanceAdapter?.addToCartEnd();
2163
+ return resultCart;
2164
+ },
2165
+ [
2166
+ client,
2167
+ locale,
2168
+ cartCookieAdapter,
2169
+ userAdapter,
2170
+ cart,
2171
+ withTrack,
2172
+ performanceAdapter,
2173
+ createCart4,
2174
+ addCartLines2,
2175
+ applyCartCodes,
2176
+ removeInvalidCodes,
2177
+ addCustomAttributes,
2178
+ config
2179
+ ]
2180
+ );
2181
+ return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
2182
+ }
2183
+ function useUpdateCartLines(options) {
2184
+ const { client, locale, cartCookieAdapter } = useShopify();
2185
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
2186
+ const updateLines = react.useCallback(
2187
+ async (_key, { arg }) => {
2188
+ const updatedCart = await shopifySdk.updateCartLines(client, {
2189
+ ...arg,
2190
+ metafieldIdentifiers,
2191
+ cookieAdapter: cartCookieAdapter
2192
+ });
2193
+ if (updatedCart) {
2194
+ mutateCart(updatedCart);
2195
+ }
2196
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
2197
+ return updatedCart;
2198
+ },
2199
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2200
+ );
2201
+ return useSWRMutation__default.default("update-cart-lines", updateLines, options);
2202
+ }
2203
+ function useUpdateCartAttributes({
2204
+ mutate,
2205
+ metafieldIdentifiers,
2206
+ disabled = false,
2207
+ swrOptions
2208
+ }) {
2209
+ const { client, locale, cartCookieAdapter } = useShopify();
2210
+ const updateAttributes = react.useCallback(
2211
+ async (_key, { arg }) => {
2212
+ if (disabled) {
2213
+ return void 0;
2214
+ }
2215
+ const updatedCart = await shopifySdk.updateCartAttributes(client, {
2216
+ ...arg,
2217
+ metafieldIdentifiers,
2218
+ cookieAdapter: cartCookieAdapter
2219
+ });
2220
+ if (updatedCart) {
2221
+ mutate(updatedCart);
2222
+ }
2223
+ return updatedCart;
2224
+ },
2225
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
2226
+ );
2227
+ return useSWRMutation__default.default("update-cart-attributes", updateAttributes, swrOptions);
2228
+ }
2229
+ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2230
+ const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2231
+ const { profile, customer, memberSetting } = useCartContext();
2232
+ const isLoggedIn = userAdapter?.isLoggedIn || false;
2233
+ const buyNow = react.useCallback(
2234
+ async (_key, { arg }) => {
2235
+ const {
2236
+ lineItems,
2237
+ discountCodes,
2238
+ gtmParams = {},
2239
+ buyerIdentity,
2240
+ fbqTrackConfig,
2241
+ customAttributes,
2242
+ metafieldIdentifiers,
2243
+ redirectToCheckout = true
2244
+ } = arg;
2245
+ if (!lineItems || lineItems.length === 0) {
2246
+ return;
2247
+ }
2248
+ const { hasPlusMember } = hasPlusMemberInLines({
2249
+ memberSetting,
2250
+ lines: lineItems
2251
+ });
2252
+ const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2253
+ const cartAttributes = getCartAttributes({
2254
+ profile,
2255
+ customer,
2256
+ memberType,
2257
+ currentUrl: window.location.href
2258
+ });
2259
+ const linesWithFunctionAttributes = getLinesWithAttributes({
2260
+ lineItems
2261
+ });
2262
+ const lines = linesWithFunctionAttributes.map((item) => ({
2263
+ merchandiseId: item.variant?.id || "",
2264
+ quantity: item.quantity || 1,
2265
+ attributes: item.attributes,
2266
+ sellingPlanId: item.sellingPlanId
2267
+ })).filter((item) => item.merchandiseId);
2268
+ if (lines.length === 0) {
2269
+ return;
2270
+ }
2271
+ const resultCart = await shopifySdk.createCart(client, {
2272
+ lines,
2273
+ metafieldIdentifiers,
2274
+ cookieAdapter: cartCookieAdapter,
2275
+ buyerIdentity,
2276
+ discountCodes,
2277
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2278
+ });
2279
+ if (!resultCart) {
2280
+ throw new Error("Failed to create cart for buy now");
2281
+ }
2282
+ if (withTrack && resultCart.lineItems) {
2283
+ trackBuyNowGA({
2284
+ lineItems,
2285
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2286
+ });
2287
+ if (fbqTrackConfig) {
2288
+ trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
2289
+ }
2290
+ }
2291
+ if (redirectToCheckout) {
2292
+ if (resultCart.url) {
2293
+ if (typeof window !== "undefined") {
2294
+ window.location.href = resultCart.url;
2295
+ }
2296
+ } else {
2297
+ throw new Error("Failed to get checkout URL");
2298
+ }
2299
+ }
2300
+ return resultCart;
2301
+ },
2302
+ [client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
2303
+ );
2304
+ return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
2305
+ }
2306
+
2307
+ // src/hooks/cart/types/price-discount.ts
2308
+ var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
2309
+ PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
2310
+ PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
2311
+ return PriceDiscountType2;
2312
+ })(PriceDiscountType || {});
2313
+ var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
2314
+ PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
2315
+ PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
2316
+ return PriceBasePriceType2;
2317
+ })(PriceBasePriceType || {});
2318
+ function useProduct(options = {}) {
2319
+ const { client, locale } = useShopify();
2320
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2321
+ return useSWR__default.default(
2322
+ handle ? ["product", locale, handle, metafieldIdentifiers] : null,
2323
+ () => shopifySdk.getProduct(client, {
2324
+ handle,
2325
+ locale,
2326
+ metafieldIdentifiers
2327
+ }),
2328
+ swrOptions
2329
+ );
2330
+ }
2331
+ function useAllProducts(options = {}) {
2332
+ const { client, locale } = useShopify();
2333
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2334
+ return useSWR__default.default(
2335
+ ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2336
+ () => shopifySdk.getAllProducts(client, {
2337
+ locale,
2338
+ first,
2339
+ query,
2340
+ sortKey,
2341
+ reverse,
2342
+ metafieldIdentifiers
2343
+ }),
2344
+ swrOptions
2345
+ );
2346
+ }
2347
+ function getFirstAvailableVariant(product) {
2348
+ const availableVariant = product.variants.find((v) => v.availableForSale);
2349
+ return availableVariant || product.variants[0];
2350
+ }
2351
+ function getVariantFromSelectedOptions(product, selectedOptions) {
2352
+ return product.variants.find((variant) => {
2353
+ return variant.selectedOptions.every((option) => {
2354
+ return selectedOptions[option.name] === option.value;
2355
+ });
2356
+ });
2357
+ }
2358
+ function useVariant({
2359
+ product,
2360
+ selectedOptions
2361
+ }) {
2362
+ const [variant, setVariant] = react.useState(
2363
+ product ? getFirstAvailableVariant(product) : void 0
2364
+ );
2365
+ react.useEffect(() => {
2366
+ if (!product) {
2367
+ setVariant(void 0);
2368
+ return;
2369
+ }
2370
+ const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
2371
+ if (newVariant && newVariant.id !== variant?.id) {
2372
+ setVariant(newVariant);
2373
+ } else if (!newVariant) {
2374
+ setVariant(getFirstAvailableVariant(product));
2375
+ }
2376
+ }, [selectedOptions, product, variant?.id]);
1661
2377
  return variant;
1662
2378
  }
1663
2379
  var FAKE_PRICE = 999999999e-2;
@@ -2062,713 +2778,140 @@ async function performSearch(client, locale, searchQuery, first = 20, types = ["
2062
2778
  handle
2063
2779
  title
2064
2780
  description
2065
- featuredImage {
2066
- url
2067
- altText
2068
- }
2069
- }
2070
- }
2071
- }
2072
- pageInfo {
2073
- hasNextPage
2074
- endCursor
2075
- }
2076
- }
2077
- }
2078
- `
2079
- );
2080
- const data = await client.query(query, {
2081
- query: searchQuery,
2082
- first,
2083
- types
2084
- });
2085
- if (!data || !data.search) {
2086
- return void 0;
2087
- }
2088
- const items = data.search.edges?.map((edge) => {
2089
- const node = edge.node;
2090
- const item = {
2091
- type: node.__typename.toUpperCase(),
2092
- id: node.id,
2093
- handle: node.handle,
2094
- title: node.title
2095
- };
2096
- if (node.__typename === "Product") {
2097
- item.description = node.description;
2098
- item.image = node.featuredImage ? {
2099
- url: node.featuredImage.url,
2100
- altText: node.featuredImage.altText
2101
- } : void 0;
2102
- } else if (node.__typename === "Article") {
2103
- item.description = node.excerpt;
2104
- item.image = node.image ? {
2105
- url: node.image.url,
2106
- altText: node.image.altText
2107
- } : void 0;
2108
- }
2109
- return item;
2110
- }) || [];
2111
- return {
2112
- items,
2113
- totalCount: data.search.totalCount || 0,
2114
- pageInfo: data.search.pageInfo
2115
- };
2116
- }
2117
- function useSearch(options = {}) {
2118
- const { client, locale } = useShopify();
2119
- const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2120
- return useSWR__default.default(
2121
- query ? ["search", locale, query, first, types] : null,
2122
- () => performSearch(client, locale, query, first, types),
2123
- swrOptions
2124
- );
2125
- }
2126
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
2127
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2128
- const query = (
2129
- /* GraphQL */
2130
- `
2131
- query getSiteInfo(
2132
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2133
- ) @inContext(language: $language) {
2134
- shop {
2135
- name
2136
- description
2137
- primaryDomain {
2138
- url
2139
- host
2140
- }
2141
- brand {
2142
- logo {
2143
- image {
2144
- url
2145
- }
2146
- }
2147
- colors {
2148
- primary {
2149
- background
2150
- }
2151
- secondary {
2152
- background
2781
+ featuredImage {
2782
+ url
2783
+ altText
2784
+ }
2153
2785
  }
2154
2786
  }
2155
2787
  }
2156
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2788
+ pageInfo {
2789
+ hasNextPage
2790
+ endCursor
2791
+ }
2157
2792
  }
2158
2793
  }
2159
2794
  `
2160
2795
  );
2161
- const variables = {};
2162
- if (hasMetafields) {
2163
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2164
- }
2165
- const data = await client.query(query, variables);
2166
- if (!data || !data.shop) {
2796
+ const data = await client.query(query, {
2797
+ query: searchQuery,
2798
+ first,
2799
+ types
2800
+ });
2801
+ if (!data || !data.search) {
2167
2802
  return void 0;
2168
2803
  }
2169
- const shop = data.shop;
2170
- const metafields = shop.metafields?.reduce((acc, mf) => {
2171
- if (mf && mf.key) {
2172
- acc[mf.key] = mf.value;
2804
+ const items = data.search.edges?.map((edge) => {
2805
+ const node = edge.node;
2806
+ const item = {
2807
+ type: node.__typename.toUpperCase(),
2808
+ id: node.id,
2809
+ handle: node.handle,
2810
+ title: node.title
2811
+ };
2812
+ if (node.__typename === "Product") {
2813
+ item.description = node.description;
2814
+ item.image = node.featuredImage ? {
2815
+ url: node.featuredImage.url,
2816
+ altText: node.featuredImage.altText
2817
+ } : void 0;
2818
+ } else if (node.__typename === "Article") {
2819
+ item.description = node.excerpt;
2820
+ item.image = node.image ? {
2821
+ url: node.image.url,
2822
+ altText: node.image.altText
2823
+ } : void 0;
2173
2824
  }
2174
- return acc;
2175
- }, {});
2825
+ return item;
2826
+ }) || [];
2176
2827
  return {
2177
- name: shop.name,
2178
- description: shop.description,
2179
- primaryDomain: shop.primaryDomain,
2180
- brand: shop.brand ? {
2181
- logo: shop.brand.logo,
2182
- colors: shop.brand.colors ? {
2183
- primary: shop.brand.colors.primary?.background,
2184
- secondary: shop.brand.colors.secondary?.background
2185
- } : void 0
2186
- } : void 0,
2187
- metafields
2828
+ items,
2829
+ totalCount: data.search.totalCount || 0,
2830
+ pageInfo: data.search.pageInfo
2188
2831
  };
2189
2832
  }
2190
- function useSite(options = {}) {
2833
+ function useSearch(options = {}) {
2191
2834
  const { client, locale } = useShopify();
2192
- const { metafieldIdentifiers, ...swrOptions } = options;
2193
- return useSWR__default.default(
2194
- ["site", locale, metafieldIdentifiers],
2195
- () => getSiteInfo(client, locale, metafieldIdentifiers),
2196
- swrOptions
2197
- );
2198
- }
2199
-
2200
- // src/hooks/member/plus/types.ts
2201
- var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
2202
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
2203
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
2204
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
2205
- return PLUS_MEMBER_TYPE2;
2206
- })(PLUS_MEMBER_TYPE || {});
2207
- var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
2208
- PlusMemberMode2["MONTHLY"] = "monthly";
2209
- PlusMemberMode2["ANNUAL"] = "annual";
2210
- return PlusMemberMode2;
2211
- })(PlusMemberMode || {});
2212
- var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
2213
- DeliveryPlusType2["FREE"] = "free";
2214
- DeliveryPlusType2["MONTHLY"] = "monthly";
2215
- DeliveryPlusType2["ANNUAL"] = "annual";
2216
- return DeliveryPlusType2;
2217
- })(DeliveryPlusType || {});
2218
- var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
2219
- ShippingMethodMode2["FREE"] = "free";
2220
- ShippingMethodMode2["TDD"] = "tdd";
2221
- ShippingMethodMode2["NDD"] = "ndd";
2222
- return ShippingMethodMode2;
2223
- })(ShippingMethodMode || {});
2224
- var createInitialValue = () => ({
2225
- zipCode: "",
2226
- plusMemberMetafields: {},
2227
- setZipCode: () => {
2228
- },
2229
- allowNextDayDelivery: false,
2230
- setAllowNextDayDelivery: () => {
2231
- },
2232
- allowThirdDayDelivery: false,
2233
- setAllowThirdDayDelivery: () => {
2234
- },
2235
- selectedPlusMemberMode: "free",
2236
- setSelectedPlusMemberMode: () => {
2237
- },
2238
- showAreaCheckModal: false,
2239
- setShowAreaCheckModal: () => {
2240
- },
2241
- selectedShippingMethod: void 0,
2242
- setSelectedShippingMethod: () => {
2243
- },
2244
- showTip: false,
2245
- setShowTip: () => {
2246
- },
2247
- showMoreShippingMethod: false,
2248
- setShowMoreShippingMethod: () => {
2249
- },
2250
- variant: {},
2251
- product: {},
2252
- shippingMethodsContext: {
2253
- freeShippingMethods: [],
2254
- paymentShippingMethods: [],
2255
- nddOverweight: false,
2256
- tddOverweight: false
2257
- },
2258
- selectedPlusMemberProduct: null,
2259
- plusMemberProducts: [],
2260
- showPlusMemberBenefit: false,
2261
- setShowPlusMemberBenefit: () => {
2262
- },
2263
- deleteMarginBottom: false,
2264
- setDeleteMarginBottom: () => {
2265
- },
2266
- profile: void 0,
2267
- locale: void 0
2268
- });
2269
- var PlusMemberContext = react.createContext(createInitialValue());
2270
- function usePlusMemberContext() {
2271
- return react.useContext(PlusMemberContext);
2272
- }
2273
- function usePlusMonthlyProductVariant() {
2274
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2275
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2276
- const plusMonthlyProductVariant = react.useMemo(() => {
2277
- const product = plusMemberProducts?.find(
2278
- (item) => item?.handle === plusMonthly?.handle
2279
- );
2280
- const productVariant = product?.variants?.find(
2281
- (item) => item.sku === plusMonthly?.sku
2282
- );
2283
- return productVariant;
2284
- }, [plusMemberProducts, plusMonthly]);
2285
- return plusMonthlyProductVariant;
2286
- }
2287
- function usePlusAnnualProductVariant() {
2288
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2289
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2290
- const plusAnnualProductVariant = react.useMemo(() => {
2291
- const product = plusMemberProducts?.find(
2292
- (item) => item?.handle === plusAnnual?.handle
2293
- );
2294
- const productVariant = product?.variants?.find(
2295
- (item) => item.sku === plusAnnual?.sku
2296
- );
2297
- return productVariant;
2298
- }, [plusMemberProducts, plusAnnual]);
2299
- return plusAnnualProductVariant;
2300
- }
2301
- function useShippingMethods(options) {
2302
- const {
2303
- variant,
2304
- plusMemberMetafields,
2305
- selectedPlusMemberMode,
2306
- isPlus = false,
2307
- nddCoupon,
2308
- tddCoupon
2309
- } = options;
2310
- const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2311
- const nddOverweight = react.useMemo(() => {
2312
- return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
2313
- }, [shippingMethod?.overWeight_ndd, variant?.weight]);
2314
- const tddOverweight = react.useMemo(() => {
2315
- return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
2316
- }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2317
- const paymentShippingMethods = react.useMemo(() => {
2318
- const weight = variant?.weight || 0;
2319
- const methods = plus_shipping?.shipping_methods?.filter(
2320
- ({ weight_low, weight_high, __mode, __plus }) => {
2321
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2322
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2323
- }
2324
- ) || [];
2325
- return methods.map((method) => {
2326
- let disabled = false;
2327
- const selectedFreeMember = selectedPlusMemberMode === "free";
2328
- if (method.__mode === "ndd" /* NDD */) {
2329
- disabled = selectedFreeMember || nddOverweight;
2330
- } else if (method.__mode === "tdd" /* TDD */) {
2331
- disabled = selectedFreeMember || tddOverweight;
2332
- }
2333
- return {
2334
- ...method,
2335
- id: method.__mode + method.__code,
2336
- useCoupon: false,
2337
- subtitle: plus_shipping?.directly || "",
2338
- disabled
2339
- };
2340
- });
2341
- }, [
2342
- nddOverweight,
2343
- plus_shipping?.directly,
2344
- plus_shipping?.shipping_methods,
2345
- selectedPlusMemberMode,
2346
- tddOverweight,
2347
- variant?.weight
2348
- ]);
2349
- const nddPrice = react.useMemo(() => {
2350
- const weight = variant?.weight || 0;
2351
- const nddMethod = paymentShippingMethods.find(
2352
- ({ __mode, weight_high, weight_low }) => {
2353
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2354
- return __mode === "ndd" && fitWeight;
2355
- }
2356
- );
2357
- return nddMethod?.price || 0;
2358
- }, [variant?.weight, paymentShippingMethods]);
2359
- const tddPrice = react.useMemo(() => {
2360
- const weight = variant?.weight || 0;
2361
- const tddMethod = paymentShippingMethods.find(
2362
- ({ __mode, weight_high, weight_low }) => {
2363
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2364
- return __mode === "tdd" && fitWeight;
2365
- }
2366
- );
2367
- return tddMethod?.price || 0;
2368
- }, [variant?.weight, paymentShippingMethods]);
2369
- const freeShippingMethods = react.useMemo(() => {
2370
- const weight = variant?.weight || 0;
2371
- let methods = plus_shipping?.shipping_methods?.filter(
2372
- ({ __mode, __plus, weight_low, weight_high }) => {
2373
- if (__mode === "free" /* FREE */) {
2374
- return true;
2375
- }
2376
- if (isPlus) {
2377
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2378
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2379
- return hasCoupon && fitWeight && !__plus;
2380
- } else {
2381
- return __plus;
2382
- }
2383
- }
2384
- ) || [];
2385
- if (isPlus) {
2386
- methods = methods.sort((a, b) => {
2387
- if (b.__mode === "free" /* FREE */) return -1;
2388
- return 0;
2389
- });
2390
- }
2391
- return methods.map((method) => {
2392
- let price = 0;
2393
- let coupon;
2394
- let disabled;
2395
- if (method.__mode !== "free" /* FREE */) {
2396
- switch (method.__mode) {
2397
- case "tdd":
2398
- price = tddPrice;
2399
- coupon = tddCoupon || nddCoupon;
2400
- break;
2401
- case "ndd":
2402
- price = nddPrice;
2403
- coupon = nddCoupon;
2404
- break;
2405
- }
2406
- disabled = selectedPlusMemberMode === "free";
2407
- if (method.__mode === "ndd" /* NDD */) {
2408
- disabled = disabled || nddOverweight;
2409
- } else if (method.__mode === "tdd" /* TDD */) {
2410
- disabled = disabled || tddOverweight;
2411
- }
2412
- }
2413
- return {
2414
- ...method,
2415
- id: method.__mode + method.__code,
2416
- useCoupon: true,
2417
- disabled,
2418
- coupon,
2419
- price
2420
- };
2421
- });
2422
- }, [
2423
- variant?.weight,
2424
- plus_shipping?.shipping_methods,
2425
- isPlus,
2426
- nddCoupon,
2427
- tddCoupon,
2428
- selectedPlusMemberMode,
2429
- tddPrice,
2430
- nddPrice,
2431
- nddOverweight,
2432
- tddOverweight
2433
- ]);
2434
- return {
2435
- freeShippingMethods,
2436
- paymentShippingMethods,
2437
- nddOverweight,
2438
- tddOverweight
2439
- };
2835
+ const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2836
+ return useSWR__default.default(
2837
+ query ? ["search", locale, query, first, types] : null,
2838
+ () => performSearch(client, locale, query, first, types),
2839
+ swrOptions
2840
+ );
2440
2841
  }
2441
- function useShippingMethodAvailableCheck() {
2442
- const {
2443
- zipCode,
2444
- allowNextDayDelivery,
2445
- allowThirdDayDelivery,
2446
- selectedShippingMethod,
2447
- setSelectedShippingMethod,
2448
- setShowTip,
2449
- shippingMethodsContext
2450
- } = usePlusMemberContext();
2451
- react.useEffect(() => {
2452
- const freeShippingMethod = shippingMethodsContext.freeShippingMethods[0];
2453
- const standardShippingMethod = shippingMethodsContext.freeShippingMethods?.find(
2454
- (item) => item.__mode === "free" /* FREE */
2455
- );
2456
- const freeTDD = shippingMethodsContext.freeShippingMethods.find(
2457
- (item) => item.__mode === "tdd" /* TDD */
2458
- );
2459
- const paymentTDD = shippingMethodsContext.paymentShippingMethods.find(
2460
- (item) => item.__mode === "tdd" /* TDD */
2461
- );
2462
- if (zipCode) {
2463
- console.log(
2464
- "allowNextDayDelivery, allowThirdDayDelivery:",
2465
- allowNextDayDelivery,
2466
- allowThirdDayDelivery
2467
- );
2468
- if (!allowNextDayDelivery && !allowThirdDayDelivery) {
2469
- setShowTip(true);
2470
- setSelectedShippingMethod(standardShippingMethod);
2471
- } else {
2472
- if (selectedShippingMethod?.__mode === "ndd" /* NDD */ && !allowNextDayDelivery) {
2473
- setShowTip(true);
2474
- if (allowThirdDayDelivery) {
2475
- if (selectedShippingMethod.useCoupon) {
2476
- const method = freeTDD || freeShippingMethod;
2477
- if (method) setSelectedShippingMethod(method);
2478
- } else {
2479
- const method = paymentTDD || freeShippingMethod;
2480
- if (method) setSelectedShippingMethod(method);
2842
+ async function getSiteInfo(client, locale, metafieldIdentifiers) {
2843
+ const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2844
+ const query = (
2845
+ /* GraphQL */
2846
+ `
2847
+ query getSiteInfo(
2848
+ ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2849
+ ) @inContext(language: $language) {
2850
+ shop {
2851
+ name
2852
+ description
2853
+ primaryDomain {
2854
+ url
2855
+ host
2856
+ }
2857
+ brand {
2858
+ logo {
2859
+ image {
2860
+ url
2861
+ }
2862
+ }
2863
+ colors {
2864
+ primary {
2865
+ background
2866
+ }
2867
+ secondary {
2868
+ background
2481
2869
  }
2482
- } else {
2483
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2484
2870
  }
2485
- } else if (
2486
- // TDD 无法使用
2487
- selectedShippingMethod?.__mode === "tdd" /* TDD */ && !allowThirdDayDelivery
2488
- ) {
2489
- setShowTip(true);
2490
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2491
2871
  }
2872
+ ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2492
2873
  }
2493
2874
  }
2494
- }, [
2495
- allowNextDayDelivery,
2496
- allowThirdDayDelivery,
2497
- zipCode,
2498
- shippingMethodsContext,
2499
- selectedShippingMethod,
2500
- setSelectedShippingMethod,
2501
- setShowTip
2502
- ]);
2503
- }
2504
- var useReplaceCartPlusMember = () => {
2505
- const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
2506
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2507
- const { cart } = useCartContext();
2508
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2509
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2510
- const handler = react.useCallback(async () => {
2511
- const plusMonthlyInCart = cart?.lineItems.find(
2512
- (item) => item.variant?.sku === plusMonthly?.sku
2513
- );
2514
- const plusAnnualInCart = cart?.lineItems.find(
2515
- (item) => item.variant?.sku === plusAnnual?.sku
2516
- );
2517
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
2518
- await removeCartLines2({
2519
- lineIds: [plusMonthlyInCart.id]
2520
- });
2521
- } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
2522
- await removeCartLines2({
2523
- lineIds: [plusAnnualInCart.id]
2524
- });
2525
- }
2526
- }, [
2527
- cart?.lineItems,
2528
- selectedPlusMemberMode,
2529
- plusMonthly?.sku,
2530
- plusAnnual?.sku,
2531
- removeCartLines2
2532
- ]);
2533
- return handler;
2534
- };
2535
- var usePlusMemberDeliveryCodes = ({
2536
- deliveryData
2537
- }) => {
2538
- return react.useMemo(
2539
- () => deliveryData?.deliveryCustomData?.discount_code,
2540
- [deliveryData]
2875
+ `
2541
2876
  );
2542
- };
2543
- var usePlusMemberItemCustomAttributes = ({
2544
- deliveryData
2545
- }) => {
2546
- const { deliveryCustomData } = deliveryData || {};
2547
- return react.useMemo(() => {
2548
- const itemCustomAttributes = [];
2549
- if (deliveryCustomData?.is_presale) {
2550
- itemCustomAttributes.push({
2551
- key: "_is_presale",
2552
- value: "true"
2553
- });
2554
- }
2555
- return itemCustomAttributes;
2556
- }, [deliveryCustomData]);
2557
- };
2558
- var usePlusMemberCheckoutCustomAttributes = ({
2559
- deliveryData,
2560
- product,
2561
- variant,
2562
- customer,
2563
- isShowShippingBenefits
2564
- }) => {
2565
- const { deliveryCustomData } = deliveryData || {};
2566
- const { profile } = usePlusMemberContext();
2567
- const userType = react.useMemo(() => {
2568
- const customerInfo = customer;
2569
- if (!customerInfo) {
2570
- return "new_user_unlogin";
2571
- }
2572
- if (customer) {
2573
- const { orders = {} } = customer;
2574
- const edgesLength = orders?.edges?.length;
2575
- if (edgesLength === 1) {
2576
- return "old_user_orders_once";
2577
- } else if (edgesLength && edgesLength > 1) {
2578
- return "old_user_orders_twice";
2579
- }
2580
- }
2581
- return "new_user_login";
2582
- }, [customer]);
2583
- return react.useMemo(() => {
2584
- const checkoutCustomAttributes = [
2585
- {
2586
- key: "_token",
2587
- value: profile?.token || ""
2588
- },
2589
- {
2590
- key: "_last_url",
2591
- value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2592
- },
2593
- {
2594
- key: "_user_type",
2595
- value: userType
2596
- }
2597
- ];
2598
- if (profile) {
2599
- checkoutCustomAttributes.push({
2600
- key: "_login_user",
2601
- value: "1"
2602
- });
2603
- }
2604
- if (deliveryCustomData) {
2605
- checkoutCustomAttributes.push({
2606
- key: "_checkout_delivery_custom",
2607
- value: JSON.stringify({
2608
- ...deliveryCustomData,
2609
- is_prime: profile?.isPlus
2610
- })
2611
- });
2612
- }
2613
- if (variant?.metafields?.presell) {
2614
- checkoutCustomAttributes.push({
2615
- key: "_presale",
2616
- value: "true"
2617
- });
2618
- }
2619
- if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2620
- checkoutCustomAttributes.push({
2621
- key: "_hide_shipping",
2622
- value: "true"
2623
- });
2624
- }
2625
- return checkoutCustomAttributes;
2626
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2627
- };
2628
- function useAutoRemovePlusMemberInCart({
2629
- cart,
2630
- profile,
2631
- memberSetting
2632
- }) {
2633
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2634
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2635
- react.useEffect(() => {
2636
- if (!cart || !plus_monthly_product || !plus_annual_product) return;
2637
- const removePlusProduct = async (productType) => {
2638
- if (!productType) return;
2639
- const product = cart.lineItems?.find(
2640
- (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2641
- );
2642
- if (product) {
2643
- await removeCartLines2({
2644
- lineIds: [product.id]
2645
- });
2646
- }
2647
- };
2648
- if (profile?.isMonthlyPlus) {
2649
- removePlusProduct(plus_monthly_product);
2650
- }
2651
- if (profile?.isAnnualPlus) {
2652
- removePlusProduct(plus_annual_product);
2653
- }
2654
- }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2655
- }
2656
- function useAddPlusMemberProductsToCart({
2657
- cart,
2658
- profile
2659
- }) {
2660
- const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2661
- const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2662
- memberSetting: plusMemberMetafields,
2663
- cart
2664
- });
2665
- const plusMemberProduct = react.useMemo(() => {
2666
- if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2667
- return void 0;
2668
- }
2669
- if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2670
- return void 0;
2671
- }
2672
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2673
- return void 0;
2674
- }
2675
- if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2676
- return void 0;
2677
- }
2678
- if (!profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2679
- return void 0;
2877
+ const variables = {};
2878
+ if (hasMetafields) {
2879
+ variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2880
+ }
2881
+ const data = await client.query(query, variables);
2882
+ if (!data || !data.shop) {
2883
+ return void 0;
2884
+ }
2885
+ const shop = data.shop;
2886
+ const metafields = shop.metafields?.reduce((acc, mf) => {
2887
+ if (mf && mf.key) {
2888
+ acc[mf.key] = mf.value;
2680
2889
  }
2681
- return selectedPlusMemberProduct;
2682
- }, [
2683
- selectedPlusMemberMode,
2684
- selectedPlusMemberProduct?.variant,
2685
- selectedPlusMemberProduct?.product,
2686
- hasMonthlyPlus,
2687
- hasAnnualPlus
2688
- ]);
2689
- return plusMemberProduct;
2890
+ return acc;
2891
+ }, {});
2892
+ return {
2893
+ name: shop.name,
2894
+ description: shop.description,
2895
+ primaryDomain: shop.primaryDomain,
2896
+ brand: shop.brand ? {
2897
+ logo: shop.brand.logo,
2898
+ colors: shop.brand.colors ? {
2899
+ primary: shop.brand.colors.primary?.background,
2900
+ secondary: shop.brand.colors.secondary?.background
2901
+ } : void 0
2902
+ } : void 0,
2903
+ metafields
2904
+ };
2690
2905
  }
2691
- var PlusMemberProvider = ({
2692
- variant,
2693
- product,
2694
- memberSetting,
2695
- initialSelectedPlusMemberMode = "free",
2696
- profile,
2697
- locale,
2698
- children
2699
- }) => {
2700
- const [zipCode, setZipCode] = react.useState("");
2701
- const [showTip, setShowTip] = react.useState(false);
2702
- const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2703
- initialSelectedPlusMemberMode
2704
- );
2705
- const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2706
- const [allowNextDayDelivery, setAllowNextDayDelivery] = react.useState(false);
2707
- const [allowThirdDayDelivery, setAllowThirdDayDelivery] = react.useState(false);
2708
- const [showAreaCheckModal, setShowAreaCheckModal] = react.useState(false);
2709
- const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2710
- const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2711
- const [deleteMarginBottom, setDeleteMarginBottom] = react.useState(false);
2712
- const shippingMethodsContext = useShippingMethods({
2713
- variant,
2714
- plusMemberMetafields: memberSetting,
2715
- selectedPlusMemberMode});
2716
- const plusMemberHandles = react.useMemo(() => {
2717
- return [
2718
- memberSetting?.plus_monthly_product?.handle,
2719
- memberSetting?.plus_annual_product?.handle
2720
- ].filter(Boolean);
2721
- }, [memberSetting]);
2722
- const { data: plusMemberProducts = [] } = useProductsByHandles({
2723
- handles: plusMemberHandles
2724
- });
2725
- const selectedPlusMemberProduct = react.useMemo(() => {
2726
- if (selectedPlusMemberMode === "free" /* FREE */) {
2727
- return null;
2728
- }
2729
- const handle = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.handle : memberSetting?.plus_annual_product?.handle;
2730
- const sku = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.sku : memberSetting?.plus_annual_product?.sku;
2731
- const product2 = plusMemberProducts?.find((p) => p.handle === handle);
2732
- const variant2 = product2?.variants?.find((v) => v.sku === sku);
2733
- return product2 && variant2 ? { product: product2, variant: variant2 } : null;
2734
- }, [plusMemberProducts, memberSetting, selectedPlusMemberMode]);
2735
- return /* @__PURE__ */ jsxRuntime.jsx(
2736
- PlusMemberContext.Provider,
2737
- {
2738
- value: {
2739
- variant,
2740
- zipCode,
2741
- setZipCode,
2742
- allowNextDayDelivery,
2743
- setAllowNextDayDelivery,
2744
- allowThirdDayDelivery,
2745
- setAllowThirdDayDelivery,
2746
- plusMemberMetafields: memberSetting,
2747
- selectedPlusMemberMode,
2748
- setSelectedPlusMemberMode,
2749
- showAreaCheckModal,
2750
- setShowAreaCheckModal,
2751
- selectedShippingMethod,
2752
- setSelectedShippingMethod,
2753
- shippingMethodsContext,
2754
- showTip,
2755
- setShowTip,
2756
- showMoreShippingMethod,
2757
- setShowMoreShippingMethod,
2758
- selectedPlusMemberProduct,
2759
- plusMemberProducts,
2760
- product,
2761
- showPlusMemberBenefit,
2762
- setShowPlusMemberBenefit,
2763
- deleteMarginBottom,
2764
- setDeleteMarginBottom,
2765
- profile,
2766
- locale
2767
- },
2768
- children
2769
- }
2906
+ function useSite(options = {}) {
2907
+ const { client, locale } = useShopify();
2908
+ const { metafieldIdentifiers, ...swrOptions } = options;
2909
+ return useSWR__default.default(
2910
+ ["site", locale, metafieldIdentifiers],
2911
+ () => getSiteInfo(client, locale, metafieldIdentifiers),
2912
+ swrOptions
2770
2913
  );
2771
- };
2914
+ }
2772
2915
  function useIntersection(targetRef, options) {
2773
2916
  const {
2774
2917
  callback,
@@ -2955,6 +3098,7 @@ exports.CUSTOMER_ATTRIBUTE_KEY = CUSTOMER_ATTRIBUTE_KEY;
2955
3098
  exports.CUSTOMER_SCRIPT_GIFT_KEY = CUSTOMER_SCRIPT_GIFT_KEY;
2956
3099
  exports.DeliveryPlusType = DeliveryPlusType;
2957
3100
  exports.MAIN_PRODUCT_CODE = MAIN_PRODUCT_CODE;
3101
+ exports.MEMBER_PRICE_ATTRIBUTE_KEY = MEMBER_PRICE_ATTRIBUTE_KEY;
2958
3102
  exports.OrderBasePriceType = OrderBasePriceType;
2959
3103
  exports.OrderDiscountType = OrderDiscountType;
2960
3104
  exports.PLUS_MEMBER_TYPE = PLUS_MEMBER_TYPE;
@@ -2967,9 +3111,6 @@ exports.RuleType = RuleType;
2967
3111
  exports.SCRIPT_CODE_AMOUNT_KEY = SCRIPT_CODE_AMOUNT_KEY;
2968
3112
  exports.ShippingMethodMode = ShippingMethodMode;
2969
3113
  exports.SpendMoneyType = SpendMoneyType;
2970
- exports.atobID = atobID;
2971
- exports.btoaID = btoaID;
2972
- exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
2973
3114
  exports.clearGeoLocationCache = clearGeoLocationCache;
2974
3115
  exports.createMockCartFromLines = createMockCartFromLines;
2975
3116
  exports.currencyCodeMapping = currencyCodeMapping;
@@ -2977,15 +3118,18 @@ exports.defaultSWRMutationConfiguration = defaultSWRMutationConfiguration;
2977
3118
  exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
2978
3119
  exports.formatScriptAutoFreeGift = formatScriptAutoFreeGift;
2979
3120
  exports.getCachedGeoLocation = getCachedGeoLocation;
3121
+ exports.getCartAttributes = getCartAttributes;
2980
3122
  exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
2981
3123
  exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
2982
3124
  exports.getQuery = getQuery;
2983
3125
  exports.getReferralAttributes = getReferralAttributes;
3126
+ exports.getUserType = getUserType;
3127
+ exports.hasPlusMemberInCart = hasPlusMemberInCart;
3128
+ exports.hasPlusMemberInLines = hasPlusMemberInLines;
2984
3129
  exports.normalizeAddToCartLines = normalizeAddToCartLines;
2985
3130
  exports.preCheck = preCheck;
2986
3131
  exports.safeParse = safeParse;
2987
3132
  exports.useAddCartLines = useAddCartLines;
2988
- exports.useAddPlusMemberProductsToCart = useAddPlusMemberProductsToCart;
2989
3133
  exports.useAddToCart = useAddToCart;
2990
3134
  exports.useAllBlogs = useAllBlogs;
2991
3135
  exports.useAllCollections = useAllCollections;
@@ -2995,6 +3139,7 @@ exports.useArticle = useArticle;
2995
3139
  exports.useArticles = useArticles;
2996
3140
  exports.useArticlesInBlog = useArticlesInBlog;
2997
3141
  exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
3142
+ exports.useAvailableDeliveryCoupon = useAvailableDeliveryCoupon;
2998
3143
  exports.useBlog = useBlog;
2999
3144
  exports.useBuyNow = useBuyNow;
3000
3145
  exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
@@ -3008,13 +3153,12 @@ exports.useCreateCart = useCreateCart;
3008
3153
  exports.useExposure = useExposure;
3009
3154
  exports.useGeoLocation = useGeoLocation;
3010
3155
  exports.useHasPlusMemberInCart = useHasPlusMemberInCart;
3156
+ exports.useHasPlusMemberInLines = useHasPlusMemberInLines;
3011
3157
  exports.useIntersection = useIntersection;
3012
- exports.usePlusAnnualProductVariant = usePlusAnnualProductVariant;
3013
3158
  exports.usePlusMemberCheckoutCustomAttributes = usePlusMemberCheckoutCustomAttributes;
3014
3159
  exports.usePlusMemberContext = usePlusMemberContext;
3015
- exports.usePlusMemberDeliveryCodes = usePlusMemberDeliveryCodes;
3016
- exports.usePlusMemberItemCustomAttributes = usePlusMemberItemCustomAttributes;
3017
- exports.usePlusMonthlyProductVariant = usePlusMonthlyProductVariant;
3160
+ exports.usePlusMemberNeedAddToCart = usePlusMemberNeedAddToCart;
3161
+ exports.usePlusMemberVariants = usePlusMemberVariants;
3018
3162
  exports.usePrice = usePrice;
3019
3163
  exports.useProduct = useProduct;
3020
3164
  exports.useProductUrl = useProductUrl;
@@ -3025,7 +3169,6 @@ exports.useReplaceCartPlusMember = useReplaceCartPlusMember;
3025
3169
  exports.useScriptAutoFreeGift = useScriptAutoFreeGift;
3026
3170
  exports.useSearch = useSearch;
3027
3171
  exports.useSelectedOptions = useSelectedOptions;
3028
- exports.useShippingMethodAvailableCheck = useShippingMethodAvailableCheck;
3029
3172
  exports.useShippingMethods = useShippingMethods;
3030
3173
  exports.useSite = useSite;
3031
3174
  exports.useUpdateCartAttributes = useUpdateCartAttributes;