@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.
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
- import { ShopifyClient, ShopifyConfig, CartCookieAdapter as CartCookieAdapter$1, NormalizedCart, HasMetafieldsIdentifier } from '@anker-in/shopify-sdk';
4
- import { C as CookieAdapter, b as CartCookieAdapter, R as RouterAdapter, U as UserContextAdapter } from '../types-BLMoxbOk.mjs';
3
+ import { ShopifyClient, ShopifyConfig, CartCookieAdapter, NormalizedCart, AttributeInput, HasMetafieldsIdentifier } from '@anker-in/shopify-sdk';
4
+ import { C as CookieAdapter, R as RouterAdapter, U as UserContextAdapter } from '../types-Dt0DUG00.mjs';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { SWRConfiguration } from 'swr';
7
- import { e as PlusMemberSettingsMetafields } from '../types-CICUnw0v.mjs';
7
+ import { e as PlusMemberSettingsMetafields } from '../types-C1So3siD.mjs';
8
8
  import 'swr/mutation';
9
9
 
10
10
  interface ShopifyContextValue {
@@ -24,7 +24,7 @@ interface ShopifyProviderProps {
24
24
  locale: string;
25
25
  locales?: string[];
26
26
  cookieAdapter?: CookieAdapter;
27
- cartCookieAdapter?: CartCookieAdapter$1;
27
+ cartCookieAdapter?: CartCookieAdapter;
28
28
  routerAdapter?: RouterAdapter;
29
29
  userAdapter?: UserContextAdapter;
30
30
  children: React__default.ReactNode;
@@ -41,10 +41,6 @@ declare function ShopifyProvider({ config, locale, locales, cookieAdapter, cartC
41
41
  */
42
42
  declare function useShopify(): ShopifyContextValue;
43
43
 
44
- type AttributeInput = {
45
- key: string;
46
- value: string;
47
- };
48
44
  type LoadingState = {
49
45
  editLineQuantityLoading: boolean;
50
46
  editLineCodeAmountLoading: boolean;
@@ -54,6 +50,8 @@ type LoadingState = {
54
50
  interface CartContextValue {
55
51
  /** Current cart data */
56
52
  cart: NormalizedCart | undefined;
53
+ /** Total quantity of items in cart */
54
+ totalQuantity: number;
57
55
  /** Whether cart is loading */
58
56
  isCartLoading: boolean;
59
57
  /** Manually trigger cart fetch */
@@ -96,6 +94,8 @@ interface CartContextValue {
96
94
  giftNeedAddToCartLines: any[];
97
95
  /** Auto free gift config */
98
96
  autoFreeGiftConfig?: any;
97
+ /** Gradient gifts config */
98
+ gradientGiftsConfig?: any;
99
99
  /** Metafield identifiers */
100
100
  metafieldIdentifiers?: {
101
101
  variant: HasMetafieldsIdentifier[];
@@ -159,4 +159,4 @@ declare function CartProvider({ children, autoFreeGiftConfig, gradientGiftsConfi
159
159
  */
160
160
  declare function useCartContext(): CartContextValue;
161
161
 
162
- export { type AttributeInput, type CartContextValue, CartProvider, type CartProviderProps, type LoadingState, ShopifyContext, type ShopifyContextValue, ShopifyProvider, type ShopifyProviderProps, useCartContext, useShopify };
162
+ export { type CartContextValue, CartProvider, type CartProviderProps, type LoadingState, ShopifyContext, type ShopifyContextValue, ShopifyProvider, type ShopifyProviderProps, useCartContext, useShopify };
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
- import { ShopifyClient, ShopifyConfig, CartCookieAdapter as CartCookieAdapter$1, NormalizedCart, HasMetafieldsIdentifier } from '@anker-in/shopify-sdk';
4
- import { C as CookieAdapter, b as CartCookieAdapter, R as RouterAdapter, U as UserContextAdapter } from '../types-BLMoxbOk.js';
3
+ import { ShopifyClient, ShopifyConfig, CartCookieAdapter, NormalizedCart, AttributeInput, HasMetafieldsIdentifier } from '@anker-in/shopify-sdk';
4
+ import { C as CookieAdapter, R as RouterAdapter, U as UserContextAdapter } from '../types-Dt0DUG00.js';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { SWRConfiguration } from 'swr';
7
- import { e as PlusMemberSettingsMetafields } from '../types-CICUnw0v.js';
7
+ import { e as PlusMemberSettingsMetafields } from '../types-C1So3siD.js';
8
8
  import 'swr/mutation';
9
9
 
10
10
  interface ShopifyContextValue {
@@ -24,7 +24,7 @@ interface ShopifyProviderProps {
24
24
  locale: string;
25
25
  locales?: string[];
26
26
  cookieAdapter?: CookieAdapter;
27
- cartCookieAdapter?: CartCookieAdapter$1;
27
+ cartCookieAdapter?: CartCookieAdapter;
28
28
  routerAdapter?: RouterAdapter;
29
29
  userAdapter?: UserContextAdapter;
30
30
  children: React__default.ReactNode;
@@ -41,10 +41,6 @@ declare function ShopifyProvider({ config, locale, locales, cookieAdapter, cartC
41
41
  */
42
42
  declare function useShopify(): ShopifyContextValue;
43
43
 
44
- type AttributeInput = {
45
- key: string;
46
- value: string;
47
- };
48
44
  type LoadingState = {
49
45
  editLineQuantityLoading: boolean;
50
46
  editLineCodeAmountLoading: boolean;
@@ -54,6 +50,8 @@ type LoadingState = {
54
50
  interface CartContextValue {
55
51
  /** Current cart data */
56
52
  cart: NormalizedCart | undefined;
53
+ /** Total quantity of items in cart */
54
+ totalQuantity: number;
57
55
  /** Whether cart is loading */
58
56
  isCartLoading: boolean;
59
57
  /** Manually trigger cart fetch */
@@ -96,6 +94,8 @@ interface CartContextValue {
96
94
  giftNeedAddToCartLines: any[];
97
95
  /** Auto free gift config */
98
96
  autoFreeGiftConfig?: any;
97
+ /** Gradient gifts config */
98
+ gradientGiftsConfig?: any;
99
99
  /** Metafield identifiers */
100
100
  metafieldIdentifiers?: {
101
101
  variant: HasMetafieldsIdentifier[];
@@ -159,4 +159,4 @@ declare function CartProvider({ children, autoFreeGiftConfig, gradientGiftsConfi
159
159
  */
160
160
  declare function useCartContext(): CartContextValue;
161
161
 
162
- export { type AttributeInput, type CartContextValue, CartProvider, type CartProviderProps, type LoadingState, ShopifyContext, type ShopifyContextValue, ShopifyProvider, type ShopifyProviderProps, useCartContext, useShopify };
162
+ export { type CartContextValue, CartProvider, type CartProviderProps, type LoadingState, ShopifyContext, type ShopifyContextValue, ShopifyProvider, type ShopifyProviderProps, useCartContext, useShopify };
@@ -104,6 +104,81 @@ var CODE_AMOUNT_KEY = "_sku_code_money";
104
104
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
105
105
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
106
106
 
107
+ // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
108
+ function normalizeAddToCartLines(lines) {
109
+ return lines.filter((line) => line.variant?.id).map((line, index) => {
110
+ const variant = line.variant;
111
+ const product = variant.product;
112
+ const quantity = line.quantity || 1;
113
+ const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
114
+ const subtotalAmount = price * quantity;
115
+ const totalAmount = subtotalAmount;
116
+ return {
117
+ id: `temp-line-${index}-${variant.id}`,
118
+ // Temporary ID for pre-cart lines
119
+ name: product?.title || variant.title || "",
120
+ quantity,
121
+ variantId: variant.id,
122
+ productId: product?.id || variant.id.split("/").slice(0, -2).join("/"),
123
+ totalAmount,
124
+ subtotalAmount,
125
+ discountAllocations: [],
126
+ customAttributes: line.attributes || [],
127
+ variant: {
128
+ id: variant.id,
129
+ price,
130
+ listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
131
+ sku: variant.sku || "",
132
+ name: variant.title || "",
133
+ image: variant.image ? {
134
+ url: variant.image.url,
135
+ altText: variant.image.altText || void 0
136
+ } : void 0,
137
+ requiresShipping: false,
138
+ // Default value, not available in NormalizedProductVariant
139
+ availableForSale: variant.availableForSale ?? true,
140
+ quantityAvailable: variant.quantityAvailable ?? 0,
141
+ currentlyNotInStock: false,
142
+ // Default value, will be updated when added to cart
143
+ weight: variant.weight,
144
+ metafields: variant.metafields
145
+ },
146
+ product,
147
+ path: product?.handle ? `/products/${product.handle}` : "",
148
+ discounts: [],
149
+ options: variant.selectedOptions?.map((opt) => ({
150
+ name: opt.name,
151
+ value: opt.value
152
+ }))
153
+ };
154
+ });
155
+ }
156
+ function createMockCartFromLines(lines, existingCart) {
157
+ const normalizedLines = normalizeAddToCartLines(lines);
158
+ const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
159
+ const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
160
+ return {
161
+ id: existingCart?.id || "temp-cart-id",
162
+ customerId: existingCart?.customerId,
163
+ email: existingCart?.email,
164
+ createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
165
+ currency: existingCart?.currency || { code: "USD" },
166
+ taxesIncluded: existingCart?.taxesIncluded,
167
+ lineItems: normalizedLines,
168
+ totalLineItemsDiscount: 0,
169
+ orderDiscounts: 0,
170
+ lineItemsSubtotalPrice: subtotalPrice,
171
+ subtotalPrice,
172
+ totalPrice,
173
+ totalTaxAmount: 0,
174
+ discountCodes: existingCart?.discountCodes || [],
175
+ discountAllocations: [],
176
+ url: existingCart?.url || "",
177
+ ready: true,
178
+ customAttributes: existingCart?.customAttributes
179
+ };
180
+ }
181
+
107
182
  // src/hooks/cart/utils/index.ts
108
183
  var getQuery = () => {
109
184
  const url = typeof window !== "undefined" ? window.location.search : "";
@@ -121,22 +196,12 @@ var getQuery = () => {
121
196
  }
122
197
  return theRequest;
123
198
  };
124
- function atobID(id) {
125
- if (id && typeof id === "string" && id.includes("/")) {
126
- return id.split("/").pop()?.split("?")?.shift();
127
- } else {
128
- return id;
129
- }
130
- }
131
- function btoaID(id, type = "ProductVariant") {
132
- return `gid://shopify/${type}/${id}`;
133
- }
134
199
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
135
200
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
136
201
  const matchedList = cartData?.lineItems?.filter((line) => {
137
202
  const { is_gift } = getDiscountEnvAttributeValue(line.customAttributes);
138
203
  return isAllStoreVariant ? !is_gift : variant_list?.find((item) => {
139
- return !is_gift && atobID(line.variantId) === item;
204
+ return !is_gift && shopifySdk.atobID(line.variantId) === item;
140
205
  });
141
206
  });
142
207
  return matchedList?.reduce((acc, line) => {
@@ -328,12 +393,15 @@ var formatFunctionAutoFreeGift = ({
328
393
  };
329
394
  return result;
330
395
  };
331
- var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
396
+ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
332
397
  const tags = react.useMemo(() => customer?.tags || [], [customer?.tags]);
333
398
  const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
334
399
  const dealsType = "";
335
400
  const { client, locale } = useShopify();
336
401
  const giftProductsCache = react.useRef(null);
402
+ const effectiveCart = react.useMemo(() => {
403
+ return cart;
404
+ }, [lines, cart]);
337
405
  const { activeCampaign, subtotal } = react.useMemo(() => {
338
406
  for (const campaign of autoFreeGiftConfig) {
339
407
  const { rule_conditions = [], rule_result } = campaign;
@@ -341,7 +409,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
341
409
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
342
410
  if (isPreCheckPassed && spend_get_reward) {
343
411
  const matchedSubtotal = getMatchedMainProductSubTotal(
344
- cart,
412
+ effectiveCart,
345
413
  spend_get_reward.main_product?.variant_list?.map((v) => v.variant_id) || [],
346
414
  {
347
415
  spend_money_type: spend_get_reward.main_product?.spend_money_type || 1,
@@ -355,13 +423,13 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
355
423
  }
356
424
  }
357
425
  return { activeCampaign: null, subtotal: 0 };
358
- }, [autoFreeGiftConfig, cart, tags, dealsType]);
426
+ }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
359
427
  const { qualifyingGift, nextTierGoal } = react.useMemo(() => {
360
428
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
361
429
  return { qualifyingGift: null, nextTierGoal: null };
362
430
  }
363
431
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
364
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
432
+ const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
365
433
  const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
366
434
  if (!qualifyingTier) {
367
435
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
@@ -373,7 +441,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
373
441
  if (!giftProduct) return null;
374
442
  return {
375
443
  variant: {
376
- id: btoaID(giftProduct.variant_id),
444
+ id: shopifySdk.btoaID(giftProduct.variant_id),
377
445
  handle: giftProduct.handle,
378
446
  sku: giftProduct.sku
379
447
  },
@@ -408,18 +476,24 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
408
476
  }
409
477
  return true;
410
478
  }, [giftHandles]);
411
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
412
- const res = await shopifySdk.getProductsByHandles(client, {
413
- handles: giftHandles,
414
- locale
415
- });
416
- const result = Array.isArray(res) ? res : [];
417
- giftProductsCache.current = {
418
- data: result,
419
- giftHandles: [...giftHandles]
420
- };
421
- return result;
422
- });
479
+ const { data: giftProductsResult } = useSWR__default.default(
480
+ shouldFetch ? giftHandles : null,
481
+ async () => {
482
+ const res = await shopifySdk.getProductsByHandles(client, {
483
+ handles: giftHandles,
484
+ locale
485
+ });
486
+ const result = Array.isArray(res) ? res : [];
487
+ giftProductsCache.current = {
488
+ data: result,
489
+ giftHandles: [...giftHandles]
490
+ };
491
+ return result;
492
+ },
493
+ {
494
+ revalidateOnFocus: false
495
+ }
496
+ );
423
497
  const finalGiftProductsResult = react.useMemo(() => {
424
498
  if (giftProductsCache.current && !shouldFetch) {
425
499
  return giftProductsCache.current.data || void 0;
@@ -438,12 +512,19 @@ var useScriptAutoFreeGift = ({
438
512
  campaign,
439
513
  _giveaway,
440
514
  cart,
441
- locale: providedLocale
515
+ locale: providedLocale,
516
+ lines
442
517
  }) => {
443
518
  const { client, locale: contextLocale } = useShopify();
444
519
  const locale = providedLocale || contextLocale;
445
520
  const [points_subscribe, set_points_subscribe] = react.useState(false);
446
521
  const giftProductsCache = react.useRef(null);
522
+ const effectiveCart = react.useMemo(() => {
523
+ if (lines && lines.length > 0) {
524
+ return createMockCartFromLines(lines, cart);
525
+ }
526
+ return cart;
527
+ }, [lines, cart]);
447
528
  react.useEffect(() => {
448
529
  if (locale === "au") {
449
530
  const isPointsSubscribe = Cookies5__default.default.get("points_subscribe");
@@ -465,14 +546,16 @@ var useScriptAutoFreeGift = ({
465
546
  upgrade_multiple2 = 1.2;
466
547
  upgrade_value2 = 40;
467
548
  }
468
- cart?.lineItems?.forEach(({ customAttributes }) => {
469
- customAttributes?.forEach(({ key, value }) => {
470
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
471
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
472
- });
473
- });
549
+ effectiveCart?.lineItems?.forEach(
550
+ ({ customAttributes }) => {
551
+ customAttributes?.forEach(({ key, value }) => {
552
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
553
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
554
+ });
555
+ }
556
+ );
474
557
  return [upgrade_multiple2, upgrade_value2];
475
- }, [cart?.lineItems, points_subscribe]);
558
+ }, [effectiveCart?.lineItems, points_subscribe]);
476
559
  const breakpoints = react.useMemo(() => {
477
560
  if (!isActivityAvailable) return [];
478
561
  return (campaign?.breakpoints || []).map((item) => ({
@@ -500,7 +583,7 @@ var useScriptAutoFreeGift = ({
500
583
  }, [giftHandles]);
501
584
  const involvedLines = react.useMemo(() => {
502
585
  if (!isActivityAvailable) return [];
503
- return (cart?.lineItems || []).filter((line) => {
586
+ return (effectiveCart?.lineItems || []).filter((line) => {
504
587
  const isNotGift = line?.totalAmount && Number(line.totalAmount) > 0 && line.customAttributes?.every(
505
588
  (item) => item.key !== _giveaway
506
589
  );
@@ -509,7 +592,7 @@ var useScriptAutoFreeGift = ({
509
592
  );
510
593
  return isNotGift && hasCampaignTag;
511
594
  });
512
- }, [cart?.lineItems, isActivityAvailable, _giveaway]);
595
+ }, [effectiveCart?.lineItems, isActivityAvailable, _giveaway]);
513
596
  const involvedSubTotal = react.useMemo(() => {
514
597
  if (!isActivityAvailable) return new Decimal2__default.default(0);
515
598
  return involvedLines.reduce((prev, item) => {
@@ -535,18 +618,24 @@ var useScriptAutoFreeGift = ({
535
618
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
536
619
  return [currentLevel, nextLevel];
537
620
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
538
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
539
- const res = await shopifySdk.getProductsByHandles(client, {
540
- handles: giftHandles,
541
- locale
542
- });
543
- const result = Array.isArray(res) ? res : [];
544
- giftProductsCache.current = {
545
- data: result,
546
- giftHandles: [...giftHandles]
547
- };
548
- return result;
549
- });
621
+ const { data: giftProductsResult } = useSWR__default.default(
622
+ shouldFetch ? giftHandles : null,
623
+ async () => {
624
+ const res = await shopifySdk.getProductsByHandles(client, {
625
+ handles: giftHandles,
626
+ locale
627
+ });
628
+ const result = Array.isArray(res) ? res : [];
629
+ giftProductsCache.current = {
630
+ data: result,
631
+ giftHandles: [...giftHandles]
632
+ };
633
+ return result;
634
+ },
635
+ {
636
+ revalidateOnFocus: false
637
+ }
638
+ );
550
639
  const finalGiftProductsResult = react.useMemo(() => {
551
640
  if (giftProductsCache.current && !shouldFetch) {
552
641
  return giftProductsCache.current.data || void 0;
@@ -628,12 +717,10 @@ function useHasPlusMemberInCart({
628
717
  };
629
718
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
630
719
  }
631
-
632
- // src/hooks/cart/feature/use-cart-attributes.ts
633
720
  var getReferralAttributes = () => {
634
- const inviteCode = Cookies5__default.default.get("invite_code");
635
- const playModeId = Cookies5__default.default.get("playModeId");
636
- const popup = Cookies5__default.default.get("_popup");
721
+ const inviteCode = shopifySdk.getLocalStorage("invite_code") || Cookies5__default.default.get("invite_code");
722
+ const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
723
+ const popup = shopifySdk.getLocalStorage("_popup") || Cookies5__default.default.get("_popup");
637
724
  if (inviteCode && playModeId) {
638
725
  return popup ? [
639
726
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -657,8 +744,6 @@ var useCartAttributes = ({
657
744
  memberSetting,
658
745
  cart
659
746
  });
660
- console.log("memberSetting", memberSetting);
661
- console.log("hasPlusMember", hasPlusMember);
662
747
  react.useEffect(() => {
663
748
  setCurrentUrl(window.location.href);
664
749
  }, []);
@@ -684,7 +769,7 @@ var useCartAttributes = ({
684
769
  return "new_user_login";
685
770
  }, [customer]);
686
771
  const memberAttributes = react.useMemo(() => {
687
- return [
772
+ const attributes = [
688
773
  {
689
774
  key: "_token",
690
775
  value: profile?.token
@@ -705,17 +790,28 @@ var useCartAttributes = ({
705
790
  value: profile?.token ? "true" : "false"
706
791
  }
707
792
  ];
793
+ if (profile?.token) {
794
+ attributes.push({
795
+ key: "_login_user",
796
+ value: "1"
797
+ });
798
+ }
799
+ return attributes;
708
800
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
709
801
  const functionAttributes = react.useMemo(() => {
710
- return [
711
- cart?.discountCodes && {
802
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
803
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
804
+ );
805
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
806
+ return hasFunctionEnvAttribute ? [
807
+ {
712
808
  key: "_discounts_function_env",
713
809
  value: JSON.stringify({
714
- discount_code: cart?.discountCodes.map((item) => item.code),
810
+ discount_code: discountCodes,
715
811
  user_tags: customer?.tags || []
716
812
  })
717
813
  }
718
- ];
814
+ ] : [];
719
815
  }, [cart]);
720
816
  const presellAttributes = react.useMemo(() => {
721
817
  return [
@@ -747,18 +843,50 @@ var useCartAttributes = ({
747
843
  }
748
844
  ];
749
845
  }, [currentUrl]);
846
+ const commonAttributes = react.useMemo(
847
+ () => [
848
+ ...memberAttributes,
849
+ ...functionAttributes,
850
+ ...presellAttributes,
851
+ ...weightAttributes,
852
+ ...trackingAttributes,
853
+ ...getReferralAttributes()
854
+ ].filter((item) => item?.value),
855
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
856
+ );
857
+ const extraAttributesInCart = react.useMemo(() => {
858
+ const commonAttributeKeys = [
859
+ // member attributes
860
+ "_token",
861
+ "_member_type",
862
+ "_user_type",
863
+ "_is_login",
864
+ "_login_user",
865
+ // function attributes
866
+ "_discounts_function_env",
867
+ // presell attributes
868
+ "_presale",
869
+ // weight attributes
870
+ "_weight",
871
+ "_app_source_name",
872
+ // tracking attributes
873
+ "utm_params",
874
+ // referral attributes
875
+ "_invite_code",
876
+ "_play_mode_id",
877
+ "_popup"
878
+ ];
879
+ return cart?.customAttributes?.filter(
880
+ (item) => !commonAttributeKeys.includes(item.key)
881
+ ) || [];
882
+ }, [cart]);
750
883
  return react.useMemo(
751
884
  () => ({
752
- attributes: [
753
- ...memberAttributes,
754
- ...functionAttributes,
755
- ...presellAttributes,
756
- ...weightAttributes,
757
- ...trackingAttributes,
758
- ...getReferralAttributes()
759
- ].filter((item) => item?.value)
885
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
886
+ (item) => item?.value
887
+ )
760
888
  }),
761
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
889
+ [commonAttributes, extraAttributesInCart]
762
890
  );
763
891
  };
764
892
  var useUpdateLineCodeAmountAttributes = ({
@@ -974,8 +1102,13 @@ function CartProvider({
974
1102
  const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
975
1103
  ahooks.useRequest(
976
1104
  () => {
977
- const newAttributes = [...attributes, ...customAttributes];
978
- const needUpdate = cart && !checkAttributesUpdateNeeded(
1105
+ const newAttributes = [...attributes];
1106
+ customAttributes.forEach((item) => {
1107
+ if (item.value && !newAttributes.some((attr) => attr.key === item.key)) {
1108
+ newAttributes.push(item);
1109
+ }
1110
+ });
1111
+ const needUpdate = cart && checkAttributesUpdateNeeded(
979
1112
  cart.customAttributes,
980
1113
  newAttributes,
981
1114
  customAttributesNeedDelete
@@ -1079,8 +1212,14 @@ function CartProvider({
1079
1212
  );
1080
1213
  return result;
1081
1214
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
1215
+ const totalQuantity = react.useMemo(() => {
1216
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
1217
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
1218
+ return cartLinesCount + giftLinesCount;
1219
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
1082
1220
  const value = react.useMemo(
1083
1221
  () => ({
1222
+ totalQuantity,
1084
1223
  cart,
1085
1224
  isCartLoading,
1086
1225
  triggerFetch: fetchCart,
@@ -1092,6 +1231,7 @@ function CartProvider({
1092
1231
  isCodeChanging,
1093
1232
  setIsCodeChanging,
1094
1233
  autoFreeGiftConfig,
1234
+ gradientGiftsConfig,
1095
1235
  setLoadingState,
1096
1236
  loadingState,
1097
1237
  // function满赠
@@ -1107,6 +1247,7 @@ function CartProvider({
1107
1247
  }),
1108
1248
  [
1109
1249
  cart,
1250
+ totalQuantity,
1110
1251
  isCartLoading,
1111
1252
  fetchCart,
1112
1253
  mutateCart,
@@ -1115,6 +1256,7 @@ function CartProvider({
1115
1256
  locale,
1116
1257
  isCodeChanging,
1117
1258
  autoFreeGiftConfig,
1259
+ gradientGiftsConfig,
1118
1260
  loadingState,
1119
1261
  // function满赠
1120
1262
  functionAutoFreeGift,