@anker-in/shopify-react 1.3.0-beta.1 → 1.3.0-beta.11

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,9 +1,9 @@
1
1
  import * as swr_mutation from 'swr/mutation';
2
2
  import { SWRMutationConfiguration } from 'swr/mutation';
3
3
  import * as _anker_in_shopify_sdk from '@anker-in/shopify-sdk';
4
- import { CartLineInput, BuyerIdentityInput, NormalizedCart, NormalizedProduct, NormalizedProductVariant, NormalizedLineItem, UpdateCartLinesOptions, HasMetafieldsIdentifier, Media, NormalizedCollection, CollectionsConnection, NormalizedBlog, NormalizedArticle, NormalizedAttribute } from '@anker-in/shopify-sdk';
5
- import { h as UseAddToCartOptions, g as AddToCartInput, A as AddToCartLineItem, G as GtmParams, C as BuyNowTrackConfig, e as UseScriptAutoFreeGiftResult, m as PlusMemberShippingMethodConfig, n as PlusMemberSettingsMetafields, D as DeliveryPlusType, o as SelectedPlusMemberVariant } from '../types-CM5QrlnE.mjs';
6
- export { p as DeliveryCustomData, P as PLUS_MEMBER_TYPE, j as PlusMemberMode, l as PlusMemberShippingMethodMetafields, S as ScriptAutoFreeGiftConfig, k as ShippingMethodMode, U as UseAutoRemoveFreeGiftsOptions, a as UseAutoRemoveFreeGiftsResult, d as isAnyGift, c as isBuyGetGift, i as isFunctionGift, b as isScriptGift, u as useAutoRemoveFreeGifts, f as useScriptAutoFreeGift } from '../types-CM5QrlnE.mjs';
4
+ import { CartLineInput, BuyerIdentityInput, NormalizedCart, NormalizedProduct, NormalizedProductVariant, NormalizedLineItem, UpdateCartLinesOptions, HasMetafieldsIdentifier, Media, NormalizedCollection, CollectionsConnection, NormalizedBlog, NormalizedArticle, NormalizedShop, NormalizedAttribute } from '@anker-in/shopify-sdk';
5
+ import { h as UseAddToCartOptions, g as AddToCartInput, A as AddToCartLineItem, G as GtmParams, C as BuyNowTrackConfig, e as UseScriptAutoFreeGiftResult, m as PlusMemberShippingMethodConfig, n as PlusMemberSettingsMetafields, D as DeliveryPlusType, o as SelectedPlusMemberVariant } from '../types-C0UyuPrG.mjs';
6
+ export { p as DeliveryCustomData, P as PLUS_MEMBER_TYPE, j as PlusMemberMode, l as PlusMemberShippingMethodMetafields, S as ScriptAutoFreeGiftConfig, k as ShippingMethodMode, U as UseAutoRemoveFreeGiftsOptions, a as UseAutoRemoveFreeGiftsResult, d as isAnyGift, c as isBuyGetGift, i as isFunctionGift, b as isScriptGift, u as useAutoRemoveFreeGifts, f as useScriptAutoFreeGift } from '../types-C0UyuPrG.mjs';
7
7
  import * as swr from 'swr';
8
8
  import swr__default, { SWRConfiguration } from 'swr';
9
9
  import * as swr__internal from 'swr/_internal';
@@ -920,7 +920,7 @@ interface UseAllProductsOptions extends SWRConfiguration<NormalizedProduct[]> {
920
920
  */
921
921
  declare function useAllProducts(options?: UseAllProductsOptions): swr.SWRResponse<NormalizedProduct[], any, SWRConfiguration<NormalizedProduct[], any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>)> | undefined>;
922
922
 
923
- interface UseProductsByHandlesOptions extends SWRConfiguration<NormalizedProduct[]> {
923
+ interface UseProductsByHandlesOptions extends SWRConfiguration<(NormalizedProduct | undefined)[]> {
924
924
  handles?: string[];
925
925
  metafieldIdentifiers?: {
926
926
  product: HasMetafieldsIdentifier[];
@@ -956,7 +956,7 @@ interface UseProductsByHandlesOptions extends SWRConfiguration<NormalizedProduct
956
956
  * }
957
957
  * ```
958
958
  */
959
- declare function useProductsByHandles(options?: UseProductsByHandlesOptions): swr.SWRResponse<NormalizedProduct[], any, SWRConfiguration<NormalizedProduct[], any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>)> | undefined>;
959
+ declare function useProductsByHandles(options?: UseProductsByHandlesOptions): swr.SWRResponse<(NormalizedProduct | undefined)[], any, SWRConfiguration<(NormalizedProduct | undefined)[], any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<(NormalizedProduct | undefined)[]>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<(NormalizedProduct | undefined)[]>)> | undefined>;
960
960
 
961
961
  /**
962
962
  * useVariant Hook
@@ -1350,33 +1350,14 @@ interface UseSearchOptions extends SWRConfiguration<SearchResult | undefined> {
1350
1350
  }
1351
1351
  declare function useSearch(options?: UseSearchOptions): swr.SWRResponse<SearchResult | undefined, any, SWRConfiguration<SearchResult | undefined, any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SearchResult | undefined>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SearchResult | undefined>)> | undefined>;
1352
1352
 
1353
- interface SiteInfo {
1354
- name: string;
1355
- description?: string;
1356
- primaryDomain: {
1357
- url: string;
1358
- host: string;
1359
- };
1360
- brand?: {
1361
- logo?: {
1362
- image?: {
1363
- url: string;
1364
- };
1365
- };
1366
- colors?: {
1367
- primary?: string;
1368
- secondary?: string;
1369
- };
1370
- };
1371
- metafields?: Record<string, any>;
1372
- }
1353
+ type SiteInfo = NormalizedShop;
1373
1354
  interface UseSiteOptions extends SWRConfiguration<SiteInfo | undefined> {
1374
1355
  metafieldIdentifiers?: Array<{
1375
1356
  namespace: string;
1376
1357
  key: string;
1377
1358
  }>;
1378
1359
  }
1379
- declare function useSite(options?: UseSiteOptions): swr.SWRResponse<SiteInfo | undefined, any, SWRConfiguration<SiteInfo | undefined, any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SiteInfo | undefined>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SiteInfo | undefined>)> | undefined>;
1360
+ declare function useSite(options?: UseSiteOptions): swr.SWRResponse<NormalizedShop | undefined, any, SWRConfiguration<NormalizedShop | undefined, any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedShop | undefined>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedShop | undefined>)> | undefined>;
1380
1361
 
1381
1362
  interface ShippingMethodsContext {
1382
1363
  freeShippingMethods: PlusMemberShippingMethodConfig[];
@@ -1,9 +1,9 @@
1
1
  import * as swr_mutation from 'swr/mutation';
2
2
  import { SWRMutationConfiguration } from 'swr/mutation';
3
3
  import * as _anker_in_shopify_sdk from '@anker-in/shopify-sdk';
4
- import { CartLineInput, BuyerIdentityInput, NormalizedCart, NormalizedProduct, NormalizedProductVariant, NormalizedLineItem, UpdateCartLinesOptions, HasMetafieldsIdentifier, Media, NormalizedCollection, CollectionsConnection, NormalizedBlog, NormalizedArticle, NormalizedAttribute } from '@anker-in/shopify-sdk';
5
- import { h as UseAddToCartOptions, g as AddToCartInput, A as AddToCartLineItem, G as GtmParams, C as BuyNowTrackConfig, e as UseScriptAutoFreeGiftResult, m as PlusMemberShippingMethodConfig, n as PlusMemberSettingsMetafields, D as DeliveryPlusType, o as SelectedPlusMemberVariant } from '../types-CM5QrlnE.js';
6
- export { p as DeliveryCustomData, P as PLUS_MEMBER_TYPE, j as PlusMemberMode, l as PlusMemberShippingMethodMetafields, S as ScriptAutoFreeGiftConfig, k as ShippingMethodMode, U as UseAutoRemoveFreeGiftsOptions, a as UseAutoRemoveFreeGiftsResult, d as isAnyGift, c as isBuyGetGift, i as isFunctionGift, b as isScriptGift, u as useAutoRemoveFreeGifts, f as useScriptAutoFreeGift } from '../types-CM5QrlnE.js';
4
+ import { CartLineInput, BuyerIdentityInput, NormalizedCart, NormalizedProduct, NormalizedProductVariant, NormalizedLineItem, UpdateCartLinesOptions, HasMetafieldsIdentifier, Media, NormalizedCollection, CollectionsConnection, NormalizedBlog, NormalizedArticle, NormalizedShop, NormalizedAttribute } from '@anker-in/shopify-sdk';
5
+ import { h as UseAddToCartOptions, g as AddToCartInput, A as AddToCartLineItem, G as GtmParams, C as BuyNowTrackConfig, e as UseScriptAutoFreeGiftResult, m as PlusMemberShippingMethodConfig, n as PlusMemberSettingsMetafields, D as DeliveryPlusType, o as SelectedPlusMemberVariant } from '../types-C0UyuPrG.js';
6
+ export { p as DeliveryCustomData, P as PLUS_MEMBER_TYPE, j as PlusMemberMode, l as PlusMemberShippingMethodMetafields, S as ScriptAutoFreeGiftConfig, k as ShippingMethodMode, U as UseAutoRemoveFreeGiftsOptions, a as UseAutoRemoveFreeGiftsResult, d as isAnyGift, c as isBuyGetGift, i as isFunctionGift, b as isScriptGift, u as useAutoRemoveFreeGifts, f as useScriptAutoFreeGift } from '../types-C0UyuPrG.js';
7
7
  import * as swr from 'swr';
8
8
  import swr__default, { SWRConfiguration } from 'swr';
9
9
  import * as swr__internal from 'swr/_internal';
@@ -920,7 +920,7 @@ interface UseAllProductsOptions extends SWRConfiguration<NormalizedProduct[]> {
920
920
  */
921
921
  declare function useAllProducts(options?: UseAllProductsOptions): swr.SWRResponse<NormalizedProduct[], any, SWRConfiguration<NormalizedProduct[], any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>)> | undefined>;
922
922
 
923
- interface UseProductsByHandlesOptions extends SWRConfiguration<NormalizedProduct[]> {
923
+ interface UseProductsByHandlesOptions extends SWRConfiguration<(NormalizedProduct | undefined)[]> {
924
924
  handles?: string[];
925
925
  metafieldIdentifiers?: {
926
926
  product: HasMetafieldsIdentifier[];
@@ -956,7 +956,7 @@ interface UseProductsByHandlesOptions extends SWRConfiguration<NormalizedProduct
956
956
  * }
957
957
  * ```
958
958
  */
959
- declare function useProductsByHandles(options?: UseProductsByHandlesOptions): swr.SWRResponse<NormalizedProduct[], any, SWRConfiguration<NormalizedProduct[], any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedProduct[]>)> | undefined>;
959
+ declare function useProductsByHandles(options?: UseProductsByHandlesOptions): swr.SWRResponse<(NormalizedProduct | undefined)[], any, SWRConfiguration<(NormalizedProduct | undefined)[], any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<(NormalizedProduct | undefined)[]>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<(NormalizedProduct | undefined)[]>)> | undefined>;
960
960
 
961
961
  /**
962
962
  * useVariant Hook
@@ -1350,33 +1350,14 @@ interface UseSearchOptions extends SWRConfiguration<SearchResult | undefined> {
1350
1350
  }
1351
1351
  declare function useSearch(options?: UseSearchOptions): swr.SWRResponse<SearchResult | undefined, any, SWRConfiguration<SearchResult | undefined, any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SearchResult | undefined>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SearchResult | undefined>)> | undefined>;
1352
1352
 
1353
- interface SiteInfo {
1354
- name: string;
1355
- description?: string;
1356
- primaryDomain: {
1357
- url: string;
1358
- host: string;
1359
- };
1360
- brand?: {
1361
- logo?: {
1362
- image?: {
1363
- url: string;
1364
- };
1365
- };
1366
- colors?: {
1367
- primary?: string;
1368
- secondary?: string;
1369
- };
1370
- };
1371
- metafields?: Record<string, any>;
1372
- }
1353
+ type SiteInfo = NormalizedShop;
1373
1354
  interface UseSiteOptions extends SWRConfiguration<SiteInfo | undefined> {
1374
1355
  metafieldIdentifiers?: Array<{
1375
1356
  namespace: string;
1376
1357
  key: string;
1377
1358
  }>;
1378
1359
  }
1379
- declare function useSite(options?: UseSiteOptions): swr.SWRResponse<SiteInfo | undefined, any, SWRConfiguration<SiteInfo | undefined, any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SiteInfo | undefined>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<SiteInfo | undefined>)> | undefined>;
1360
+ declare function useSite(options?: UseSiteOptions): swr.SWRResponse<NormalizedShop | undefined, any, SWRConfiguration<NormalizedShop | undefined, any, ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedShop | undefined>) | ((arg: readonly [any, ...unknown[]]) => swr__internal.FetcherResponse<NormalizedShop | undefined>)> | undefined>;
1380
1361
 
1381
1362
  interface ShippingMethodsContext {
1382
1363
  freeShippingMethods: PlusMemberShippingMethodConfig[];
@@ -671,6 +671,177 @@ var useScriptAutoFreeGift = ({
671
671
  giftProductsResult: finalGiftProductsResult
672
672
  };
673
673
  };
674
+ function useRemoveCartLines(options) {
675
+ const { client, locale, cartCookieAdapter } = useShopify();
676
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
677
+ const removeLines = react.useCallback(
678
+ async (_key, { arg }) => {
679
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
680
+ let updatedCart = await shopifySdk.removeCartLines(client, {
681
+ cartId,
682
+ lineIds,
683
+ metafieldIdentifiers,
684
+ cookieAdapter: cartCookieAdapter
685
+ });
686
+ if (updatedCart && autoRemoveInvalidCodes) {
687
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
688
+ if (unApplicableCodes.length > 0) {
689
+ if (onCodesRemoved) {
690
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
691
+ if (handledCart) {
692
+ updatedCart = handledCart;
693
+ }
694
+ } else {
695
+ updatedCart = await shopifySdk.updateCartCodes(client, {
696
+ cartId: updatedCart.id,
697
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
698
+ metafieldIdentifiers,
699
+ cookieAdapter: cartCookieAdapter
700
+ }) || updatedCart;
701
+ }
702
+ }
703
+ }
704
+ if (updatedCart) {
705
+ mutateCart(updatedCart);
706
+ }
707
+ return updatedCart;
708
+ },
709
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
710
+ );
711
+ return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
712
+ }
713
+
714
+ // src/hooks/cart/feature/use-auto-remove-free-gifts.ts
715
+ function useAutoRemoveFreeGifts(options = {}) {
716
+ const {
717
+ removeFunctionGifts = true,
718
+ removeScriptGifts = true,
719
+ isGiftLineItem,
720
+ runOnlyOnceAfterInit = false,
721
+ initDelay = 500
722
+ } = options;
723
+ const [isRemoving, setIsRemoving] = react.useState(false);
724
+ const [isInitialized, setIsInitialized] = react.useState(!runOnlyOnceAfterInit);
725
+ const [isFinished, setIsFinished] = react.useState(false);
726
+ const { cart } = useCartContext();
727
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
728
+ const giftsToRemove = react.useMemo(() => {
729
+ if (!cart?.lineItems) {
730
+ return [];
731
+ }
732
+ return cart.lineItems.filter((item) => {
733
+ if (removeFunctionGifts) {
734
+ const functionAttr = item.customAttributes?.find(
735
+ (attr) => attr.key === "_discounts_function_env"
736
+ )?.value;
737
+ if (functionAttr) {
738
+ try {
739
+ const functionAttrObj = JSON.parse(functionAttr);
740
+ if (functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money) {
741
+ return true;
742
+ }
743
+ } catch (error) {
744
+ console.error("Failed to parse _discounts_function_env:", error);
745
+ }
746
+ }
747
+ }
748
+ if (removeScriptGifts) {
749
+ const scriptGiftAttr = item.customAttributes?.find(
750
+ (attr) => attr.key === "_giveaway_gradient_gifts"
751
+ );
752
+ if (scriptGiftAttr) {
753
+ return true;
754
+ }
755
+ }
756
+ if (isGiftLineItem && isGiftLineItem(item)) {
757
+ return true;
758
+ }
759
+ return false;
760
+ });
761
+ }, [cart, removeFunctionGifts, removeScriptGifts, isGiftLineItem]);
762
+ ahooks.useDebounceEffect(
763
+ () => {
764
+ if (!runOnlyOnceAfterInit || isInitialized || isFinished) {
765
+ return;
766
+ }
767
+ if (!cart?.lineItems?.length) {
768
+ return;
769
+ }
770
+ setIsInitialized(true);
771
+ if (giftsToRemove.length === 0) {
772
+ setIsFinished(true);
773
+ }
774
+ },
775
+ [runOnlyOnceAfterInit, isInitialized, isFinished, cart?.lineItems, giftsToRemove.length],
776
+ {
777
+ trailing: true,
778
+ wait: initDelay
779
+ }
780
+ );
781
+ react.useEffect(() => {
782
+ if (runOnlyOnceAfterInit && (!isInitialized || isFinished)) {
783
+ return;
784
+ }
785
+ if (isRemoving || giftsToRemove.length === 0) {
786
+ return;
787
+ }
788
+ const performRemoval = async () => {
789
+ setIsRemoving(true);
790
+ try {
791
+ await removeCartLines2({
792
+ lineIds: giftsToRemove.map((item) => item.id)
793
+ });
794
+ } catch (error) {
795
+ console.error("Failed to remove free gifts:", error);
796
+ } finally {
797
+ setIsRemoving(false);
798
+ if (runOnlyOnceAfterInit) {
799
+ setIsFinished(true);
800
+ }
801
+ }
802
+ };
803
+ performRemoval();
804
+ }, [
805
+ runOnlyOnceAfterInit,
806
+ isInitialized,
807
+ isFinished,
808
+ isRemoving,
809
+ giftsToRemove,
810
+ removeCartLines2
811
+ ]);
812
+ return {
813
+ isRemoving
814
+ };
815
+ }
816
+ function isFunctionGift(line) {
817
+ const functionAttr = line.customAttributes?.find(
818
+ (attr) => attr.key === "_discounts_function_env"
819
+ )?.value;
820
+ if (!functionAttr) {
821
+ return false;
822
+ }
823
+ try {
824
+ const functionAttrObj = JSON.parse(functionAttr);
825
+ return Boolean(
826
+ functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money
827
+ );
828
+ } catch {
829
+ return false;
830
+ }
831
+ }
832
+ function isScriptGift(line) {
833
+ return line.customAttributes?.some(
834
+ (attr) => attr.key === "_giveaway_gradient_gifts"
835
+ ) ?? false;
836
+ }
837
+ function isBuyGetGift(line) {
838
+ return line.customAttributes?.some(
839
+ (attr) => attr.key === "_freegift_related_handlesku"
840
+ ) ?? false;
841
+ }
842
+ function isAnyGift(line) {
843
+ return isFunctionGift(line) || isScriptGift(line) || isBuyGetGift(line);
844
+ }
674
845
  var CartContext = react.createContext(null);
675
846
  function useCartContext(options) {
676
847
  const context = react.useContext(CartContext);
@@ -994,6 +1165,26 @@ function useRemoveCartCodes(options) {
994
1165
  );
995
1166
  return useSWRMutation__default.default("remove-codes", removeCodes, options);
996
1167
  }
1168
+ function useUpdateCartLines(options) {
1169
+ const { client, locale, cartCookieAdapter } = useShopify();
1170
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1171
+ const updateLines = react.useCallback(
1172
+ async (_key, { arg }) => {
1173
+ const updatedCart = await shopifySdk.updateCartLines(client, {
1174
+ ...arg,
1175
+ metafieldIdentifiers,
1176
+ cookieAdapter: cartCookieAdapter
1177
+ });
1178
+ if (updatedCart) {
1179
+ mutateCart(updatedCart);
1180
+ }
1181
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
1182
+ return updatedCart;
1183
+ },
1184
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1185
+ );
1186
+ return useSWRMutation__default.default("update-cart-lines", updateLines, options);
1187
+ }
997
1188
  var initSameLinesAttributes = ({
998
1189
  cart,
999
1190
  line
@@ -1081,145 +1272,6 @@ var getLinesWithAttributes = ({
1081
1272
  return functionLine;
1082
1273
  });
1083
1274
  };
1084
- function useRemoveCartLines(options) {
1085
- const { client, locale, cartCookieAdapter } = useShopify();
1086
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1087
- const removeLines = react.useCallback(
1088
- async (_key, { arg }) => {
1089
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1090
- let updatedCart = await shopifySdk.removeCartLines(client, {
1091
- cartId,
1092
- lineIds,
1093
- metafieldIdentifiers,
1094
- cookieAdapter: cartCookieAdapter
1095
- });
1096
- if (updatedCart && autoRemoveInvalidCodes) {
1097
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1098
- if (unApplicableCodes.length > 0) {
1099
- if (onCodesRemoved) {
1100
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1101
- if (handledCart) {
1102
- updatedCart = handledCart;
1103
- }
1104
- } else {
1105
- updatedCart = await shopifySdk.updateCartCodes(client, {
1106
- cartId: updatedCart.id,
1107
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1108
- metafieldIdentifiers,
1109
- cookieAdapter: cartCookieAdapter
1110
- }) || updatedCart;
1111
- }
1112
- }
1113
- }
1114
- if (updatedCart) {
1115
- mutateCart(updatedCart);
1116
- }
1117
- return updatedCart;
1118
- },
1119
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1120
- );
1121
- return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1122
- }
1123
-
1124
- // src/hooks/cart/feature/use-auto-remove-free-gifts.ts
1125
- function useAutoRemoveFreeGifts(options = {}) {
1126
- const {
1127
- removeFunctionGifts = true,
1128
- removeScriptGifts = true,
1129
- isGiftLineItem
1130
- } = options;
1131
- const [isRemoving, setIsRemoving] = react.useState(false);
1132
- const { cart } = useCartContext();
1133
- const { trigger: removeCartLines2 } = useRemoveCartLines();
1134
- const giftsToRemove = react.useMemo(() => {
1135
- if (!cart?.lineItems) {
1136
- return [];
1137
- }
1138
- return cart.lineItems.filter((item) => {
1139
- if (removeFunctionGifts) {
1140
- const functionAttr = item.customAttributes?.find(
1141
- (attr) => attr.key === "_discounts_function_env"
1142
- )?.value;
1143
- if (functionAttr) {
1144
- try {
1145
- const functionAttrObj = JSON.parse(functionAttr);
1146
- if (functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money) {
1147
- return true;
1148
- }
1149
- } catch (error) {
1150
- console.error("Failed to parse _discounts_function_env:", error);
1151
- }
1152
- }
1153
- }
1154
- if (removeScriptGifts) {
1155
- const scriptGiftAttr = item.customAttributes?.find(
1156
- (attr) => attr.key === "_giveaway_gradient_gifts"
1157
- );
1158
- if (scriptGiftAttr) {
1159
- return true;
1160
- }
1161
- }
1162
- if (isGiftLineItem && isGiftLineItem(item)) {
1163
- return true;
1164
- }
1165
- return false;
1166
- });
1167
- }, [cart, removeFunctionGifts, removeScriptGifts, isGiftLineItem]);
1168
- react.useEffect(() => {
1169
- if (isRemoving || giftsToRemove.length === 0) {
1170
- return;
1171
- }
1172
- const performRemoval = async () => {
1173
- setIsRemoving(true);
1174
- try {
1175
- await removeCartLines2({
1176
- lineIds: giftsToRemove.map((item) => item.id)
1177
- });
1178
- } catch (error) {
1179
- console.error("Failed to remove free gifts:", error);
1180
- } finally {
1181
- setIsRemoving(false);
1182
- }
1183
- };
1184
- performRemoval();
1185
- }, [
1186
- isRemoving,
1187
- giftsToRemove,
1188
- removeCartLines2
1189
- ]);
1190
- return {
1191
- isRemoving
1192
- };
1193
- }
1194
- function isFunctionGift(line) {
1195
- const functionAttr = line.customAttributes?.find(
1196
- (attr) => attr.key === "_discounts_function_env"
1197
- )?.value;
1198
- if (!functionAttr) {
1199
- return false;
1200
- }
1201
- try {
1202
- const functionAttrObj = JSON.parse(functionAttr);
1203
- return Boolean(
1204
- functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money
1205
- );
1206
- } catch {
1207
- return false;
1208
- }
1209
- }
1210
- function isScriptGift(line) {
1211
- return line.customAttributes?.some(
1212
- (attr) => attr.key === "_giveaway_gradient_gifts"
1213
- ) ?? false;
1214
- }
1215
- function isBuyGetGift(line) {
1216
- return line.customAttributes?.some(
1217
- (attr) => attr.key === "_freegift_related_handlesku"
1218
- ) ?? false;
1219
- }
1220
- function isAnyGift(line) {
1221
- return isFunctionGift(line) || isScriptGift(line) || isBuyGetGift(line);
1222
- }
1223
1275
  function useCalcGiftsFromLines({
1224
1276
  lines,
1225
1277
  customer,
@@ -2294,6 +2346,7 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2294
2346
  const { trigger: applyCartCodes } = useApplyCartCodes();
2295
2347
  const { trigger: removeInvalidCodes } = useRemoveCartCodes();
2296
2348
  const { trigger: addCartLines2 } = useAddCartLines();
2349
+ const { trigger: updateCartLines3 } = useUpdateCartLines();
2297
2350
  const { trigger: createCart4 } = useCreateCart({
2298
2351
  updateCookie: true
2299
2352
  });
@@ -2346,10 +2399,36 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2346
2399
  // 初次加购时,就把所有 cart attributes 带上
2347
2400
  });
2348
2401
  } else {
2349
- resultCart = await addCartLines2({
2350
- cartId,
2351
- lines
2402
+ const linesToUpdate = [];
2403
+ const linesToAddNew = lines.filter((lineToAdd) => {
2404
+ const existingLine = cart?.lineItems?.find(
2405
+ (item) => item.variant?.id === lineToAdd.merchandiseId
2406
+ );
2407
+ if (existingLine) {
2408
+ linesToUpdate.push({
2409
+ id: existingLine.id,
2410
+ quantity: existingLine.quantity + (lineToAdd.quantity || 1),
2411
+ attributes: lineToAdd.attributes || void 0
2412
+ });
2413
+ return false;
2414
+ }
2415
+ return true;
2352
2416
  });
2417
+ if (linesToUpdate.length > 0) {
2418
+ resultCart = await updateCartLines3({
2419
+ cartId,
2420
+ lines: linesToUpdate
2421
+ });
2422
+ }
2423
+ if (linesToAddNew.length > 0) {
2424
+ resultCart = await addCartLines2({
2425
+ cartId: resultCart?.id || cartId,
2426
+ lines: linesToAddNew
2427
+ });
2428
+ }
2429
+ if (!resultCart) {
2430
+ resultCart = cart;
2431
+ }
2353
2432
  console.log("npm addCartLines resultCart", resultCart);
2354
2433
  if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
2355
2434
  const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
@@ -2410,6 +2489,7 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2410
2489
  performanceAdapter,
2411
2490
  createCart4,
2412
2491
  addCartLines2,
2492
+ updateCartLines3,
2413
2493
  applyCartCodes,
2414
2494
  removeInvalidCodes,
2415
2495
  addCustomAttributes,
@@ -2419,26 +2499,6 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2419
2499
  );
2420
2500
  return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
2421
2501
  }
2422
- function useUpdateCartLines(options) {
2423
- const { client, locale, cartCookieAdapter } = useShopify();
2424
- const { mutateCart, metafieldIdentifiers } = useCartContext();
2425
- const updateLines = react.useCallback(
2426
- async (_key, { arg }) => {
2427
- const updatedCart = await shopifySdk.updateCartLines(client, {
2428
- ...arg,
2429
- metafieldIdentifiers,
2430
- cookieAdapter: cartCookieAdapter
2431
- });
2432
- if (updatedCart) {
2433
- mutateCart(updatedCart);
2434
- }
2435
- console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
2436
- return updatedCart;
2437
- },
2438
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2439
- );
2440
- return useSWRMutation__default.default("update-cart-lines", updateLines, options);
2441
- }
2442
2502
  function useUpdateCartAttributes({
2443
2503
  mutate,
2444
2504
  metafieldIdentifiers,
@@ -3037,8 +3097,7 @@ async function performSearch(client, locale, searchQuery, first = 20, types = ["
3037
3097
  const query = (
3038
3098
  /* GraphQL */
3039
3099
  `
3040
- query search($query: String!, $first: Int!, $types: [SearchType!])
3041
- @inContext(language: $language) {
3100
+ query search($query: String!, $first: Int!, $types: [SearchType!]) {
3042
3101
  search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
3043
3102
  totalCount
3044
3103
  edges {
@@ -3127,76 +3186,15 @@ function useSearch(options = {}) {
3127
3186
  swrOptions
3128
3187
  );
3129
3188
  }
3130
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
3131
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
3132
- const query = (
3133
- /* GraphQL */
3134
- `
3135
- query getSiteInfo(
3136
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
3137
- ) @inContext(language: $language) {
3138
- shop {
3139
- name
3140
- description
3141
- primaryDomain {
3142
- url
3143
- host
3144
- }
3145
- brand {
3146
- logo {
3147
- image {
3148
- url
3149
- }
3150
- }
3151
- colors {
3152
- primary {
3153
- background
3154
- }
3155
- secondary {
3156
- background
3157
- }
3158
- }
3159
- }
3160
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
3161
- }
3162
- }
3163
- `
3164
- );
3165
- const variables = {};
3166
- if (hasMetafields) {
3167
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
3168
- }
3169
- const data = await client.query(query, variables);
3170
- if (!data || !data.shop) {
3171
- return void 0;
3172
- }
3173
- const shop = data.shop;
3174
- const metafields = shop.metafields?.reduce((acc, mf) => {
3175
- if (mf && mf.key) {
3176
- acc[mf.key] = mf.value;
3177
- }
3178
- return acc;
3179
- }, {});
3180
- return {
3181
- name: shop.name,
3182
- description: shop.description,
3183
- primaryDomain: shop.primaryDomain,
3184
- brand: shop.brand ? {
3185
- logo: shop.brand.logo,
3186
- colors: shop.brand.colors ? {
3187
- primary: shop.brand.colors.primary?.background,
3188
- secondary: shop.brand.colors.secondary?.background
3189
- } : void 0
3190
- } : void 0,
3191
- metafields
3192
- };
3193
- }
3194
3189
  function useSite(options = {}) {
3195
3190
  const { client, locale } = useShopify();
3196
3191
  const { metafieldIdentifiers, ...swrOptions } = options;
3197
3192
  return useSWR__default.default(
3198
3193
  ["site", locale, metafieldIdentifiers],
3199
- () => getSiteInfo(client, locale, metafieldIdentifiers),
3194
+ () => shopifySdk.getShop(client, {
3195
+ locale,
3196
+ metafieldIdentifiers
3197
+ }),
3200
3198
  swrOptions
3201
3199
  );
3202
3200
  }