@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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
2
- import { createShopifyClient, getProductsByHandles, createCart, updateCartCodes, addCartLines, updateCartLines, removeCartLines, updateCartAttributes, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getLocalStorage, getCart, setLocalStorage } from '@anker-in/shopify-sdk';
3
- export { ShopifyConfig, clearLocalStorage, createShopifyClient, getLocalStorage, removeLocalStorage, setLocalStorage } from '@anker-in/shopify-sdk';
2
+ import { createShopifyClient, atobID, btoaID, getProductsByHandles, createCart, updateCartCodes, addCartLines, updateCartLines, removeCartLines, updateCartAttributes, getLocalStorage, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getCart, setLocalStorage, updateCartDeliveryOptions } from '@anker-in/shopify-sdk';
3
+ export * from '@anker-in/shopify-sdk';
4
4
  import Cookies5 from 'js-cookie';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
  import Decimal2 from 'decimal.js';
@@ -134,6 +134,81 @@ var CODE_AMOUNT_KEY = "_sku_code_money";
134
134
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
135
135
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
136
136
 
137
+ // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
138
+ function normalizeAddToCartLines(lines) {
139
+ return lines.filter((line) => line.variant?.id).map((line, index) => {
140
+ const variant = line.variant;
141
+ const product = variant.product;
142
+ const quantity = line.quantity || 1;
143
+ const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
144
+ const subtotalAmount = price * quantity;
145
+ const totalAmount = subtotalAmount;
146
+ return {
147
+ id: `temp-line-${index}-${variant.id}`,
148
+ // Temporary ID for pre-cart lines
149
+ name: product?.title || variant.title || "",
150
+ quantity,
151
+ variantId: variant.id,
152
+ productId: product?.id || variant.id.split("/").slice(0, -2).join("/"),
153
+ totalAmount,
154
+ subtotalAmount,
155
+ discountAllocations: [],
156
+ customAttributes: line.attributes || [],
157
+ variant: {
158
+ id: variant.id,
159
+ price,
160
+ listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
161
+ sku: variant.sku || "",
162
+ name: variant.title || "",
163
+ image: variant.image ? {
164
+ url: variant.image.url,
165
+ altText: variant.image.altText || void 0
166
+ } : void 0,
167
+ requiresShipping: false,
168
+ // Default value, not available in NormalizedProductVariant
169
+ availableForSale: variant.availableForSale ?? true,
170
+ quantityAvailable: variant.quantityAvailable ?? 0,
171
+ currentlyNotInStock: false,
172
+ // Default value, will be updated when added to cart
173
+ weight: variant.weight,
174
+ metafields: variant.metafields
175
+ },
176
+ product,
177
+ path: product?.handle ? `/products/${product.handle}` : "",
178
+ discounts: [],
179
+ options: variant.selectedOptions?.map((opt) => ({
180
+ name: opt.name,
181
+ value: opt.value
182
+ }))
183
+ };
184
+ });
185
+ }
186
+ function createMockCartFromLines(lines, existingCart) {
187
+ const normalizedLines = normalizeAddToCartLines(lines);
188
+ const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
189
+ const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
190
+ return {
191
+ id: existingCart?.id || "temp-cart-id",
192
+ customerId: existingCart?.customerId,
193
+ email: existingCart?.email,
194
+ createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
195
+ currency: existingCart?.currency || { code: "USD" },
196
+ taxesIncluded: existingCart?.taxesIncluded,
197
+ lineItems: normalizedLines,
198
+ totalLineItemsDiscount: 0,
199
+ orderDiscounts: 0,
200
+ lineItemsSubtotalPrice: subtotalPrice,
201
+ subtotalPrice,
202
+ totalPrice,
203
+ totalTaxAmount: 0,
204
+ discountCodes: existingCart?.discountCodes || [],
205
+ discountAllocations: [],
206
+ url: existingCart?.url || "",
207
+ ready: true,
208
+ customAttributes: existingCart?.customAttributes
209
+ };
210
+ }
211
+
137
212
  // src/hooks/cart/utils/index.ts
138
213
  var getQuery = () => {
139
214
  const url = typeof window !== "undefined" ? window.location.search : "";
@@ -151,16 +226,6 @@ var getQuery = () => {
151
226
  }
152
227
  return theRequest;
153
228
  };
154
- function atobID(id) {
155
- if (id && typeof id === "string" && id.includes("/")) {
156
- return id.split("/").pop()?.split("?")?.shift();
157
- } else {
158
- return id;
159
- }
160
- }
161
- function btoaID(id, type = "ProductVariant") {
162
- return `gid://shopify/${type}/${id}`;
163
- }
164
229
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
165
230
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
166
231
  const matchedList = cartData?.lineItems?.filter((line) => {
@@ -358,12 +423,18 @@ var formatFunctionAutoFreeGift = ({
358
423
  };
359
424
  return result;
360
425
  };
361
- var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
426
+ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
362
427
  const tags = useMemo(() => customer?.tags || [], [customer?.tags]);
363
428
  const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
364
429
  const dealsType = "";
365
430
  const { client, locale } = useShopify();
366
431
  const giftProductsCache = useRef(null);
432
+ const effectiveCart = useMemo(() => {
433
+ if (lines && lines.length > 0) {
434
+ return createMockCartFromLines(lines, cart);
435
+ }
436
+ return cart;
437
+ }, [lines, cart]);
367
438
  const { activeCampaign, subtotal } = useMemo(() => {
368
439
  for (const campaign of autoFreeGiftConfig) {
369
440
  const { rule_conditions = [], rule_result } = campaign;
@@ -371,7 +442,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
371
442
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
372
443
  if (isPreCheckPassed && spend_get_reward) {
373
444
  const matchedSubtotal = getMatchedMainProductSubTotal(
374
- cart,
445
+ effectiveCart,
375
446
  spend_get_reward.main_product?.variant_list?.map((v) => v.variant_id) || [],
376
447
  {
377
448
  spend_money_type: spend_get_reward.main_product?.spend_money_type || 1,
@@ -385,13 +456,13 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
385
456
  }
386
457
  }
387
458
  return { activeCampaign: null, subtotal: 0 };
388
- }, [autoFreeGiftConfig, cart, tags, dealsType]);
459
+ }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
389
460
  const { qualifyingGift, nextTierGoal } = useMemo(() => {
390
461
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
391
462
  return { qualifyingGift: null, nextTierGoal: null };
392
463
  }
393
464
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
394
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
465
+ const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
395
466
  const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
396
467
  if (!qualifyingTier) {
397
468
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
@@ -438,18 +509,24 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
438
509
  }
439
510
  return true;
440
511
  }, [giftHandles]);
441
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
442
- const res = await getProductsByHandles(client, {
443
- handles: giftHandles,
444
- locale
445
- });
446
- const result = Array.isArray(res) ? res : [];
447
- giftProductsCache.current = {
448
- data: result,
449
- giftHandles: [...giftHandles]
450
- };
451
- return result;
452
- });
512
+ const { data: giftProductsResult } = useSWR(
513
+ shouldFetch ? giftHandles : null,
514
+ async () => {
515
+ const res = await getProductsByHandles(client, {
516
+ handles: giftHandles,
517
+ locale
518
+ });
519
+ const result = Array.isArray(res) ? res : [];
520
+ giftProductsCache.current = {
521
+ data: result,
522
+ giftHandles: [...giftHandles]
523
+ };
524
+ return result;
525
+ },
526
+ {
527
+ revalidateOnFocus: false
528
+ }
529
+ );
453
530
  const finalGiftProductsResult = useMemo(() => {
454
531
  if (giftProductsCache.current && !shouldFetch) {
455
532
  return giftProductsCache.current.data || void 0;
@@ -468,12 +545,19 @@ var useScriptAutoFreeGift = ({
468
545
  campaign,
469
546
  _giveaway,
470
547
  cart,
471
- locale: providedLocale
548
+ locale: providedLocale,
549
+ lines
472
550
  }) => {
473
551
  const { client, locale: contextLocale } = useShopify();
474
552
  const locale = providedLocale || contextLocale;
475
553
  const [points_subscribe, set_points_subscribe] = useState(false);
476
554
  const giftProductsCache = useRef(null);
555
+ const effectiveCart = useMemo(() => {
556
+ if (lines && lines.length > 0) {
557
+ return createMockCartFromLines(lines, cart);
558
+ }
559
+ return cart;
560
+ }, [lines, cart]);
477
561
  useEffect(() => {
478
562
  if (locale === "au") {
479
563
  const isPointsSubscribe = Cookies5.get("points_subscribe");
@@ -495,14 +579,16 @@ var useScriptAutoFreeGift = ({
495
579
  upgrade_multiple2 = 1.2;
496
580
  upgrade_value2 = 40;
497
581
  }
498
- cart?.lineItems?.forEach(({ customAttributes }) => {
499
- customAttributes?.forEach(({ key, value }) => {
500
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
501
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
502
- });
503
- });
582
+ effectiveCart?.lineItems?.forEach(
583
+ ({ customAttributes }) => {
584
+ customAttributes?.forEach(({ key, value }) => {
585
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
586
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
587
+ });
588
+ }
589
+ );
504
590
  return [upgrade_multiple2, upgrade_value2];
505
- }, [cart?.lineItems, points_subscribe]);
591
+ }, [effectiveCart?.lineItems, points_subscribe]);
506
592
  const breakpoints = useMemo(() => {
507
593
  if (!isActivityAvailable) return [];
508
594
  return (campaign?.breakpoints || []).map((item) => ({
@@ -530,7 +616,7 @@ var useScriptAutoFreeGift = ({
530
616
  }, [giftHandles]);
531
617
  const involvedLines = useMemo(() => {
532
618
  if (!isActivityAvailable) return [];
533
- return (cart?.lineItems || []).filter((line) => {
619
+ return (effectiveCart?.lineItems || []).filter((line) => {
534
620
  const isNotGift = line?.totalAmount && Number(line.totalAmount) > 0 && line.customAttributes?.every(
535
621
  (item) => item.key !== _giveaway
536
622
  );
@@ -539,7 +625,7 @@ var useScriptAutoFreeGift = ({
539
625
  );
540
626
  return isNotGift && hasCampaignTag;
541
627
  });
542
- }, [cart?.lineItems, isActivityAvailable, _giveaway]);
628
+ }, [effectiveCart?.lineItems, isActivityAvailable, _giveaway]);
543
629
  const involvedSubTotal = useMemo(() => {
544
630
  if (!isActivityAvailable) return new Decimal2(0);
545
631
  return involvedLines.reduce((prev, item) => {
@@ -565,18 +651,24 @@ var useScriptAutoFreeGift = ({
565
651
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
566
652
  return [currentLevel, nextLevel];
567
653
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
568
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
569
- const res = await getProductsByHandles(client, {
570
- handles: giftHandles,
571
- locale
572
- });
573
- const result = Array.isArray(res) ? res : [];
574
- giftProductsCache.current = {
575
- data: result,
576
- giftHandles: [...giftHandles]
577
- };
578
- return result;
579
- });
654
+ const { data: giftProductsResult } = useSWR(
655
+ shouldFetch ? giftHandles : null,
656
+ async () => {
657
+ const res = await getProductsByHandles(client, {
658
+ handles: giftHandles,
659
+ locale
660
+ });
661
+ const result = Array.isArray(res) ? res : [];
662
+ giftProductsCache.current = {
663
+ data: result,
664
+ giftHandles: [...giftHandles]
665
+ };
666
+ return result;
667
+ },
668
+ {
669
+ revalidateOnFocus: false
670
+ }
671
+ );
580
672
  const finalGiftProductsResult = useMemo(() => {
581
673
  if (giftProductsCache.current && !shouldFetch) {
582
674
  return giftProductsCache.current.data || void 0;
@@ -839,7 +931,7 @@ function useApplyCartCodes(options) {
839
931
  if (!discountCodes?.length) {
840
932
  throw new Error("Invalid input used for this operation: Miss discountCode");
841
933
  }
842
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
934
+ const cartId = providedCartId || cart?.id;
843
935
  if (!cartId) {
844
936
  return void 0;
845
937
  }
@@ -867,7 +959,7 @@ function useRemoveCartCodes(options) {
867
959
  const removeCodes = useCallback(
868
960
  async (_key, { arg }) => {
869
961
  const { cartId: providedCartId, discountCodes } = arg;
870
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
962
+ const cartId = providedCartId || cart?.id;
871
963
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
872
964
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
873
965
  const updatedCart = await updateCartCodes(client, {
@@ -889,7 +981,7 @@ function useRemoveCartCodes(options) {
889
981
  // src/hooks/cart/use-add-to-cart.ts
890
982
  function useAddToCart({ withTrack = true } = {}, swrOptions) {
891
983
  const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
892
- const { cart } = useCartContext();
984
+ const { cart, addCustomAttributes } = useCartContext();
893
985
  const { trigger: applyCartCodes } = useApplyCartCodes();
894
986
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
895
987
  const { trigger: addCartLines2 } = useAddCartLines();
@@ -903,7 +995,8 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
903
995
  buyerIdentity,
904
996
  needCreateCart = false,
905
997
  onCodesInvalid,
906
- replaceExistingCodes
998
+ replaceExistingCodes,
999
+ customAttributes
907
1000
  } = arg;
908
1001
  if (!lineItems || lineItems.length === 0) {
909
1002
  return;
@@ -926,6 +1019,7 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
926
1019
  if (!resultCart) {
927
1020
  return void 0;
928
1021
  }
1022
+ console.log("npm addCartLines resultCart", resultCart);
929
1023
  if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
930
1024
  const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
931
1025
  if (unapplicableCodes.length > 0) {
@@ -947,6 +1041,9 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
947
1041
  discountCodes
948
1042
  });
949
1043
  }
1044
+ if (customAttributes && customAttributes.length > 0) {
1045
+ addCustomAttributes(customAttributes);
1046
+ }
950
1047
  if (withTrack) {
951
1048
  trackAddToCartGA({
952
1049
  lineItems,
@@ -1099,6 +1196,60 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
1099
1196
  );
1100
1197
  return useSWRMutation("buy-now", buyNow, swrOptions);
1101
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 = 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 = useMemo(() => {
1244
+ return allGiftLines.length > 0;
1245
+ }, [allGiftLines]);
1246
+ return {
1247
+ functionGift,
1248
+ scriptGift,
1249
+ allGiftLines,
1250
+ hasGifts
1251
+ };
1252
+ }
1102
1253
 
1103
1254
  // src/hooks/cart/types/order-discount.ts
1104
1255
  var OrderDiscountType = /* @__PURE__ */ ((OrderDiscountType2) => {
@@ -1219,12 +1370,10 @@ function useHasPlusMemberInCart({
1219
1370
  };
1220
1371
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1221
1372
  }
1222
-
1223
- // src/hooks/cart/feature/use-cart-attributes.ts
1224
1373
  var getReferralAttributes = () => {
1225
- const inviteCode = Cookies5.get("invite_code");
1226
- const playModeId = Cookies5.get("playModeId");
1227
- const popup = Cookies5.get("_popup");
1374
+ const inviteCode = getLocalStorage("invite_code") || Cookies5.get("invite_code");
1375
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
1376
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
1228
1377
  if (inviteCode && playModeId) {
1229
1378
  return popup ? [
1230
1379
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1248,8 +1397,6 @@ var useCartAttributes = ({
1248
1397
  memberSetting,
1249
1398
  cart
1250
1399
  });
1251
- console.log("memberSetting", memberSetting);
1252
- console.log("hasPlusMember", hasPlusMember);
1253
1400
  useEffect(() => {
1254
1401
  setCurrentUrl(window.location.href);
1255
1402
  }, []);
@@ -1275,7 +1422,7 @@ var useCartAttributes = ({
1275
1422
  return "new_user_login";
1276
1423
  }, [customer]);
1277
1424
  const memberAttributes = useMemo(() => {
1278
- return [
1425
+ const attributes = [
1279
1426
  {
1280
1427
  key: "_token",
1281
1428
  value: profile?.token
@@ -1296,17 +1443,28 @@ var useCartAttributes = ({
1296
1443
  value: profile?.token ? "true" : "false"
1297
1444
  }
1298
1445
  ];
1446
+ if (profile?.token) {
1447
+ attributes.push({
1448
+ key: "_login_user",
1449
+ value: "1"
1450
+ });
1451
+ }
1452
+ return attributes;
1299
1453
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1300
1454
  const functionAttributes = useMemo(() => {
1301
- return [
1302
- cart?.discountCodes && {
1455
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
1456
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1457
+ );
1458
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1459
+ return hasFunctionEnvAttribute ? [
1460
+ {
1303
1461
  key: "_discounts_function_env",
1304
1462
  value: JSON.stringify({
1305
- discount_code: cart?.discountCodes.map((item) => item.code),
1463
+ discount_code: discountCodes,
1306
1464
  user_tags: customer?.tags || []
1307
1465
  })
1308
1466
  }
1309
- ];
1467
+ ] : [];
1310
1468
  }, [cart]);
1311
1469
  const presellAttributes = useMemo(() => {
1312
1470
  return [
@@ -1338,18 +1496,50 @@ var useCartAttributes = ({
1338
1496
  }
1339
1497
  ];
1340
1498
  }, [currentUrl]);
1499
+ const commonAttributes = useMemo(
1500
+ () => [
1501
+ ...memberAttributes,
1502
+ ...functionAttributes,
1503
+ ...presellAttributes,
1504
+ ...weightAttributes,
1505
+ ...trackingAttributes,
1506
+ ...getReferralAttributes()
1507
+ ].filter((item) => item?.value),
1508
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1509
+ );
1510
+ const extraAttributesInCart = useMemo(() => {
1511
+ const commonAttributeKeys = [
1512
+ // member attributes
1513
+ "_token",
1514
+ "_member_type",
1515
+ "_user_type",
1516
+ "_is_login",
1517
+ "_login_user",
1518
+ // function attributes
1519
+ "_discounts_function_env",
1520
+ // presell attributes
1521
+ "_presale",
1522
+ // weight attributes
1523
+ "_weight",
1524
+ "_app_source_name",
1525
+ // tracking attributes
1526
+ "utm_params",
1527
+ // referral attributes
1528
+ "_invite_code",
1529
+ "_play_mode_id",
1530
+ "_popup"
1531
+ ];
1532
+ return cart?.customAttributes?.filter(
1533
+ (item) => !commonAttributeKeys.includes(item.key)
1534
+ ) || [];
1535
+ }, [cart]);
1341
1536
  return useMemo(
1342
1537
  () => ({
1343
- attributes: [
1344
- ...memberAttributes,
1345
- ...functionAttributes,
1346
- ...presellAttributes,
1347
- ...weightAttributes,
1348
- ...trackingAttributes,
1349
- ...getReferralAttributes()
1350
- ].filter((item) => item?.value)
1538
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1539
+ (item) => item?.value
1540
+ )
1351
1541
  }),
1352
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1542
+ [commonAttributes, extraAttributesInCart]
1353
1543
  );
1354
1544
  };
1355
1545
  var DEFAULT_MIN = 1;
@@ -1566,8 +1756,9 @@ function useProductsByHandles(options = {}) {
1566
1756
  metafieldIdentifiers
1567
1757
  });
1568
1758
  },
1569
- swrOptions || {
1570
- revalidateOnFocus: false
1759
+ {
1760
+ revalidateOnFocus: false,
1761
+ ...swrOptions
1571
1762
  }
1572
1763
  );
1573
1764
  }
@@ -2483,6 +2674,73 @@ var usePlusMemberDeliveryCodes = ({
2483
2674
  [deliveryData]
2484
2675
  );
2485
2676
  };
2677
+ function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2678
+ const { client, locale, cartCookieAdapter } = useShopify();
2679
+ const updateDeliveryOptions = useCallback(
2680
+ async (_key, { arg }) => {
2681
+ const updatedCart = await updateCartDeliveryOptions(client, {
2682
+ ...arg,
2683
+ metafieldIdentifiers,
2684
+ cookieAdapter: cartCookieAdapter
2685
+ });
2686
+ console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2687
+ if (updatedCart) {
2688
+ mutate(updatedCart);
2689
+ }
2690
+ return updatedCart;
2691
+ },
2692
+ [client, locale, cartCookieAdapter, mutate]
2693
+ );
2694
+ return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2695
+ }
2696
+
2697
+ // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2698
+ var useUpdatePlusMemberDeliveryOptions = ({
2699
+ options
2700
+ } = {}) => {
2701
+ const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2702
+ const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2703
+ mutateCart,
2704
+ metafieldIdentifiers
2705
+ );
2706
+ const handler = useCallback(
2707
+ async (_, { arg }) => {
2708
+ const currentCart = arg?.cart || cartContextData;
2709
+ const { deliveryData } = arg;
2710
+ const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2711
+ const deliveryGroupId = firstDeliveryGroup?.id;
2712
+ const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2713
+ if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2714
+ return null;
2715
+ }
2716
+ const deliveryGroup = currentCart?.deliveryGroups?.find(
2717
+ (group) => group?.id === deliveryGroupId
2718
+ );
2719
+ const matchedOption = deliveryGroup?.deliveryOptions?.find(
2720
+ (option) => option?.code === selectedOptionCode
2721
+ );
2722
+ if (!matchedOption?.handle) {
2723
+ return null;
2724
+ }
2725
+ const deliveryOptions = [
2726
+ {
2727
+ deliveryGroupId,
2728
+ deliveryOptionHandle: matchedOption.handle
2729
+ }
2730
+ ];
2731
+ const updatedCart = await updateCartDeliveryOptions2({
2732
+ selectedDeliveryOptions: deliveryOptions,
2733
+ cartId: currentCart?.id
2734
+ });
2735
+ if (updatedCart && mutateCart) {
2736
+ mutateCart(updatedCart);
2737
+ }
2738
+ return updatedCart;
2739
+ },
2740
+ [cartContextData, updateCartDeliveryOptions2, mutateCart]
2741
+ );
2742
+ return useSWRMutation("update-cart-delivery-options", handler, options);
2743
+ };
2486
2744
  var usePlusMemberItemCustomAttributes = ({
2487
2745
  deliveryData
2488
2746
  }) => {
@@ -2502,48 +2760,18 @@ var usePlusMemberCheckoutCustomAttributes = ({
2502
2760
  deliveryData,
2503
2761
  product,
2504
2762
  variant,
2505
- customer,
2506
2763
  isShowShippingBenefits
2507
2764
  }) => {
2508
2765
  const { deliveryCustomData } = deliveryData || {};
2509
2766
  const { profile } = usePlusMemberContext();
2510
- const userType = useMemo(() => {
2511
- const customerInfo = customer;
2512
- if (!customerInfo) {
2513
- return "new_user_unlogin";
2514
- }
2515
- if (customer) {
2516
- const { orders = {} } = customer;
2517
- const edgesLength = orders?.edges?.length;
2518
- if (edgesLength === 1) {
2519
- return "old_user_orders_once";
2520
- } else if (edgesLength && edgesLength > 1) {
2521
- return "old_user_orders_twice";
2522
- }
2523
- }
2524
- return "new_user_login";
2525
- }, [customer]);
2526
2767
  return useMemo(() => {
2527
2768
  const checkoutCustomAttributes = [
2528
- {
2529
- key: "_token",
2530
- value: profile?.token || ""
2531
- },
2769
+ // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2532
2770
  {
2533
2771
  key: "_last_url",
2534
2772
  value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2535
- },
2536
- {
2537
- key: "_user_type",
2538
- value: userType
2539
2773
  }
2540
2774
  ];
2541
- if (profile) {
2542
- checkoutCustomAttributes.push({
2543
- key: "_login_user",
2544
- value: "1"
2545
- });
2546
- }
2547
2775
  if (deliveryCustomData) {
2548
2776
  checkoutCustomAttributes.push({
2549
2777
  key: "_checkout_delivery_custom",
@@ -2553,12 +2781,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
2553
2781
  })
2554
2782
  });
2555
2783
  }
2556
- if (variant?.metafields?.presell) {
2557
- checkoutCustomAttributes.push({
2558
- key: "_presale",
2559
- value: "true"
2560
- });
2561
- }
2562
2784
  if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2563
2785
  checkoutCustomAttributes.push({
2564
2786
  key: "_hide_shipping",
@@ -2566,18 +2788,17 @@ var usePlusMemberCheckoutCustomAttributes = ({
2566
2788
  });
2567
2789
  }
2568
2790
  return checkoutCustomAttributes;
2569
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2791
+ }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2570
2792
  };
2571
2793
  function useAutoRemovePlusMemberInCart({
2572
- metafields,
2573
- isMonthlyPlus,
2574
- isAnnualPlus
2794
+ cart,
2795
+ profile,
2796
+ memberSetting
2575
2797
  }) {
2576
- const { plus_monthly_product, plus_annual_product } = metafields || {};
2577
- const { cart } = useCartContext();
2798
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2578
2799
  const { trigger: removeCartLines2 } = useRemoveCartLines();
2579
2800
  useEffect(() => {
2580
- if (!cart) return;
2801
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
2581
2802
  const removePlusProduct = async (productType) => {
2582
2803
  if (!productType) return;
2583
2804
  const product = cart.lineItems?.find(
@@ -2589,33 +2810,25 @@ function useAutoRemovePlusMemberInCart({
2589
2810
  });
2590
2811
  }
2591
2812
  };
2592
- if (isMonthlyPlus) {
2813
+ if (profile?.isMonthlyPlus) {
2593
2814
  removePlusProduct(plus_monthly_product);
2594
2815
  }
2595
- if (isAnnualPlus) {
2816
+ if (profile?.isAnnualPlus) {
2596
2817
  removePlusProduct(plus_annual_product);
2597
2818
  }
2598
- }, [
2599
- cart,
2600
- plus_annual_product,
2601
- plus_monthly_product,
2602
- isAnnualPlus,
2603
- isMonthlyPlus,
2604
- removeCartLines2
2605
- ]);
2819
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2606
2820
  }
2607
2821
  function useAddPlusMemberProductsToCart({
2608
2822
  cart,
2609
- memberSetting,
2610
- selectedPlusMemberMode,
2611
- selectedPlusMemberProduct
2823
+ profile
2612
2824
  }) {
2825
+ const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2613
2826
  const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2614
- cart,
2615
- memberSetting
2827
+ memberSetting: plusMemberMetafields,
2828
+ cart
2616
2829
  });
2617
2830
  const plusMemberProduct = useMemo(() => {
2618
- if (selectedPlusMemberMode === "free" /* FREE */) {
2831
+ if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2619
2832
  return void 0;
2620
2833
  }
2621
2834
  if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
@@ -2624,7 +2837,10 @@ function useAddPlusMemberProductsToCart({
2624
2837
  if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2625
2838
  return void 0;
2626
2839
  }
2627
- if (!selectedPlusMemberProduct) {
2840
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2841
+ return void 0;
2842
+ }
2843
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2628
2844
  return void 0;
2629
2845
  }
2630
2846
  return selectedPlusMemberProduct;
@@ -2943,8 +3159,13 @@ function CartProvider({
2943
3159
  const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
2944
3160
  useRequest(
2945
3161
  () => {
2946
- const newAttributes = [...attributes, ...customAttributes];
2947
- const needUpdate = cart && !checkAttributesUpdateNeeded(
3162
+ const newAttributes = [...attributes];
3163
+ customAttributes.forEach((item) => {
3164
+ if (item.value && !newAttributes.some((attr) => attr.key === item.key)) {
3165
+ newAttributes.push(item);
3166
+ }
3167
+ });
3168
+ const needUpdate = cart && checkAttributesUpdateNeeded(
2948
3169
  cart.customAttributes,
2949
3170
  newAttributes,
2950
3171
  customAttributesNeedDelete
@@ -3048,8 +3269,14 @@ function CartProvider({
3048
3269
  );
3049
3270
  return result;
3050
3271
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
3272
+ const totalQuantity = useMemo(() => {
3273
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
3274
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3275
+ return cartLinesCount + giftLinesCount;
3276
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
3051
3277
  const value = useMemo(
3052
3278
  () => ({
3279
+ totalQuantity,
3053
3280
  cart,
3054
3281
  isCartLoading,
3055
3282
  triggerFetch: fetchCart,
@@ -3061,6 +3288,7 @@ function CartProvider({
3061
3288
  isCodeChanging,
3062
3289
  setIsCodeChanging,
3063
3290
  autoFreeGiftConfig,
3291
+ gradientGiftsConfig,
3064
3292
  setLoadingState,
3065
3293
  loadingState,
3066
3294
  // function满赠
@@ -3076,6 +3304,7 @@ function CartProvider({
3076
3304
  }),
3077
3305
  [
3078
3306
  cart,
3307
+ totalQuantity,
3079
3308
  isCartLoading,
3080
3309
  fetchCart,
3081
3310
  mutateCart,
@@ -3084,6 +3313,7 @@ function CartProvider({
3084
3313
  locale,
3085
3314
  isCodeChanging,
3086
3315
  autoFreeGiftConfig,
3316
+ gradientGiftsConfig,
3087
3317
  loadingState,
3088
3318
  // function满赠
3089
3319
  functionAutoFreeGift,
@@ -3107,6 +3337,6 @@ function useCartContext() {
3107
3337
  return context;
3108
3338
  }
3109
3339
 
3110
- export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, CartProvider, DeliveryPlusType, MAIN_PRODUCT_CODE, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, ShopifyContext, ShopifyProvider, SpendMoneyType, atobID, browserCartCookieAdapter, browserCookieAdapter, btoaID, checkAttributesUpdateNeeded, clearGeoLocationCache, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, gaTrack, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, preCheck, safeParse, trackAddToCartFBQ, trackAddToCartGA, trackBeginCheckoutGA, trackBuyNowFBQ, trackBuyNowGA, useAddCartLines, useAddPlusMemberProductsToCart, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcOrderDiscount, useCartAttributes, useCartContext, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useIntersection, usePlusAnnualProductVariant, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberDeliveryCodes, usePlusMemberItemCustomAttributes, usePlusMonthlyProductVariant, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethodAvailableCheck, useShippingMethods, useShopify, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3340
+ export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, CartProvider, DeliveryPlusType, MAIN_PRODUCT_CODE, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, ShopifyContext, ShopifyProvider, SpendMoneyType, browserCartCookieAdapter, browserCookieAdapter, checkAttributesUpdateNeeded, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, gaTrack, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, normalizeAddToCartLines, preCheck, safeParse, trackAddToCartFBQ, trackAddToCartGA, trackBeginCheckoutGA, trackBuyNowFBQ, trackBuyNowGA, useAddCartLines, useAddPlusMemberProductsToCart, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartContext, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useIntersection, usePlusAnnualProductVariant, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberDeliveryCodes, usePlusMemberItemCustomAttributes, usePlusMonthlyProductVariant, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethodAvailableCheck, useShippingMethods, useShopify, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdatePlusMemberDeliveryOptions, useUpdateVariantQuery, useVariant, useVariantMedia };
3111
3341
  //# sourceMappingURL=index.mjs.map
3112
3342
  //# sourceMappingURL=index.mjs.map