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

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 : "";
@@ -159,22 +234,12 @@ var getQuery = () => {
159
234
  }
160
235
  return theRequest;
161
236
  };
162
- function atobID(id) {
163
- if (id && typeof id === "string" && id.includes("/")) {
164
- return id.split("/").pop()?.split("?")?.shift();
165
- } else {
166
- return id;
167
- }
168
- }
169
- function btoaID(id, type = "ProductVariant") {
170
- return `gid://shopify/${type}/${id}`;
171
- }
172
237
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
173
238
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
174
239
  const matchedList = cartData?.lineItems?.filter((line) => {
175
240
  const { is_gift } = getDiscountEnvAttributeValue(line.customAttributes);
176
241
  return isAllStoreVariant ? !is_gift : variant_list?.find((item) => {
177
- return !is_gift && atobID(line.variantId) === item;
242
+ return !is_gift && shopifySdk.atobID(line.variantId) === item;
178
243
  });
179
244
  });
180
245
  return matchedList?.reduce((acc, line) => {
@@ -366,12 +431,18 @@ var formatFunctionAutoFreeGift = ({
366
431
  };
367
432
  return result;
368
433
  };
369
- var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
434
+ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
370
435
  const tags = react.useMemo(() => customer?.tags || [], [customer?.tags]);
371
436
  const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
372
437
  const dealsType = "";
373
438
  const { client, locale } = useShopify();
374
439
  const giftProductsCache = react.useRef(null);
440
+ const effectiveCart = react.useMemo(() => {
441
+ if (lines && lines.length > 0) {
442
+ return createMockCartFromLines(lines, cart);
443
+ }
444
+ return cart;
445
+ }, [lines, cart]);
375
446
  const { activeCampaign, subtotal } = react.useMemo(() => {
376
447
  for (const campaign of autoFreeGiftConfig) {
377
448
  const { rule_conditions = [], rule_result } = campaign;
@@ -379,7 +450,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
379
450
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
380
451
  if (isPreCheckPassed && spend_get_reward) {
381
452
  const matchedSubtotal = getMatchedMainProductSubTotal(
382
- cart,
453
+ effectiveCart,
383
454
  spend_get_reward.main_product?.variant_list?.map((v) => v.variant_id) || [],
384
455
  {
385
456
  spend_money_type: spend_get_reward.main_product?.spend_money_type || 1,
@@ -393,13 +464,13 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
393
464
  }
394
465
  }
395
466
  return { activeCampaign: null, subtotal: 0 };
396
- }, [autoFreeGiftConfig, cart, tags, dealsType]);
467
+ }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
397
468
  const { qualifyingGift, nextTierGoal } = react.useMemo(() => {
398
469
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
399
470
  return { qualifyingGift: null, nextTierGoal: null };
400
471
  }
401
472
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
402
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
473
+ 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
474
  const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
404
475
  if (!qualifyingTier) {
405
476
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
@@ -411,7 +482,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
411
482
  if (!giftProduct) return null;
412
483
  return {
413
484
  variant: {
414
- id: btoaID(giftProduct.variant_id),
485
+ id: shopifySdk.btoaID(giftProduct.variant_id),
415
486
  handle: giftProduct.handle,
416
487
  sku: giftProduct.sku
417
488
  },
@@ -446,18 +517,24 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
446
517
  }
447
518
  return true;
448
519
  }, [giftHandles]);
449
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
450
- const res = await shopifySdk.getProductsByHandles(client, {
451
- handles: giftHandles,
452
- locale
453
- });
454
- const result = Array.isArray(res) ? res : [];
455
- giftProductsCache.current = {
456
- data: result,
457
- giftHandles: [...giftHandles]
458
- };
459
- return result;
460
- });
520
+ const { data: giftProductsResult } = useSWR__default.default(
521
+ shouldFetch ? giftHandles : null,
522
+ async () => {
523
+ const res = await shopifySdk.getProductsByHandles(client, {
524
+ handles: giftHandles,
525
+ locale
526
+ });
527
+ const result = Array.isArray(res) ? res : [];
528
+ giftProductsCache.current = {
529
+ data: result,
530
+ giftHandles: [...giftHandles]
531
+ };
532
+ return result;
533
+ },
534
+ {
535
+ revalidateOnFocus: false
536
+ }
537
+ );
461
538
  const finalGiftProductsResult = react.useMemo(() => {
462
539
  if (giftProductsCache.current && !shouldFetch) {
463
540
  return giftProductsCache.current.data || void 0;
@@ -476,12 +553,19 @@ var useScriptAutoFreeGift = ({
476
553
  campaign,
477
554
  _giveaway,
478
555
  cart,
479
- locale: providedLocale
556
+ locale: providedLocale,
557
+ lines
480
558
  }) => {
481
559
  const { client, locale: contextLocale } = useShopify();
482
560
  const locale = providedLocale || contextLocale;
483
561
  const [points_subscribe, set_points_subscribe] = react.useState(false);
484
562
  const giftProductsCache = react.useRef(null);
563
+ const effectiveCart = react.useMemo(() => {
564
+ if (lines && lines.length > 0) {
565
+ return createMockCartFromLines(lines, cart);
566
+ }
567
+ return cart;
568
+ }, [lines, cart]);
485
569
  react.useEffect(() => {
486
570
  if (locale === "au") {
487
571
  const isPointsSubscribe = Cookies5__default.default.get("points_subscribe");
@@ -503,14 +587,16 @@ var useScriptAutoFreeGift = ({
503
587
  upgrade_multiple2 = 1.2;
504
588
  upgrade_value2 = 40;
505
589
  }
506
- cart?.lineItems?.forEach(({ customAttributes }) => {
507
- customAttributes?.forEach(({ key, value }) => {
508
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
509
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
510
- });
511
- });
590
+ effectiveCart?.lineItems?.forEach(
591
+ ({ customAttributes }) => {
592
+ customAttributes?.forEach(({ key, value }) => {
593
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
594
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
595
+ });
596
+ }
597
+ );
512
598
  return [upgrade_multiple2, upgrade_value2];
513
- }, [cart?.lineItems, points_subscribe]);
599
+ }, [effectiveCart?.lineItems, points_subscribe]);
514
600
  const breakpoints = react.useMemo(() => {
515
601
  if (!isActivityAvailable) return [];
516
602
  return (campaign?.breakpoints || []).map((item) => ({
@@ -538,7 +624,7 @@ var useScriptAutoFreeGift = ({
538
624
  }, [giftHandles]);
539
625
  const involvedLines = react.useMemo(() => {
540
626
  if (!isActivityAvailable) return [];
541
- return (cart?.lineItems || []).filter((line) => {
627
+ return (effectiveCart?.lineItems || []).filter((line) => {
542
628
  const isNotGift = line?.totalAmount && Number(line.totalAmount) > 0 && line.customAttributes?.every(
543
629
  (item) => item.key !== _giveaway
544
630
  );
@@ -547,7 +633,7 @@ var useScriptAutoFreeGift = ({
547
633
  );
548
634
  return isNotGift && hasCampaignTag;
549
635
  });
550
- }, [cart?.lineItems, isActivityAvailable, _giveaway]);
636
+ }, [effectiveCart?.lineItems, isActivityAvailable, _giveaway]);
551
637
  const involvedSubTotal = react.useMemo(() => {
552
638
  if (!isActivityAvailable) return new Decimal2__default.default(0);
553
639
  return involvedLines.reduce((prev, item) => {
@@ -573,18 +659,24 @@ var useScriptAutoFreeGift = ({
573
659
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
574
660
  return [currentLevel, nextLevel];
575
661
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
576
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
577
- const res = await shopifySdk.getProductsByHandles(client, {
578
- handles: giftHandles,
579
- locale
580
- });
581
- const result = Array.isArray(res) ? res : [];
582
- giftProductsCache.current = {
583
- data: result,
584
- giftHandles: [...giftHandles]
585
- };
586
- return result;
587
- });
662
+ const { data: giftProductsResult } = useSWR__default.default(
663
+ shouldFetch ? giftHandles : null,
664
+ async () => {
665
+ const res = await shopifySdk.getProductsByHandles(client, {
666
+ handles: giftHandles,
667
+ locale
668
+ });
669
+ const result = Array.isArray(res) ? res : [];
670
+ giftProductsCache.current = {
671
+ data: result,
672
+ giftHandles: [...giftHandles]
673
+ };
674
+ return result;
675
+ },
676
+ {
677
+ revalidateOnFocus: false
678
+ }
679
+ );
588
680
  const finalGiftProductsResult = react.useMemo(() => {
589
681
  if (giftProductsCache.current && !shouldFetch) {
590
682
  return giftProductsCache.current.data || void 0;
@@ -847,7 +939,7 @@ function useApplyCartCodes(options) {
847
939
  if (!discountCodes?.length) {
848
940
  throw new Error("Invalid input used for this operation: Miss discountCode");
849
941
  }
850
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
942
+ const cartId = providedCartId || cart?.id;
851
943
  if (!cartId) {
852
944
  return void 0;
853
945
  }
@@ -875,7 +967,7 @@ function useRemoveCartCodes(options) {
875
967
  const removeCodes = react.useCallback(
876
968
  async (_key, { arg }) => {
877
969
  const { cartId: providedCartId, discountCodes } = arg;
878
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
970
+ const cartId = providedCartId || cart?.id;
879
971
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
880
972
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
881
973
  const updatedCart = await shopifySdk.updateCartCodes(client, {
@@ -897,7 +989,7 @@ function useRemoveCartCodes(options) {
897
989
  // src/hooks/cart/use-add-to-cart.ts
898
990
  function useAddToCart({ withTrack = true } = {}, swrOptions) {
899
991
  const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
900
- const { cart } = useCartContext();
992
+ const { cart, addCustomAttributes } = useCartContext();
901
993
  const { trigger: applyCartCodes } = useApplyCartCodes();
902
994
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
903
995
  const { trigger: addCartLines2 } = useAddCartLines();
@@ -911,7 +1003,8 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
911
1003
  buyerIdentity,
912
1004
  needCreateCart = false,
913
1005
  onCodesInvalid,
914
- replaceExistingCodes
1006
+ replaceExistingCodes,
1007
+ customAttributes
915
1008
  } = arg;
916
1009
  if (!lineItems || lineItems.length === 0) {
917
1010
  return;
@@ -934,6 +1027,7 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
934
1027
  if (!resultCart) {
935
1028
  return void 0;
936
1029
  }
1030
+ console.log("npm addCartLines resultCart", resultCart);
937
1031
  if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
938
1032
  const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
939
1033
  if (unapplicableCodes.length > 0) {
@@ -955,6 +1049,9 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
955
1049
  discountCodes
956
1050
  });
957
1051
  }
1052
+ if (customAttributes && customAttributes.length > 0) {
1053
+ addCustomAttributes(customAttributes);
1054
+ }
958
1055
  if (withTrack) {
959
1056
  trackAddToCartGA({
960
1057
  lineItems,
@@ -1107,6 +1204,60 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1107
1204
  );
1108
1205
  return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
1109
1206
  }
1207
+ function useCalcGiftsFromLines({
1208
+ lines,
1209
+ customer,
1210
+ scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
1211
+ }) {
1212
+ const { locale } = useShopify();
1213
+ const { cart, autoFreeGiftConfig, gradientGiftsConfig } = useCartContext();
1214
+ const functionGift = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer, lines);
1215
+ const scriptGift = useScriptAutoFreeGift({
1216
+ campaign: gradientGiftsConfig || null,
1217
+ _giveaway: scriptGiveawayKey,
1218
+ cart,
1219
+ locale,
1220
+ lines
1221
+ });
1222
+ const allGiftLines = react.useMemo(() => {
1223
+ const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || [];
1224
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((product) => {
1225
+ const giftProduct = scriptGift.giftProductsResult?.find(
1226
+ (p) => p.handle === product.handle
1227
+ );
1228
+ const variant = giftProduct?.variants?.[0];
1229
+ return {
1230
+ variant: {
1231
+ id: variant?.id || "",
1232
+ handle: product.handle,
1233
+ sku: product.sku
1234
+ },
1235
+ quantity: 1,
1236
+ attributes: [
1237
+ {
1238
+ key: scriptGiveawayKey,
1239
+ value: "true"
1240
+ }
1241
+ ]
1242
+ };
1243
+ }).filter((item) => item.variant.id) : [];
1244
+ return [...functionGiftLines, ...scriptGiftLines];
1245
+ }, [
1246
+ functionGift.qualifyingGift,
1247
+ scriptGift.freeGiftLevel,
1248
+ scriptGift.giftProductsResult,
1249
+ scriptGiveawayKey
1250
+ ]);
1251
+ const hasGifts = react.useMemo(() => {
1252
+ return allGiftLines.length > 0;
1253
+ }, [allGiftLines]);
1254
+ return {
1255
+ functionGift,
1256
+ scriptGift,
1257
+ allGiftLines,
1258
+ hasGifts
1259
+ };
1260
+ }
1110
1261
 
1111
1262
  // src/hooks/cart/types/order-discount.ts
1112
1263
  var OrderDiscountType = /* @__PURE__ */ ((OrderDiscountType2) => {
@@ -1227,12 +1378,10 @@ function useHasPlusMemberInCart({
1227
1378
  };
1228
1379
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1229
1380
  }
1230
-
1231
- // src/hooks/cart/feature/use-cart-attributes.ts
1232
1381
  var getReferralAttributes = () => {
1233
- const inviteCode = Cookies5__default.default.get("invite_code");
1234
- const playModeId = Cookies5__default.default.get("playModeId");
1235
- const popup = Cookies5__default.default.get("_popup");
1382
+ const inviteCode = shopifySdk.getLocalStorage("invite_code") || Cookies5__default.default.get("invite_code");
1383
+ const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
1384
+ const popup = shopifySdk.getLocalStorage("_popup") || Cookies5__default.default.get("_popup");
1236
1385
  if (inviteCode && playModeId) {
1237
1386
  return popup ? [
1238
1387
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1256,8 +1405,6 @@ var useCartAttributes = ({
1256
1405
  memberSetting,
1257
1406
  cart
1258
1407
  });
1259
- console.log("memberSetting", memberSetting);
1260
- console.log("hasPlusMember", hasPlusMember);
1261
1408
  react.useEffect(() => {
1262
1409
  setCurrentUrl(window.location.href);
1263
1410
  }, []);
@@ -1283,7 +1430,7 @@ var useCartAttributes = ({
1283
1430
  return "new_user_login";
1284
1431
  }, [customer]);
1285
1432
  const memberAttributes = react.useMemo(() => {
1286
- return [
1433
+ const attributes = [
1287
1434
  {
1288
1435
  key: "_token",
1289
1436
  value: profile?.token
@@ -1304,17 +1451,28 @@ var useCartAttributes = ({
1304
1451
  value: profile?.token ? "true" : "false"
1305
1452
  }
1306
1453
  ];
1454
+ if (profile?.token) {
1455
+ attributes.push({
1456
+ key: "_login_user",
1457
+ value: "1"
1458
+ });
1459
+ }
1460
+ return attributes;
1307
1461
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1308
1462
  const functionAttributes = react.useMemo(() => {
1309
- return [
1310
- cart?.discountCodes && {
1463
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1464
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1465
+ );
1466
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1467
+ return hasFunctionEnvAttribute ? [
1468
+ {
1311
1469
  key: "_discounts_function_env",
1312
1470
  value: JSON.stringify({
1313
- discount_code: cart?.discountCodes.map((item) => item.code),
1471
+ discount_code: discountCodes,
1314
1472
  user_tags: customer?.tags || []
1315
1473
  })
1316
1474
  }
1317
- ];
1475
+ ] : [];
1318
1476
  }, [cart]);
1319
1477
  const presellAttributes = react.useMemo(() => {
1320
1478
  return [
@@ -1346,18 +1504,50 @@ var useCartAttributes = ({
1346
1504
  }
1347
1505
  ];
1348
1506
  }, [currentUrl]);
1507
+ const commonAttributes = react.useMemo(
1508
+ () => [
1509
+ ...memberAttributes,
1510
+ ...functionAttributes,
1511
+ ...presellAttributes,
1512
+ ...weightAttributes,
1513
+ ...trackingAttributes,
1514
+ ...getReferralAttributes()
1515
+ ].filter((item) => item?.value),
1516
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1517
+ );
1518
+ const extraAttributesInCart = react.useMemo(() => {
1519
+ const commonAttributeKeys = [
1520
+ // member attributes
1521
+ "_token",
1522
+ "_member_type",
1523
+ "_user_type",
1524
+ "_is_login",
1525
+ "_login_user",
1526
+ // function attributes
1527
+ "_discounts_function_env",
1528
+ // presell attributes
1529
+ "_presale",
1530
+ // weight attributes
1531
+ "_weight",
1532
+ "_app_source_name",
1533
+ // tracking attributes
1534
+ "utm_params",
1535
+ // referral attributes
1536
+ "_invite_code",
1537
+ "_play_mode_id",
1538
+ "_popup"
1539
+ ];
1540
+ return cart?.customAttributes?.filter(
1541
+ (item) => !commonAttributeKeys.includes(item.key)
1542
+ ) || [];
1543
+ }, [cart]);
1349
1544
  return react.useMemo(
1350
1545
  () => ({
1351
- attributes: [
1352
- ...memberAttributes,
1353
- ...functionAttributes,
1354
- ...presellAttributes,
1355
- ...weightAttributes,
1356
- ...trackingAttributes,
1357
- ...getReferralAttributes()
1358
- ].filter((item) => item?.value)
1546
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1547
+ (item) => item?.value
1548
+ )
1359
1549
  }),
1360
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1550
+ [commonAttributes, extraAttributesInCart]
1361
1551
  );
1362
1552
  };
1363
1553
  var DEFAULT_MIN = 1;
@@ -1574,8 +1764,9 @@ function useProductsByHandles(options = {}) {
1574
1764
  metafieldIdentifiers
1575
1765
  });
1576
1766
  },
1577
- swrOptions || {
1578
- revalidateOnFocus: false
1767
+ {
1768
+ revalidateOnFocus: false,
1769
+ ...swrOptions
1579
1770
  }
1580
1771
  );
1581
1772
  }
@@ -2491,6 +2682,73 @@ var usePlusMemberDeliveryCodes = ({
2491
2682
  [deliveryData]
2492
2683
  );
2493
2684
  };
2685
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2686
+ const { client, locale, cartCookieAdapter } = useShopify();
2687
+ const updateDeliveryOptions = react.useCallback(
2688
+ async (_key, { arg }) => {
2689
+ const updatedCart = await shopifySdk.updateCartDeliveryOptions(client, {
2690
+ ...arg,
2691
+ metafieldIdentifiers,
2692
+ cookieAdapter: cartCookieAdapter
2693
+ });
2694
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2695
+ if (updatedCart) {
2696
+ mutate(updatedCart);
2697
+ }
2698
+ return updatedCart;
2699
+ },
2700
+ [client, locale, cartCookieAdapter, mutate]
2701
+ );
2702
+ return useSWRMutation__default.default("update-cart-delivery-options", updateDeliveryOptions, options);
2703
+ }
2704
+
2705
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2706
+ var useUpdatePlusMemberDeliveryOptions = ({
2707
+ options
2708
+ } = {}) => {
2709
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2710
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2711
+ mutateCart,
2712
+ metafieldIdentifiers
2713
+ );
2714
+ const handler = react.useCallback(
2715
+ async (_, { arg }) => {
2716
+ const currentCart = arg?.cart || cartContextData;
2717
+ const { deliveryData } = arg;
2718
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2719
+ const deliveryGroupId = firstDeliveryGroup?.id;
2720
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2721
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2722
+ return null;
2723
+ }
2724
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2725
+ (group) => group?.id === deliveryGroupId
2726
+ );
2727
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2728
+ (option) => option?.code === selectedOptionCode
2729
+ );
2730
+ if (!matchedOption?.handle) {
2731
+ return null;
2732
+ }
2733
+ const deliveryOptions = [
2734
+ {
2735
+ deliveryGroupId,
2736
+ deliveryOptionHandle: matchedOption.handle
2737
+ }
2738
+ ];
2739
+ const updatedCart = await updateCartDeliveryOptions2({
2740
+ selectedDeliveryOptions: deliveryOptions,
2741
+ cartId: currentCart?.id
2742
+ });
2743
+ if (updatedCart && mutateCart) {
2744
+ mutateCart(updatedCart);
2745
+ }
2746
+ return updatedCart;
2747
+ },
2748
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2749
+ );
2750
+ return useSWRMutation__default.default("update-cart-delivery-options", handler, options);
2751
+ };
2494
2752
  var usePlusMemberItemCustomAttributes = ({
2495
2753
  deliveryData
2496
2754
  }) => {
@@ -2510,48 +2768,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2510
2768
  deliveryData,
2511
2769
  product,
2512
2770
  variant,
2513
- customer,
2514
2771
  isShowShippingBenefits
2515
2772
  }) => {
2516
2773
  const { deliveryCustomData } = deliveryData || {};
2517
2774
  const { profile } = usePlusMemberContext();
2518
- const userType = react.useMemo(() => {
2519
- const customerInfo = customer;
2520
- if (!customerInfo) {
2521
- return "new_user_unlogin";
2522
- }
2523
- if (customer) {
2524
- const { orders = {} } = customer;
2525
- const edgesLength = orders?.edges?.length;
2526
- if (edgesLength === 1) {
2527
- return "old_user_orders_once";
2528
- } else if (edgesLength && edgesLength > 1) {
2529
- return "old_user_orders_twice";
2530
- }
2531
- }
2532
- return "new_user_login";
2533
- }, [customer]);
2534
2775
  return react.useMemo(() => {
2535
2776
  const checkoutCustomAttributes = [
2536
- {
2537
- key: "_token",
2538
- value: profile?.token || ""
2539
- },
2777
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2540
2778
  {
2541
2779
  key: "_last_url",
2542
2780
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2543
- },
2544
- {
2545
- key: "_user_type",
2546
- value: userType
2547
2781
  }
2548
2782
  ];
2549
- if (profile) {
2550
- checkoutCustomAttributes.push({
2551
- key: "_login_user",
2552
- value: "1"
2553
- });
2554
- }
2555
2783
  if (deliveryCustomData) {
2556
2784
  checkoutCustomAttributes.push({
2557
2785
  key: "_checkout_delivery_custom",
@@ -2561,12 +2789,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2561
2789
  })
2562
2790
  });
2563
2791
  }
2564
- if (variant?.metafields?.presell) {
2565
- checkoutCustomAttributes.push({
2566
- key: "_presale",
2567
- value: "true"
2568
- });
2569
- }
2570
2792
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2571
2793
  checkoutCustomAttributes.push({
2572
2794
  key: "_hide_shipping",
@@ -2574,18 +2796,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2574
2796
  });
2575
2797
  }
2576
2798
  return checkoutCustomAttributes;
2577
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2799
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2578
2800
  };
2579
2801
  function useAutoRemovePlusMemberInCart({
2580
- metafields,
2581
- isMonthlyPlus,
2582
- isAnnualPlus
2802
+ cart,
2803
+ profile,
2804
+ memberSetting
2583
2805
  }) {
2584
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2585
- const { cart } = useCartContext();
2806
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2586
2807
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2587
2808
  react.useEffect(() => {
2588
- if (!cart) return;
2809
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2589
2810
  const removePlusProduct = async (productType) => {
2590
2811
  if (!productType) return;
2591
2812
  const product = cart.lineItems?.find(
@@ -2597,33 +2818,25 @@ function useAutoRemovePlusMemberInCart({
2597
2818
  });
2598
2819
  }
2599
2820
  };
2600
- if (isMonthlyPlus) {
2821
+ if (profile?.isMonthlyPlus) {
2601
2822
  removePlusProduct(plus_monthly_product);
2602
2823
  }
2603
- if (isAnnualPlus) {
2824
+ if (profile?.isAnnualPlus) {
2604
2825
  removePlusProduct(plus_annual_product);
2605
2826
  }
2606
- }, [
2607
- cart,
2608
- plus_annual_product,
2609
- plus_monthly_product,
2610
- isAnnualPlus,
2611
- isMonthlyPlus,
2612
- removeCartLines2
2613
- ]);
2827
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2614
2828
  }
2615
2829
  function useAddPlusMemberProductsToCart({
2616
2830
  cart,
2617
- memberSetting,
2618
- selectedPlusMemberMode,
2619
- selectedPlusMemberProduct
2831
+ profile
2620
2832
  }) {
2833
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2621
2834
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2622
- cart,
2623
- memberSetting
2835
+ memberSetting: plusMemberMetafields,
2836
+ cart
2624
2837
  });
2625
2838
  const plusMemberProduct = react.useMemo(() => {
2626
- if (selectedPlusMemberMode === "free" /* FREE */) {
2839
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2627
2840
  return void 0;
2628
2841
  }
2629
2842
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2632,7 +2845,10 @@ function useAddPlusMemberProductsToCart({
2632
2845
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2633
2846
  return void 0;
2634
2847
  }
2635
- if (!selectedPlusMemberProduct) {
2848
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2849
+ return void 0;
2850
+ }
2851
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2636
2852
  return void 0;
2637
2853
  }
2638
2854
  return selectedPlusMemberProduct;
@@ -2951,8 +3167,13 @@ function CartProvider({
2951
3167
  const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
2952
3168
  ahooks.useRequest(
2953
3169
  () => {
2954
- const newAttributes = [...attributes, ...customAttributes];
2955
- const needUpdate = cart && !checkAttributesUpdateNeeded(
3170
+ const newAttributes = [...attributes];
3171
+ customAttributes.forEach((item) => {
3172
+ if (item.value && !newAttributes.some((attr) => attr.key === item.key)) {
3173
+ newAttributes.push(item);
3174
+ }
3175
+ });
3176
+ const needUpdate = cart && checkAttributesUpdateNeeded(
2956
3177
  cart.customAttributes,
2957
3178
  newAttributes,
2958
3179
  customAttributesNeedDelete
@@ -3056,8 +3277,14 @@ function CartProvider({
3056
3277
  );
3057
3278
  return result;
3058
3279
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
3280
+ const totalQuantity = react.useMemo(() => {
3281
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
3282
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3283
+ return cartLinesCount + giftLinesCount;
3284
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
3059
3285
  const value = react.useMemo(
3060
3286
  () => ({
3287
+ totalQuantity,
3061
3288
  cart,
3062
3289
  isCartLoading,
3063
3290
  triggerFetch: fetchCart,
@@ -3069,6 +3296,7 @@ function CartProvider({
3069
3296
  isCodeChanging,
3070
3297
  setIsCodeChanging,
3071
3298
  autoFreeGiftConfig,
3299
+ gradientGiftsConfig,
3072
3300
  setLoadingState,
3073
3301
  loadingState,
3074
3302
  // function满赠
@@ -3084,6 +3312,7 @@ function CartProvider({
3084
3312
  }),
3085
3313
  [
3086
3314
  cart,
3315
+ totalQuantity,
3087
3316
  isCartLoading,
3088
3317
  fetchCart,
3089
3318
  mutateCart,
@@ -3092,6 +3321,7 @@ function CartProvider({
3092
3321
  locale,
3093
3322
  isCodeChanging,
3094
3323
  autoFreeGiftConfig,
3324
+ gradientGiftsConfig,
3095
3325
  loadingState,
3096
3326
  // function满赠
3097
3327
  functionAutoFreeGift,
@@ -3115,30 +3345,6 @@ function useCartContext() {
3115
3345
  return context;
3116
3346
  }
3117
3347
 
3118
- Object.defineProperty(exports, "ShopifyConfig", {
3119
- enumerable: true,
3120
- get: function () { return shopifySdk.ShopifyConfig; }
3121
- });
3122
- Object.defineProperty(exports, "clearLocalStorage", {
3123
- enumerable: true,
3124
- get: function () { return shopifySdk.clearLocalStorage; }
3125
- });
3126
- Object.defineProperty(exports, "createShopifyClient", {
3127
- enumerable: true,
3128
- get: function () { return shopifySdk.createShopifyClient; }
3129
- });
3130
- Object.defineProperty(exports, "getLocalStorage", {
3131
- enumerable: true,
3132
- get: function () { return shopifySdk.getLocalStorage; }
3133
- });
3134
- Object.defineProperty(exports, "removeLocalStorage", {
3135
- enumerable: true,
3136
- get: function () { return shopifySdk.removeLocalStorage; }
3137
- });
3138
- Object.defineProperty(exports, "setLocalStorage", {
3139
- enumerable: true,
3140
- get: function () { return shopifySdk.setLocalStorage; }
3141
- });
3142
3348
  exports.BuyRuleType = BuyRuleType;
3143
3349
  exports.CODE_AMOUNT_KEY = CODE_AMOUNT_KEY;
3144
3350
  exports.CUSTOMER_ATTRIBUTE_KEY = CUSTOMER_ATTRIBUTE_KEY;
@@ -3160,12 +3366,11 @@ exports.ShippingMethodMode = ShippingMethodMode;
3160
3366
  exports.ShopifyContext = ShopifyContext;
3161
3367
  exports.ShopifyProvider = ShopifyProvider;
3162
3368
  exports.SpendMoneyType = SpendMoneyType;
3163
- exports.atobID = atobID;
3164
3369
  exports.browserCartCookieAdapter = browserCartCookieAdapter;
3165
3370
  exports.browserCookieAdapter = browserCookieAdapter;
3166
- exports.btoaID = btoaID;
3167
3371
  exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
3168
3372
  exports.clearGeoLocationCache = clearGeoLocationCache;
3373
+ exports.createMockCartFromLines = createMockCartFromLines;
3169
3374
  exports.currencyCodeMapping = currencyCodeMapping;
3170
3375
  exports.defaultSWRMutationConfiguration = defaultSWRMutationConfiguration;
3171
3376
  exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
@@ -3176,6 +3381,7 @@ exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
3176
3381
  exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
3177
3382
  exports.getQuery = getQuery;
3178
3383
  exports.getReferralAttributes = getReferralAttributes;
3384
+ exports.normalizeAddToCartLines = normalizeAddToCartLines;
3179
3385
  exports.preCheck = preCheck;
3180
3386
  exports.safeParse = safeParse;
3181
3387
  exports.trackAddToCartFBQ = trackAddToCartFBQ;
@@ -3197,6 +3403,7 @@ exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
3197
3403
  exports.useBlog = useBlog;
3198
3404
  exports.useBuyNow = useBuyNow;
3199
3405
  exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
3406
+ exports.useCalcGiftsFromLines = useCalcGiftsFromLines;
3200
3407
  exports.useCalcOrderDiscount = useCalcOrderDiscount;
3201
3408
  exports.useCartAttributes = useCartAttributes;
3202
3409
  exports.useCartContext = useCartContext;
@@ -3231,8 +3438,15 @@ exports.useSite = useSite;
3231
3438
  exports.useUpdateCartAttributes = useUpdateCartAttributes;
3232
3439
  exports.useUpdateCartLines = useUpdateCartLines;
3233
3440
  exports.useUpdateLineCodeAmountAttributes = useUpdateLineCodeAmountAttributes;
3441
+ exports.useUpdatePlusMemberDeliveryOptions = useUpdatePlusMemberDeliveryOptions;
3234
3442
  exports.useUpdateVariantQuery = useUpdateVariantQuery;
3235
3443
  exports.useVariant = useVariant;
3236
3444
  exports.useVariantMedia = useVariantMedia;
3445
+ Object.keys(shopifySdk).forEach(function (k) {
3446
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
3447
+ enumerable: true,
3448
+ get: function () { return shopifySdk[k]; }
3449
+ });
3450
+ });
3237
3451
  //# sourceMappingURL=index.js.map
3238
3452
  //# sourceMappingURL=index.js.map