@anker-in/shopify-react 0.1.1-beta.1 → 0.1.1-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -142,6 +142,81 @@ var CODE_AMOUNT_KEY = "_sku_code_money";
142
142
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
143
143
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
144
144
 
145
+ // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
146
+ function normalizeAddToCartLines(lines) {
147
+ return lines.filter((line) => line.variant?.id).map((line, index) => {
148
+ const variant = line.variant;
149
+ const product = variant.product;
150
+ const quantity = line.quantity || 1;
151
+ const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
152
+ const subtotalAmount = price * quantity;
153
+ const totalAmount = subtotalAmount;
154
+ return {
155
+ id: `temp-line-${index}-${variant.id}`,
156
+ // Temporary ID for pre-cart lines
157
+ name: product?.title || variant.title || "",
158
+ quantity,
159
+ variantId: variant.id,
160
+ productId: product?.id || variant.id.split("/").slice(0, -2).join("/"),
161
+ totalAmount,
162
+ subtotalAmount,
163
+ discountAllocations: [],
164
+ customAttributes: line.attributes || [],
165
+ variant: {
166
+ id: variant.id,
167
+ price,
168
+ listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
169
+ sku: variant.sku || "",
170
+ name: variant.title || "",
171
+ image: variant.image ? {
172
+ url: variant.image.url,
173
+ altText: variant.image.altText || void 0
174
+ } : void 0,
175
+ requiresShipping: false,
176
+ // Default value, not available in NormalizedProductVariant
177
+ availableForSale: variant.availableForSale ?? true,
178
+ quantityAvailable: variant.quantityAvailable ?? 0,
179
+ currentlyNotInStock: false,
180
+ // Default value, will be updated when added to cart
181
+ weight: variant.weight,
182
+ metafields: variant.metafields
183
+ },
184
+ product,
185
+ path: product?.handle ? `/products/${product.handle}` : "",
186
+ discounts: [],
187
+ options: variant.selectedOptions?.map((opt) => ({
188
+ name: opt.name,
189
+ value: opt.value
190
+ }))
191
+ };
192
+ });
193
+ }
194
+ function createMockCartFromLines(lines, existingCart) {
195
+ const normalizedLines = normalizeAddToCartLines(lines);
196
+ const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
197
+ const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
198
+ return {
199
+ id: existingCart?.id || "temp-cart-id",
200
+ customerId: existingCart?.customerId,
201
+ email: existingCart?.email,
202
+ createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
203
+ currency: existingCart?.currency || { code: "USD" },
204
+ taxesIncluded: existingCart?.taxesIncluded,
205
+ lineItems: normalizedLines,
206
+ totalLineItemsDiscount: 0,
207
+ orderDiscounts: 0,
208
+ lineItemsSubtotalPrice: subtotalPrice,
209
+ subtotalPrice,
210
+ totalPrice,
211
+ totalTaxAmount: 0,
212
+ discountCodes: existingCart?.discountCodes || [],
213
+ discountAllocations: [],
214
+ url: existingCart?.url || "",
215
+ ready: true,
216
+ customAttributes: existingCart?.customAttributes
217
+ };
218
+ }
219
+
145
220
  // src/hooks/cart/utils/index.ts
146
221
  var getQuery = () => {
147
222
  const url = typeof window !== "undefined" ? window.location.search : "";
@@ -181,25 +256,25 @@ var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
181
256
  return acc + (main_product?.spend_money_type === 1 /* ORIGIN_PRICE */ ? Number(line.subtotalAmount) || 0 : Number(line.totalAmount) || 0);
182
257
  }, 0) || 0;
183
258
  };
184
- var getDiscountEnvAttributeValue = (attributes = []) => {
185
- const attr = attributes.find((attr2) => attr2.key === CUSTOMER_ATTRIBUTE_KEY);
186
- return safeParseJson(attr?.value ?? "") ?? {};
187
- };
188
- var isAttributesEqual = (attrs1 = [], attrs2 = []) => {
189
- if (attrs1.length !== attrs2.length) return false;
190
- const sorted1 = [...attrs1].sort((a, b) => a.key.localeCompare(b.key));
191
- const sorted2 = [...attrs2].sort((a, b) => a.key.localeCompare(b.key));
192
- return sorted1.every(
193
- (attr, i) => attr.key === sorted2[i]?.key && attr.value === sorted2[i]?.value
194
- );
195
- };
196
- var safeParseJson = (str) => {
259
+ var safeParse = (str) => {
197
260
  try {
198
261
  return JSON.parse(str);
199
262
  } catch (err) {
200
263
  return {};
201
264
  }
202
265
  };
266
+ var getDiscountEnvAttributeValue = (attributes = []) => {
267
+ const attr = attributes.find((attr2) => attr2.key === CUSTOMER_ATTRIBUTE_KEY);
268
+ return safeParse(attr?.value ?? "") ?? {};
269
+ };
270
+ var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
271
+ return oldAttributes.some((attr) => {
272
+ const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
273
+ return newAttr ? newAttr.value !== attr.value : true;
274
+ }) || newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || customAttributesNeedRemove.some(
275
+ (removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
276
+ );
277
+ };
203
278
  var containsAll = (source, requiredItems = []) => {
204
279
  if (!requiredItems?.length) return true;
205
280
  const sourceSet = new Set(source);
@@ -366,12 +441,18 @@ var formatFunctionAutoFreeGift = ({
366
441
  };
367
442
  return result;
368
443
  };
369
- var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
444
+ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
370
445
  const tags = react.useMemo(() => customer?.tags || [], [customer?.tags]);
371
446
  const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
372
447
  const dealsType = "";
373
448
  const { client, locale } = useShopify();
374
449
  const giftProductsCache = react.useRef(null);
450
+ const effectiveCart = react.useMemo(() => {
451
+ if (lines && lines.length > 0) {
452
+ return createMockCartFromLines(lines, cart);
453
+ }
454
+ return cart;
455
+ }, [lines, cart]);
375
456
  const { activeCampaign, subtotal } = react.useMemo(() => {
376
457
  for (const campaign of autoFreeGiftConfig) {
377
458
  const { rule_conditions = [], rule_result } = campaign;
@@ -379,7 +460,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
379
460
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
380
461
  if (isPreCheckPassed && spend_get_reward) {
381
462
  const matchedSubtotal = getMatchedMainProductSubTotal(
382
- cart,
463
+ effectiveCart,
383
464
  spend_get_reward.main_product?.variant_list?.map((v) => v.variant_id) || [],
384
465
  {
385
466
  spend_money_type: spend_get_reward.main_product?.spend_money_type || 1,
@@ -393,13 +474,13 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
393
474
  }
394
475
  }
395
476
  return { activeCampaign: null, subtotal: 0 };
396
- }, [autoFreeGiftConfig, cart, tags, dealsType]);
477
+ }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
397
478
  const { qualifyingGift, nextTierGoal } = react.useMemo(() => {
398
479
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
399
480
  return { qualifyingGift: null, nextTierGoal: null };
400
481
  }
401
482
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
402
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
483
+ const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
403
484
  const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
404
485
  if (!qualifyingTier) {
405
486
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
@@ -476,18 +557,33 @@ var useScriptAutoFreeGift = ({
476
557
  campaign,
477
558
  _giveaway,
478
559
  cart,
479
- locale: providedLocale
560
+ locale: providedLocale,
561
+ lines
480
562
  }) => {
481
563
  const { client, locale: contextLocale } = useShopify();
482
564
  const locale = providedLocale || contextLocale;
483
565
  const [points_subscribe, set_points_subscribe] = react.useState(false);
484
566
  const giftProductsCache = react.useRef(null);
567
+ const effectiveCart = react.useMemo(() => {
568
+ if (lines && lines.length > 0) {
569
+ return createMockCartFromLines(lines, cart);
570
+ }
571
+ return cart;
572
+ }, [lines, cart]);
485
573
  react.useEffect(() => {
486
574
  if (locale === "au") {
487
575
  const isPointsSubscribe = Cookies5__default.default.get("points_subscribe");
488
576
  set_points_subscribe(!!isPointsSubscribe);
489
577
  }
490
578
  }, [locale]);
579
+ const isActivityAvailable = react.useMemo(() => {
580
+ if (!campaign) return false;
581
+ const query = getQuery();
582
+ const utmCampaign = Cookies5__default.default.get("utm_campaign") || query?.utm_campaign;
583
+ if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
584
+ return false;
585
+ return true;
586
+ }, [campaign]);
491
587
  const [upgrade_multiple, upgrade_value] = react.useMemo(() => {
492
588
  let upgrade_multiple2 = 1;
493
589
  let upgrade_value2 = 0;
@@ -495,17 +591,17 @@ var useScriptAutoFreeGift = ({
495
591
  upgrade_multiple2 = 1.2;
496
592
  upgrade_value2 = 40;
497
593
  }
498
- cart?.lineItems?.forEach(({ customAttributes }) => {
594
+ effectiveCart?.lineItems?.forEach(({ customAttributes }) => {
499
595
  customAttributes?.forEach(({ key, value }) => {
500
596
  if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
501
597
  if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
502
598
  });
503
599
  });
504
600
  return [upgrade_multiple2, upgrade_value2];
505
- }, [cart?.lineItems, points_subscribe]);
601
+ }, [effectiveCart?.lineItems, points_subscribe]);
506
602
  const breakpoints = react.useMemo(() => {
507
- if (!campaign) return [];
508
- return (campaign.breakpoints || []).map((item) => ({
603
+ if (!isActivityAvailable) return [];
604
+ return (campaign?.breakpoints || []).map((item) => ({
509
605
  breakpoint: new Decimal2__default.default(item.breakpoint).minus(new Decimal2__default.default(upgrade_value)).dividedBy(new Decimal2__default.default(upgrade_multiple)).toFixed(2, Decimal2__default.default.ROUND_DOWN),
510
606
  giveawayProducts: item.giveawayProducts || []
511
607
  }));
@@ -529,25 +625,26 @@ var useScriptAutoFreeGift = ({
529
625
  return true;
530
626
  }, [giftHandles]);
531
627
  const involvedLines = react.useMemo(() => {
532
- if (!campaign) return [];
533
- return (cart?.lineItems || []).filter((line) => {
628
+ if (!isActivityAvailable) return [];
629
+ return (effectiveCart?.lineItems || []).filter((line) => {
534
630
  const isNotGift = line?.totalAmount && Number(line.totalAmount) > 0 && line.customAttributes?.every(
535
631
  (item) => item.key !== _giveaway
536
632
  );
537
633
  const hasCampaignTag = line.product?.tags?.some(
538
- (tag) => campaign.includeTags?.includes(tag.trim()) && line.variant?.availableForSale
634
+ (tag) => campaign?.includeTags?.includes(tag.trim()) && line.variant?.availableForSale
539
635
  );
540
636
  return isNotGift && hasCampaignTag;
541
637
  });
542
- }, [cart?.lineItems, campaign, _giveaway]);
638
+ }, [effectiveCart?.lineItems, isActivityAvailable, _giveaway]);
543
639
  const involvedSubTotal = react.useMemo(() => {
544
- if (!campaign) return new Decimal2__default.default(0);
640
+ if (!isActivityAvailable) return new Decimal2__default.default(0);
545
641
  return involvedLines.reduce((prev, item) => {
546
- const amount = campaign.useTotalAmount ? item.totalAmount : item.subtotalAmount;
642
+ const amount = campaign?.useTotalAmount ? item.totalAmount : item.subtotalAmount;
547
643
  return new Decimal2__default.default(prev).plus(new Decimal2__default.default(amount || 0));
548
644
  }, new Decimal2__default.default(0));
549
- }, [involvedLines, campaign]);
645
+ }, [involvedLines, isActivityAvailable]);
550
646
  const [freeGiftLevel, nextFreeGiftLevel] = react.useMemo(() => {
647
+ if (!isActivityAvailable) return [null, null];
551
648
  const sortedLevels = [...breakpoints].sort(
552
649
  (a, b) => Number(b.breakpoint) - Number(a.breakpoint)
553
650
  );
@@ -691,8 +788,12 @@ var trackAddToCartGA = ({
691
788
  }
692
789
  const { variant } = lineItems[0];
693
790
  const currencyCode = variant.product?.price?.currencyCode;
694
- const price = variant.compareAtPrice?.amount ?? (variant.price?.amount || 0);
695
- const totalPrice = lineItems?.reduce((prev, { variant: variant2 }) => prev.plus(variant2?.finalPrice?.amount ?? price), new Decimal2__default.default(0)).toNumber();
791
+ const totalPrice = lineItems?.reduce(
792
+ (prev, { variant: variant2 }) => prev.plus(
793
+ variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
794
+ ),
795
+ new Decimal2__default.default(0)
796
+ ).toNumber();
696
797
  gaTrack({
697
798
  event: "ga4Event",
698
799
  event_name: "add_to_cart",
@@ -707,7 +808,7 @@ var trackAddToCartGA = ({
707
808
  item_brand: gtmParams?.brand || "",
708
809
  item_category: variant2?.product?.productType || "",
709
810
  item_variant: variant2?.title || variant2?.title,
710
- price,
811
+ price: variant2?.compareAtPrice?.amount ?? variant2?.price?.amount,
711
812
  quantity: quantity || 1
712
813
  })),
713
814
  ...gtmParams?.ga4Params
@@ -722,9 +823,12 @@ var trackBeginCheckoutGA = ({
722
823
  if (!lineItems.length) {
723
824
  return;
724
825
  }
725
- const { variant } = lineItems[0] || {};
726
- const price = variant?.compareAtPrice?.amount ?? (variant?.price?.amount || 0);
727
- const totalPrice = lineItems?.reduce((prev, { variant: variant2 }) => prev.plus(variant2?.finalPrice?.amount ?? price), new Decimal2__default.default(0)).toNumber();
826
+ const totalPrice = lineItems?.reduce(
827
+ (prev, { variant }) => prev.plus(
828
+ variant?.finalPrice?.amount ?? variant?.compareAtPrice?.amount ?? variant?.price?.amount ?? 0
829
+ ),
830
+ new Decimal2__default.default(0)
831
+ ).toNumber();
728
832
  gaTrack({
729
833
  event: "ga4Event",
730
834
  event_name: "begin_checkout",
@@ -739,7 +843,7 @@ var trackBeginCheckoutGA = ({
739
843
  item_brand: gtmParams?.brand || "",
740
844
  item_category: item.variant?.product?.productType,
741
845
  item_variant: item.variant?.title,
742
- price,
846
+ price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
743
847
  quantity: item.quantity || 1
744
848
  })),
745
849
  ...gtmParams?.ga4Params
@@ -755,8 +859,12 @@ var trackBuyNowGA = ({
755
859
  }
756
860
  const { variant } = lineItems[0];
757
861
  const currencyCode = variant.price?.currencyCode;
758
- const price = variant.compareAtPrice?.amount ?? (variant.price?.amount || 0);
759
- const totalPrice = lineItems?.reduce((prev, { variant: variant2 }) => prev.plus(variant2?.finalPrice?.amount ?? price), new Decimal2__default.default(0)).toNumber();
862
+ const totalPrice = lineItems?.reduce(
863
+ (prev, { variant: variant2 }) => prev.plus(
864
+ variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
865
+ ),
866
+ new Decimal2__default.default(0)
867
+ ).toNumber();
760
868
  gaTrack({
761
869
  event: "ga4Event",
762
870
  event_name: "begin_checkout",
@@ -771,7 +879,7 @@ var trackBuyNowGA = ({
771
879
  item_brand: gtmParams?.brand || "",
772
880
  item_category: item.variant?.product?.productType || "",
773
881
  item_variant: item.variant?.title,
774
- price,
882
+ price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
775
883
  quantity: item.quantity || 1
776
884
  })),
777
885
  ...gtmParams?.ga4Params
@@ -914,6 +1022,7 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
914
1022
  if (!resultCart) {
915
1023
  return void 0;
916
1024
  }
1025
+ console.log("npm addCartLines resultCart", resultCart);
917
1026
  if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
918
1027
  const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
919
1028
  if (unapplicableCodes.length > 0) {
@@ -1087,6 +1196,60 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1087
1196
  );
1088
1197
  return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
1089
1198
  }
1199
+ function useCalcGiftsFromLines({
1200
+ lines,
1201
+ customer,
1202
+ scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
1203
+ }) {
1204
+ const { locale } = useShopify();
1205
+ const { cart, autoFreeGiftConfig, gradientGiftsConfig } = useCartContext();
1206
+ const functionGift = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer, lines);
1207
+ const scriptGift = useScriptAutoFreeGift({
1208
+ campaign: gradientGiftsConfig || null,
1209
+ _giveaway: scriptGiveawayKey,
1210
+ cart,
1211
+ locale,
1212
+ lines
1213
+ });
1214
+ const allGiftLines = react.useMemo(() => {
1215
+ const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || [];
1216
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((product) => {
1217
+ const giftProduct = scriptGift.giftProductsResult?.find(
1218
+ (p) => p.handle === product.handle
1219
+ );
1220
+ const variant = giftProduct?.variants?.[0];
1221
+ return {
1222
+ variant: {
1223
+ id: variant?.id || "",
1224
+ handle: product.handle,
1225
+ sku: product.sku
1226
+ },
1227
+ quantity: 1,
1228
+ attributes: [
1229
+ {
1230
+ key: scriptGiveawayKey,
1231
+ value: "true"
1232
+ }
1233
+ ]
1234
+ };
1235
+ }).filter((item) => item.variant.id) : [];
1236
+ return [...functionGiftLines, ...scriptGiftLines];
1237
+ }, [
1238
+ functionGift.qualifyingGift,
1239
+ scriptGift.freeGiftLevel,
1240
+ scriptGift.giftProductsResult,
1241
+ scriptGiveawayKey
1242
+ ]);
1243
+ const hasGifts = react.useMemo(() => {
1244
+ return allGiftLines.length > 0;
1245
+ }, [allGiftLines]);
1246
+ return {
1247
+ functionGift,
1248
+ scriptGift,
1249
+ allGiftLines,
1250
+ hasGifts
1251
+ };
1252
+ }
1090
1253
 
1091
1254
  // src/hooks/cart/types/order-discount.ts
1092
1255
  var OrderDiscountType = /* @__PURE__ */ ((OrderDiscountType2) => {
@@ -1236,8 +1399,6 @@ var useCartAttributes = ({
1236
1399
  memberSetting,
1237
1400
  cart
1238
1401
  });
1239
- console.log("memberSetting", memberSetting);
1240
- console.log("hasPlusMember", hasPlusMember);
1241
1402
  react.useEffect(() => {
1242
1403
  setCurrentUrl(window.location.href);
1243
1404
  }, []);
@@ -1286,15 +1447,19 @@ var useCartAttributes = ({
1286
1447
  ];
1287
1448
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1288
1449
  const functionAttributes = react.useMemo(() => {
1289
- return [
1290
- cart?.discountCodes && {
1450
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1451
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1452
+ );
1453
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1454
+ return hasFunctionEnvAttribute ? [
1455
+ {
1291
1456
  key: "_discounts_function_env",
1292
1457
  value: JSON.stringify({
1293
- discount_code: cart?.discountCodes.map((item) => item.code),
1458
+ discount_code: discountCodes,
1294
1459
  user_tags: customer?.tags || []
1295
1460
  })
1296
1461
  }
1297
- ];
1462
+ ] : [];
1298
1463
  }, [cart]);
1299
1464
  const presellAttributes = react.useMemo(() => {
1300
1465
  return [
@@ -2471,6 +2636,69 @@ var usePlusMemberDeliveryCodes = ({
2471
2636
  [deliveryData]
2472
2637
  );
2473
2638
  };
2639
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2640
+ const { client, locale, cartCookieAdapter } = useShopify();
2641
+ const updateDeliveryOptions = react.useCallback(
2642
+ async (_key, { arg }) => {
2643
+ const updatedCart = await shopifySdk.updateCartDeliveryOptions(client, {
2644
+ ...arg,
2645
+ metafieldIdentifiers,
2646
+ cookieAdapter: cartCookieAdapter
2647
+ });
2648
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2649
+ if (updatedCart) {
2650
+ mutate(updatedCart);
2651
+ }
2652
+ return updatedCart;
2653
+ },
2654
+ [client, locale, cartCookieAdapter, mutate]
2655
+ );
2656
+ return useSWRMutation__default.default("update-cart-delivery-options", updateDeliveryOptions, options);
2657
+ }
2658
+
2659
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2660
+ var useUpdatePlusMemberDeliveryOptions = ({
2661
+ options
2662
+ }) => {
2663
+ const { cart, mutateCart: mutate, metafieldIdentifiers } = useCartContext();
2664
+ const { trigger: updateCartDeliveryOptions2, isMutating } = useUpdateCartDeliveryOptions(
2665
+ mutate,
2666
+ metafieldIdentifiers
2667
+ );
2668
+ const handler = react.useCallback(
2669
+ async (_, { arg }) => {
2670
+ const { deliveryData } = arg;
2671
+ const firstDeliveryGroup = cart?.deliveryGroups?.[0];
2672
+ const deliveryGroupId = firstDeliveryGroup?.id;
2673
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2674
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2675
+ return null;
2676
+ }
2677
+ const deliveryGroup = cart?.deliveryGroups?.find((group) => group?.id === deliveryGroupId);
2678
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2679
+ (option) => option?.code === selectedOptionCode
2680
+ );
2681
+ if (!matchedOption?.handle) {
2682
+ return null;
2683
+ }
2684
+ const deliveryOptions = [
2685
+ {
2686
+ deliveryGroupId,
2687
+ deliveryOptionHandle: matchedOption.handle
2688
+ }
2689
+ ];
2690
+ const updatedCart = await updateCartDeliveryOptions2({
2691
+ selectedDeliveryOptions: deliveryOptions
2692
+ });
2693
+ if (updatedCart && mutate) {
2694
+ mutate(updatedCart);
2695
+ }
2696
+ return updatedCart;
2697
+ },
2698
+ [cart, updateCartDeliveryOptions2, mutate]
2699
+ );
2700
+ return useSWRMutation__default.default("update-cart-delivery-options", handler, options);
2701
+ };
2474
2702
  var usePlusMemberItemCustomAttributes = ({
2475
2703
  deliveryData
2476
2704
  }) => {
@@ -2557,15 +2785,14 @@ var usePlusMemberCheckoutCustomAttributes = ({
2557
2785
  }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2558
2786
  };
2559
2787
  function useAutoRemovePlusMemberInCart({
2560
- metafields,
2561
- isMonthlyPlus,
2562
- isAnnualPlus
2788
+ cart,
2789
+ profile,
2790
+ memberSetting
2563
2791
  }) {
2564
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2565
- const { cart } = useCartContext();
2792
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2566
2793
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2567
2794
  react.useEffect(() => {
2568
- if (!cart) return;
2795
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2569
2796
  const removePlusProduct = async (productType) => {
2570
2797
  if (!productType) return;
2571
2798
  const product = cart.lineItems?.find(
@@ -2577,26 +2804,53 @@ function useAutoRemovePlusMemberInCart({
2577
2804
  });
2578
2805
  }
2579
2806
  };
2580
- if (isMonthlyPlus) {
2807
+ if (profile?.isMonthlyPlus) {
2581
2808
  removePlusProduct(plus_monthly_product);
2582
2809
  }
2583
- if (isAnnualPlus) {
2810
+ if (profile?.isAnnualPlus) {
2584
2811
  removePlusProduct(plus_annual_product);
2585
2812
  }
2813
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2814
+ }
2815
+ function useAddPlusMemberProductsToCart({
2816
+ cart,
2817
+ profile
2818
+ }) {
2819
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2820
+ const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2821
+ memberSetting: plusMemberMetafields,
2822
+ cart
2823
+ });
2824
+ const plusMemberProduct = react.useMemo(() => {
2825
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2826
+ return void 0;
2827
+ }
2828
+ if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2829
+ return void 0;
2830
+ }
2831
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2832
+ return void 0;
2833
+ }
2834
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2835
+ return void 0;
2836
+ }
2837
+ if (!profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2838
+ return void 0;
2839
+ }
2840
+ return selectedPlusMemberProduct;
2586
2841
  }, [
2587
- cart,
2588
- plus_annual_product,
2589
- plus_monthly_product,
2590
- isAnnualPlus,
2591
- isMonthlyPlus,
2592
- removeCartLines2
2842
+ selectedPlusMemberMode,
2843
+ selectedPlusMemberProduct?.variant,
2844
+ selectedPlusMemberProduct?.product,
2845
+ hasMonthlyPlus,
2846
+ hasAnnualPlus
2593
2847
  ]);
2848
+ return plusMemberProduct;
2594
2849
  }
2595
2850
  var PlusMemberProvider = ({
2596
2851
  variant,
2597
2852
  product,
2598
- shopCommon,
2599
- metafields,
2853
+ memberSetting,
2600
2854
  initialSelectedPlusMemberMode = "free",
2601
2855
  profile,
2602
2856
  locale,
@@ -2616,14 +2870,14 @@ var PlusMemberProvider = ({
2616
2870
  const [deleteMarginBottom, setDeleteMarginBottom] = react.useState(false);
2617
2871
  const shippingMethodsContext = useShippingMethods({
2618
2872
  variant,
2619
- plusMemberMetafields: metafields,
2873
+ plusMemberMetafields: memberSetting,
2620
2874
  selectedPlusMemberMode});
2621
2875
  const plusMemberHandles = react.useMemo(() => {
2622
2876
  return [
2623
- metafields?.plus_monthly_product?.handle,
2624
- metafields?.plus_annual_product?.handle
2877
+ memberSetting?.plus_monthly_product?.handle,
2878
+ memberSetting?.plus_annual_product?.handle
2625
2879
  ].filter(Boolean);
2626
- }, [metafields]);
2880
+ }, [memberSetting]);
2627
2881
  const { data: plusMemberProducts = [] } = useProductsByHandles({
2628
2882
  handles: plusMemberHandles
2629
2883
  });
@@ -2631,25 +2885,24 @@ var PlusMemberProvider = ({
2631
2885
  if (selectedPlusMemberMode === "free" /* FREE */) {
2632
2886
  return null;
2633
2887
  }
2634
- const handle = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? metafields?.plus_monthly_product?.handle : metafields?.plus_annual_product?.handle;
2635
- const sku = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? metafields?.plus_monthly_product?.sku : metafields?.plus_annual_product?.sku;
2888
+ const handle = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.handle : memberSetting?.plus_annual_product?.handle;
2889
+ const sku = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.sku : memberSetting?.plus_annual_product?.sku;
2636
2890
  const product2 = plusMemberProducts?.find((p) => p.handle === handle);
2637
2891
  const variant2 = product2?.variants?.find((v) => v.sku === sku);
2638
2892
  return product2 && variant2 ? { product: product2, variant: variant2 } : null;
2639
- }, [plusMemberProducts, metafields, selectedPlusMemberMode]);
2893
+ }, [plusMemberProducts, memberSetting, selectedPlusMemberMode]);
2640
2894
  return /* @__PURE__ */ jsxRuntime.jsx(
2641
2895
  PlusMemberContext.Provider,
2642
2896
  {
2643
2897
  value: {
2644
2898
  variant,
2645
- shopCommon,
2646
2899
  zipCode,
2647
2900
  setZipCode,
2648
2901
  allowNextDayDelivery,
2649
2902
  setAllowNextDayDelivery,
2650
2903
  allowThirdDayDelivery,
2651
2904
  setAllowThirdDayDelivery,
2652
- plusMemberMetafields: metafields,
2905
+ plusMemberMetafields: memberSetting,
2653
2906
  selectedPlusMemberMode,
2654
2907
  setSelectedPlusMemberMode,
2655
2908
  showAreaCheckModal,
@@ -2868,6 +3121,9 @@ function CartProvider({
2868
3121
  }) {
2869
3122
  const { client, cartCookieAdapter } = useShopify();
2870
3123
  const [customAttributes, setCustomAttributes] = react.useState([]);
3124
+ const [customAttributesNeedDelete, setCustomAttributesNeedDelete] = react.useState(
3125
+ []
3126
+ );
2871
3127
  const [isCodeChanging, setIsCodeChanging] = react.useState(false);
2872
3128
  const [loadingState, setLoadingState] = react.useState({
2873
3129
  editLineQuantityLoading: false,
@@ -2898,7 +3154,11 @@ function CartProvider({
2898
3154
  ahooks.useRequest(
2899
3155
  () => {
2900
3156
  const newAttributes = [...attributes, ...customAttributes];
2901
- const needUpdate = cart && !isAttributesEqual(cart.customAttributes, newAttributes);
3157
+ const needUpdate = cart && !checkAttributesUpdateNeeded(
3158
+ cart.customAttributes,
3159
+ newAttributes,
3160
+ customAttributesNeedDelete
3161
+ );
2902
3162
  if (needUpdate) {
2903
3163
  return updateAttributes({ attributes: newAttributes });
2904
3164
  } else {
@@ -2919,11 +3179,12 @@ function CartProvider({
2919
3179
  isCartLoading: isCartLoading || isCodeChanging,
2920
3180
  setLoadingState
2921
3181
  });
2922
- const removeCustomAttributes = react.useCallback((attributes2) => {
2923
- setCustomAttributes(
2924
- (prev) => prev.filter((attr) => !attributes2.some((a) => a.key === attr.key))
2925
- );
2926
- }, []);
3182
+ const removeCustomAttributes = react.useCallback(
3183
+ (attributes2) => {
3184
+ setCustomAttributesNeedDelete(attributes2);
3185
+ },
3186
+ [setCustomAttributesNeedDelete]
3187
+ );
2927
3188
  const addCustomAttributes = react.useCallback(
2928
3189
  (attributes2) => {
2929
3190
  const sameAttributes = attributes2.filter(
@@ -3010,6 +3271,7 @@ function CartProvider({
3010
3271
  isCodeChanging,
3011
3272
  setIsCodeChanging,
3012
3273
  autoFreeGiftConfig,
3274
+ gradientGiftsConfig,
3013
3275
  setLoadingState,
3014
3276
  loadingState,
3015
3277
  // function满赠
@@ -3033,6 +3295,7 @@ function CartProvider({
3033
3295
  locale,
3034
3296
  isCodeChanging,
3035
3297
  autoFreeGiftConfig,
3298
+ gradientGiftsConfig,
3036
3299
  loadingState,
3037
3300
  // function满赠
3038
3301
  functionAutoFreeGift,
@@ -3105,7 +3368,9 @@ exports.atobID = atobID;
3105
3368
  exports.browserCartCookieAdapter = browserCartCookieAdapter;
3106
3369
  exports.browserCookieAdapter = browserCookieAdapter;
3107
3370
  exports.btoaID = btoaID;
3371
+ exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
3108
3372
  exports.clearGeoLocationCache = clearGeoLocationCache;
3373
+ exports.createMockCartFromLines = createMockCartFromLines;
3109
3374
  exports.currencyCodeMapping = currencyCodeMapping;
3110
3375
  exports.defaultSWRMutationConfiguration = defaultSWRMutationConfiguration;
3111
3376
  exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
@@ -3116,15 +3381,16 @@ exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
3116
3381
  exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
3117
3382
  exports.getQuery = getQuery;
3118
3383
  exports.getReferralAttributes = getReferralAttributes;
3119
- exports.isAttributesEqual = isAttributesEqual;
3384
+ exports.normalizeAddToCartLines = normalizeAddToCartLines;
3120
3385
  exports.preCheck = preCheck;
3121
- exports.safeParseJson = safeParseJson;
3386
+ exports.safeParse = safeParse;
3122
3387
  exports.trackAddToCartFBQ = trackAddToCartFBQ;
3123
3388
  exports.trackAddToCartGA = trackAddToCartGA;
3124
3389
  exports.trackBeginCheckoutGA = trackBeginCheckoutGA;
3125
3390
  exports.trackBuyNowFBQ = trackBuyNowFBQ;
3126
3391
  exports.trackBuyNowGA = trackBuyNowGA;
3127
3392
  exports.useAddCartLines = useAddCartLines;
3393
+ exports.useAddPlusMemberProductsToCart = useAddPlusMemberProductsToCart;
3128
3394
  exports.useAddToCart = useAddToCart;
3129
3395
  exports.useAllBlogs = useAllBlogs;
3130
3396
  exports.useAllCollections = useAllCollections;
@@ -3137,6 +3403,7 @@ exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
3137
3403
  exports.useBlog = useBlog;
3138
3404
  exports.useBuyNow = useBuyNow;
3139
3405
  exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
3406
+ exports.useCalcGiftsFromLines = useCalcGiftsFromLines;
3140
3407
  exports.useCalcOrderDiscount = useCalcOrderDiscount;
3141
3408
  exports.useCartAttributes = useCartAttributes;
3142
3409
  exports.useCartContext = useCartContext;
@@ -3171,6 +3438,7 @@ exports.useSite = useSite;
3171
3438
  exports.useUpdateCartAttributes = useUpdateCartAttributes;
3172
3439
  exports.useUpdateCartLines = useUpdateCartLines;
3173
3440
  exports.useUpdateLineCodeAmountAttributes = useUpdateLineCodeAmountAttributes;
3441
+ exports.useUpdatePlusMemberDeliveryOptions = useUpdatePlusMemberDeliveryOptions;
3174
3442
  exports.useUpdateVariantQuery = useUpdateVariantQuery;
3175
3443
  exports.useVariant = useVariant;
3176
3444
  exports.useVariantMedia = useVariantMedia;