@anker-in/shopify-react 1.1.2 → 1.2.0-beta.1

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,5 +1,5 @@
1
1
  import { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
2
- import { createShopifyClient, getProductsByHandles, createCart, updateCartCodes, addCartLines, getLocalStorage, updateCartLines, removeCartLines, updateCartAttributes, updateBuyerIdentity, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getCart, setLocalStorage } from '@anker-in/shopify-sdk';
2
+ import { createShopifyClient, getProductsByHandles, createCart, updateCartCodes, addCartLines, removeCartLines, getLocalStorage, updateCartLines, updateCartAttributes, updateBuyerIdentity, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, getCart, setLocalStorage } from '@anker-in/shopify-sdk';
3
3
  export * from '@anker-in/shopify-sdk';
4
4
  import Cookies5 from 'js-cookie';
5
5
  import { jsx } from 'react/jsx-runtime';
@@ -877,15 +877,23 @@ var trackAddToCartGA = ({
877
877
  currency: currencyCode,
878
878
  value: totalPrice,
879
879
  position: gtmParams?.position || "",
880
- items: lineItems.map(({ variant: variant2, quantity }) => ({
881
- item_id: variant2?.sku,
882
- item_name: variant2?.product?.title || variant2?.product?.title,
883
- item_brand: gtmParams?.brand || "",
884
- item_category: variant2?.product?.productType || "",
885
- item_variant: variant2?.title || variant2?.title,
886
- price: variant2?.compareAtPrice?.amount ?? variant2?.price?.amount,
887
- quantity: quantity || 1
888
- })),
880
+ items: lineItems.map((item) => {
881
+ const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
882
+ const itemCategoryId = item.gtmParams?.item_category_id;
883
+ const itemVariantId = item.variant?.id ? atobID(item.variant.id) : void 0;
884
+ return {
885
+ item_id: item.variant?.sku,
886
+ item_name: item.variant?.product?.title || item.variant?.product?.title,
887
+ item_brand: gtmParams?.brand || "",
888
+ item_category: item.variant?.product?.productType || "",
889
+ item_variant: item.variant?.title || item.variant?.title,
890
+ price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
891
+ quantity: item.quantity || 1,
892
+ ...imageUrl && { image_url: imageUrl },
893
+ ...itemCategoryId && { item_category_id: itemCategoryId },
894
+ ...itemVariantId && { item_variant_id: itemVariantId }
895
+ };
896
+ }),
889
897
  ...gtmParams?.ga4Params
890
898
  }
891
899
  });
@@ -912,15 +920,23 @@ var trackBeginCheckoutGA = ({
912
920
  position: gtmParams?.position,
913
921
  currency: currencyCode,
914
922
  value: totalPrice,
915
- items: lineItems.map((item) => ({
916
- item_id: item.variant?.sku,
917
- item_name: item.variant?.product?.title,
918
- item_brand: gtmParams?.brand || "",
919
- item_category: item.variant?.product?.productType,
920
- item_variant: item.variant?.title,
921
- price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
922
- quantity: item.quantity || 1
923
- })),
923
+ items: lineItems.map((item) => {
924
+ const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
925
+ const itemCategoryId = item.gtmParams?.item_category_id;
926
+ const itemVariantId = item.variant?.id ? atobID(item.variant.id) : void 0;
927
+ return {
928
+ item_id: item.variant?.sku,
929
+ item_name: item.variant?.product?.title,
930
+ item_brand: gtmParams?.brand || "",
931
+ item_category: item.variant?.product?.productType,
932
+ item_variant: item.variant?.title,
933
+ price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
934
+ quantity: item.quantity || 1,
935
+ ...imageUrl && { image_url: imageUrl },
936
+ ...itemCategoryId !== void 0 && { item_category_id: itemCategoryId },
937
+ ...itemVariantId && { item_variant_id: itemVariantId }
938
+ };
939
+ }),
924
940
  ...gtmParams?.ga4Params
925
941
  }
926
942
  });
@@ -948,19 +964,111 @@ var trackBuyNowGA = ({
948
964
  position: gtmParams?.position,
949
965
  currency: currencyCode,
950
966
  value: totalPrice,
951
- items: lineItems.map((item) => ({
952
- item_id: item.variant?.sku,
953
- item_name: item.variant?.product?.title || item.variant?.title,
954
- item_brand: gtmParams?.brand || "",
955
- item_category: item.variant?.product?.productType || "",
956
- item_variant: item.variant?.title,
957
- price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
958
- quantity: item.quantity || 1
959
- })),
967
+ items: lineItems.map((item) => {
968
+ const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
969
+ const itemCategoryId = item.gtmParams?.item_category_id;
970
+ const itemVariantId = item.variant?.id ? atobID(item.variant.id) : void 0;
971
+ return {
972
+ item_id: item.variant?.sku,
973
+ item_name: item.variant?.product?.title || item.variant?.title,
974
+ item_brand: gtmParams?.brand || "",
975
+ item_category: item.variant?.product?.productType || "",
976
+ item_variant: item.variant?.title,
977
+ price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
978
+ quantity: item.quantity || 1,
979
+ ...imageUrl && { image_url: imageUrl },
980
+ ...itemCategoryId !== void 0 && { item_category_id: itemCategoryId },
981
+ ...itemVariantId && { item_variant_id: itemVariantId }
982
+ };
983
+ }),
960
984
  ...gtmParams?.ga4Params
961
985
  }
962
986
  });
963
987
  };
988
+ function waitForGtagReady(timeout = 1e4) {
989
+ return new Promise((resolve, reject) => {
990
+ const start = Date.now();
991
+ function check() {
992
+ if (typeof window !== "undefined" && typeof window.gtag !== "undefined") {
993
+ resolve();
994
+ } else if (Date.now() - start > timeout) {
995
+ reject(new Error("GA4 gtag not loaded"));
996
+ } else {
997
+ setTimeout(check, 50);
998
+ }
999
+ }
1000
+ check();
1001
+ });
1002
+ }
1003
+ var getGA4ClientId = async (measurementId = "G-R0BRMRK4CY") => {
1004
+ try {
1005
+ await waitForGtagReady();
1006
+ return new Promise((resolve, reject) => {
1007
+ if (!window.gtag) {
1008
+ reject(new Error("gtag is not defined"));
1009
+ return;
1010
+ }
1011
+ window.gtag("get", measurementId, "client_id", (clientId) => {
1012
+ if (clientId) {
1013
+ resolve(clientId);
1014
+ } else {
1015
+ reject(new Error("Failed to get client_id"));
1016
+ }
1017
+ });
1018
+ });
1019
+ } catch (error) {
1020
+ console.error("Failed to get GA4 client_id:", error);
1021
+ return "";
1022
+ }
1023
+ };
1024
+ var getGA4SessionId = async (measurementId = "G-R0BRMRK4CY") => {
1025
+ try {
1026
+ await waitForGtagReady();
1027
+ return new Promise((resolve) => {
1028
+ if (!window.gtag) {
1029
+ resolve("");
1030
+ return;
1031
+ }
1032
+ window.gtag("get", measurementId, "session_id", (sessionId) => {
1033
+ resolve(sessionId || "");
1034
+ });
1035
+ });
1036
+ } catch (error) {
1037
+ console.error("Failed to get GA4 session_id:", error);
1038
+ return "";
1039
+ }
1040
+ };
1041
+ var getGA4Data = async (measurementId = "G-R0BRMRK4CY") => {
1042
+ try {
1043
+ await waitForGtagReady();
1044
+ const timeoutPromise = new Promise((resolve) => {
1045
+ setTimeout(() => {
1046
+ resolve({ clientId: "", sessionId: "" });
1047
+ }, 300);
1048
+ });
1049
+ const dataPromise = new Promise((resolve) => {
1050
+ if (!window.gtag) {
1051
+ resolve({ clientId: "", sessionId: "" });
1052
+ return;
1053
+ }
1054
+ window.gtag("get", measurementId, "client_id", (clientId) => {
1055
+ window.gtag("get", measurementId, "session_id", (sessionId) => {
1056
+ resolve({
1057
+ clientId: clientId || "",
1058
+ sessionId: sessionId || ""
1059
+ });
1060
+ });
1061
+ });
1062
+ });
1063
+ return Promise.race([dataPromise, timeoutPromise]);
1064
+ } catch (error) {
1065
+ console.error("Failed to get GA4 data:", error);
1066
+ return {
1067
+ clientId: "",
1068
+ sessionId: ""
1069
+ };
1070
+ }
1071
+ };
964
1072
 
965
1073
  // src/tracking/fbq.ts
966
1074
  var trackAddToCartFBQ = ({ lineItems = [] }) => {
@@ -1143,16 +1251,155 @@ var getLinesWithAttributes = ({
1143
1251
  return functionLine;
1144
1252
  });
1145
1253
  };
1254
+ function useRemoveCartLines(options) {
1255
+ const { client, locale, cartCookieAdapter } = useShopify();
1256
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1257
+ const removeLines = useCallback(
1258
+ async (_key, { arg }) => {
1259
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1260
+ let updatedCart = await removeCartLines(client, {
1261
+ cartId,
1262
+ lineIds,
1263
+ metafieldIdentifiers,
1264
+ cookieAdapter: cartCookieAdapter
1265
+ });
1266
+ if (updatedCart && autoRemoveInvalidCodes) {
1267
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1268
+ if (unApplicableCodes.length > 0) {
1269
+ if (onCodesRemoved) {
1270
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1271
+ if (handledCart) {
1272
+ updatedCart = handledCart;
1273
+ }
1274
+ } else {
1275
+ updatedCart = await updateCartCodes(client, {
1276
+ cartId: updatedCart.id,
1277
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1278
+ metafieldIdentifiers,
1279
+ cookieAdapter: cartCookieAdapter
1280
+ }) || updatedCart;
1281
+ }
1282
+ }
1283
+ }
1284
+ if (updatedCart) {
1285
+ mutateCart(updatedCart);
1286
+ }
1287
+ return updatedCart;
1288
+ },
1289
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1290
+ );
1291
+ return useSWRMutation("remove-cart-lines", removeLines, options);
1292
+ }
1293
+
1294
+ // src/hooks/cart/feature/use-auto-remove-free-gifts.ts
1295
+ function useAutoRemoveFreeGifts(options = {}) {
1296
+ const {
1297
+ removeFunctionGifts = true,
1298
+ removeScriptGifts = true,
1299
+ isGiftLineItem
1300
+ } = options;
1301
+ const [isRemoving, setIsRemoving] = useState(false);
1302
+ const { cart } = useCartContext();
1303
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1304
+ const giftsToRemove = useMemo(() => {
1305
+ if (!cart?.lineItems) {
1306
+ return [];
1307
+ }
1308
+ return cart.lineItems.filter((item) => {
1309
+ if (removeFunctionGifts) {
1310
+ const functionAttr = item.customAttributes?.find(
1311
+ (attr) => attr.key === "_discounts_function_env"
1312
+ )?.value;
1313
+ if (functionAttr) {
1314
+ try {
1315
+ const functionAttrObj = JSON.parse(functionAttr);
1316
+ if (functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money) {
1317
+ return true;
1318
+ }
1319
+ } catch (error) {
1320
+ console.error("Failed to parse _discounts_function_env:", error);
1321
+ }
1322
+ }
1323
+ }
1324
+ if (removeScriptGifts) {
1325
+ const scriptGiftAttr = item.customAttributes?.find(
1326
+ (attr) => attr.key === "_giveaway_gradient_gifts"
1327
+ );
1328
+ if (scriptGiftAttr) {
1329
+ return true;
1330
+ }
1331
+ }
1332
+ if (isGiftLineItem && isGiftLineItem(item)) {
1333
+ return true;
1334
+ }
1335
+ return false;
1336
+ });
1337
+ }, [cart, removeFunctionGifts, removeScriptGifts, isGiftLineItem]);
1338
+ useEffect(() => {
1339
+ if (isRemoving || giftsToRemove.length === 0) {
1340
+ return;
1341
+ }
1342
+ const performRemoval = async () => {
1343
+ setIsRemoving(true);
1344
+ try {
1345
+ await removeCartLines2({
1346
+ lineIds: giftsToRemove.map((item) => item.id)
1347
+ });
1348
+ } catch (error) {
1349
+ console.error("Failed to remove free gifts:", error);
1350
+ } finally {
1351
+ setIsRemoving(false);
1352
+ }
1353
+ };
1354
+ performRemoval();
1355
+ }, [
1356
+ isRemoving,
1357
+ giftsToRemove,
1358
+ removeCartLines2
1359
+ ]);
1360
+ return {
1361
+ isRemoving
1362
+ };
1363
+ }
1364
+ function isFunctionGift(line) {
1365
+ const functionAttr = line.customAttributes?.find(
1366
+ (attr) => attr.key === "_discounts_function_env"
1367
+ )?.value;
1368
+ if (!functionAttr) {
1369
+ return false;
1370
+ }
1371
+ try {
1372
+ const functionAttrObj = JSON.parse(functionAttr);
1373
+ return Boolean(
1374
+ functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money
1375
+ );
1376
+ } catch {
1377
+ return false;
1378
+ }
1379
+ }
1380
+ function isScriptGift(line) {
1381
+ return line.customAttributes?.some(
1382
+ (attr) => attr.key === "_giveaway_gradient_gifts"
1383
+ ) ?? false;
1384
+ }
1385
+ function isBuyGetGift(line) {
1386
+ return line.customAttributes?.some(
1387
+ (attr) => attr.key === "_freegift_related_handlesku"
1388
+ ) ?? false;
1389
+ }
1390
+ function isAnyGift(line) {
1391
+ return isFunctionGift(line) || isScriptGift(line) || isBuyGetGift(line);
1392
+ }
1146
1393
  function useCalcGiftsFromLines({
1147
1394
  lines,
1148
1395
  customer,
1149
1396
  scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
1150
1397
  }) {
1151
1398
  const { locale } = useShopify();
1152
- const { cart, autoFreeGiftConfig, gradientGiftsConfig } = useCartContext();
1153
- const functionGift = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer, lines);
1399
+ const { cart, functionAutoFreeGiftConfig, scriptAutoFreeGiftConfig } = useCartContext();
1400
+ const functionGift = useCalcAutoFreeGift(cart, functionAutoFreeGiftConfig || [], customer, lines);
1154
1401
  const scriptGift = useScriptAutoFreeGift({
1155
- campaign: gradientGiftsConfig || null,
1402
+ campaign: scriptAutoFreeGiftConfig,
1156
1403
  _giveaway: scriptGiveawayKey,
1157
1404
  cart,
1158
1405
  locale,
@@ -1187,7 +1434,9 @@ function useCalcGiftsFromLines({
1187
1434
  const variants = product?.variants;
1188
1435
  const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1189
1436
  if (!variant) {
1190
- console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1437
+ console.warn(
1438
+ `Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`
1439
+ );
1191
1440
  return null;
1192
1441
  }
1193
1442
  return {
@@ -1330,6 +1579,19 @@ var getReferralAttributes = () => {
1330
1579
  }
1331
1580
  return [];
1332
1581
  };
1582
+ var getOperatingSystem = () => {
1583
+ if (typeof window === "undefined" || typeof navigator === "undefined") {
1584
+ return "Unknown";
1585
+ }
1586
+ const userAgent = navigator.userAgent || navigator.vendor || window.opera;
1587
+ if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
1588
+ return "IOS";
1589
+ }
1590
+ if (/android/i.test(userAgent)) {
1591
+ return "Android";
1592
+ }
1593
+ return "Unknown";
1594
+ };
1333
1595
  var getUserType = (customer) => {
1334
1596
  let userInfo = Cookies5.get("userInfo");
1335
1597
  if (userInfo) {
@@ -1351,12 +1613,42 @@ var getUserType = (customer) => {
1351
1613
  }
1352
1614
  return "new_user_login";
1353
1615
  };
1354
- function getCartAttributes({
1616
+ function getGA4Attributes(ga4Data) {
1617
+ if (!ga4Data?.clientId && !ga4Data?.sessionId) {
1618
+ return [];
1619
+ }
1620
+ const attributes = [];
1621
+ if (ga4Data.clientId) {
1622
+ attributes.push({
1623
+ key: "_ga4_client_id",
1624
+ value: ga4Data.clientId
1625
+ });
1626
+ }
1627
+ if (ga4Data.sessionId) {
1628
+ attributes.push({
1629
+ key: "_ga4_session_id",
1630
+ value: ga4Data.sessionId
1631
+ });
1632
+ }
1633
+ return attributes;
1634
+ }
1635
+ async function getGA4AttributesAsync() {
1636
+ try {
1637
+ const ga4Data = await getGA4Data();
1638
+ return getGA4Attributes(ga4Data);
1639
+ } catch (error) {
1640
+ console.error("Failed to get GA4 attributes:", error);
1641
+ return [];
1642
+ }
1643
+ }
1644
+ function getCartBasicAttributes({
1355
1645
  profile,
1356
1646
  customer,
1357
1647
  cart,
1358
1648
  memberType,
1359
- currentUrl = ""
1649
+ currentUrl = "",
1650
+ appContext,
1651
+ buyPath
1360
1652
  }) {
1361
1653
  const userType = getUserType(customer);
1362
1654
  const memberAttributes = [
@@ -1383,12 +1675,10 @@ function getCartAttributes({
1383
1675
  value: "1"
1384
1676
  });
1385
1677
  }
1386
- const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1387
1678
  const functionAttributes = [
1388
1679
  {
1389
1680
  key: CUSTOMER_ATTRIBUTE_KEY,
1390
1681
  value: JSON.stringify({
1391
- discount_code: discountCodes,
1392
1682
  user_tags: customer?.tags || []
1393
1683
  })
1394
1684
  }
@@ -1396,26 +1686,38 @@ function getCartAttributes({
1396
1686
  const presellAttributes = [
1397
1687
  {
1398
1688
  key: "_presale",
1399
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1689
+ value: cart?.lineItems?.some((item) => item?.variant?.metafields?.presell === "presell")
1400
1690
  }
1401
1691
  ];
1402
1692
  const weightAttributes = [
1403
1693
  {
1404
1694
  key: "_weight",
1405
- value: cart?.lineItems.reduce((acc, item) => {
1695
+ value: cart?.lineItems?.reduce((acc, item) => {
1406
1696
  const itemWeight = new Decimal2(item.variant.weight ?? 0).times(item.quantity);
1407
1697
  return new Decimal2(acc).plus(itemWeight).toNumber();
1408
1698
  }, 0).toString()
1409
- },
1410
- {
1411
- key: "_app_source_name",
1412
- value: "dtc"
1413
1699
  }
1414
1700
  ];
1415
1701
  const trackingAttributes = [
1416
1702
  {
1417
1703
  key: "utm_params",
1418
1704
  value: currentUrl
1705
+ },
1706
+ {
1707
+ key: "_app_source_name",
1708
+ value: appContext?.isInApp && appContext?.appName ? appContext.appName : "dtc"
1709
+ },
1710
+ {
1711
+ key: "_operating_system",
1712
+ value: getOperatingSystem()
1713
+ },
1714
+ {
1715
+ key: "_cart_id",
1716
+ value: cart?.id
1717
+ },
1718
+ {
1719
+ key: "_buy_path",
1720
+ value: buyPath
1419
1721
  }
1420
1722
  ];
1421
1723
  const commonAttributes = [
@@ -1435,21 +1737,41 @@ var useCartAttributes = ({
1435
1737
  profile,
1436
1738
  customer,
1437
1739
  cart,
1438
- memberType
1740
+ memberType,
1741
+ appContext,
1742
+ buyPath
1439
1743
  }) => {
1440
1744
  const [currentUrl, setCurrentUrl] = useState("");
1745
+ const [ga4Data, setGa4Data] = useState(null);
1441
1746
  useEffect(() => {
1442
1747
  setCurrentUrl(window.location.href);
1443
1748
  }, []);
1749
+ useEffect(() => {
1750
+ let isMounted = true;
1751
+ getGA4Data().then((data) => {
1752
+ if (isMounted) {
1753
+ setGa4Data(data);
1754
+ }
1755
+ }).catch((error) => {
1756
+ console.error("Failed to get GA4 data in useCartAttributes:", error);
1757
+ });
1758
+ return () => {
1759
+ isMounted = false;
1760
+ };
1761
+ }, []);
1444
1762
  const attributes = useMemo(() => {
1445
- return getCartAttributes({
1763
+ const basicAttributes = getCartBasicAttributes({
1446
1764
  profile,
1447
1765
  customer,
1448
1766
  cart,
1449
1767
  memberType,
1450
- currentUrl
1768
+ currentUrl,
1769
+ appContext,
1770
+ buyPath
1451
1771
  });
1452
- }, [profile, customer, cart, memberType, currentUrl]);
1772
+ const ga4Attributes = getGA4Attributes(ga4Data);
1773
+ return [...basicAttributes, ...ga4Attributes];
1774
+ }, [profile, customer, cart, memberType, currentUrl, appContext, buyPath, ga4Data]);
1453
1775
  return useMemo(
1454
1776
  () => ({
1455
1777
  attributes
@@ -1512,12 +1834,9 @@ var useUpdateLineCodeAmountAttributes = ({
1512
1834
  const codeDiscount = line.discountAllocations?.find(
1513
1835
  (allocation) => mainProductDiscountCodes?.includes(allocation.code)
1514
1836
  );
1515
- const hasFunctionEnvAttribute = line.customAttributes?.find(
1516
- (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY
1517
- );
1518
1837
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1519
1838
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1520
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1839
+ if (!hasSameFunctionEnvAttribute && !functionEnvValue.is_gift) {
1521
1840
  attrNeedUpdate.push({
1522
1841
  key: CUSTOMER_ATTRIBUTE_KEY,
1523
1842
  value: JSON.stringify({
@@ -1938,47 +2257,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
1938
2257
  return checkoutCustomAttributes;
1939
2258
  }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1940
2259
  };
1941
- function useRemoveCartLines(options) {
1942
- const { client, locale, cartCookieAdapter } = useShopify();
1943
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1944
- const removeLines = useCallback(
1945
- async (_key, { arg }) => {
1946
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1947
- let updatedCart = await removeCartLines(client, {
1948
- cartId,
1949
- lineIds,
1950
- metafieldIdentifiers,
1951
- cookieAdapter: cartCookieAdapter
1952
- });
1953
- if (updatedCart && autoRemoveInvalidCodes) {
1954
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1955
- if (unApplicableCodes.length > 0) {
1956
- if (onCodesRemoved) {
1957
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1958
- if (handledCart) {
1959
- updatedCart = handledCart;
1960
- }
1961
- } else {
1962
- updatedCart = await updateCartCodes(client, {
1963
- cartId: updatedCart.id,
1964
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1965
- metafieldIdentifiers,
1966
- cookieAdapter: cartCookieAdapter
1967
- }) || updatedCart;
1968
- }
1969
- }
1970
- }
1971
- if (updatedCart) {
1972
- mutateCart(updatedCart);
1973
- }
1974
- return updatedCart;
1975
- },
1976
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1977
- );
1978
- return useSWRMutation("remove-cart-lines", removeLines, options);
1979
- }
1980
-
1981
- // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1982
2260
  function useAutoRemovePlusMemberInCart({
1983
2261
  cart,
1984
2262
  profile,
@@ -2193,7 +2471,8 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2193
2471
  profile,
2194
2472
  customer,
2195
2473
  cart,
2196
- memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2474
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0),
2475
+ buyPath: "hasCart"
2197
2476
  });
2198
2477
  const addToCart = useCallback(
2199
2478
  async (_key, { arg }) => {
@@ -2366,7 +2645,7 @@ function useUpdateBuyerIdentity({
2366
2645
  }
2367
2646
  function useBuyNow({ withTrack = true } = {}, swrOptions) {
2368
2647
  const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2369
- const { profile, customer, memberSetting } = useCartContext();
2648
+ const { profile, customer, memberSetting, appContext } = useCartContext();
2370
2649
  const isLoggedIn = userAdapter?.isLoggedIn || false;
2371
2650
  const buyNow = useCallback(
2372
2651
  async (_key, { arg }) => {
@@ -2388,12 +2667,6 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2388
2667
  lines: lineItems
2389
2668
  });
2390
2669
  const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2391
- const cartAttributes = getCartAttributes({
2392
- profile,
2393
- customer,
2394
- memberType,
2395
- currentUrl: window.location.href
2396
- });
2397
2670
  const linesWithFunctionAttributes = getLinesWithAttributes({
2398
2671
  lineItems
2399
2672
  });
@@ -2406,13 +2679,23 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2406
2679
  if (lines.length === 0) {
2407
2680
  return;
2408
2681
  }
2682
+ const basicCartAttributes = getCartBasicAttributes({
2683
+ profile,
2684
+ customer,
2685
+ memberType,
2686
+ cart: { lineItems },
2687
+ currentUrl: window.location.href,
2688
+ appContext,
2689
+ buyPath: "buyNow"
2690
+ });
2691
+ const ga4Attributes = await getGA4AttributesAsync();
2409
2692
  const resultCart = await createCart(client, {
2410
2693
  lines,
2411
2694
  metafieldIdentifiers,
2412
2695
  cookieAdapter: cartCookieAdapter,
2413
2696
  buyerIdentity,
2414
2697
  discountCodes,
2415
- customAttributes: [...cartAttributes, ...customAttributes || []]
2698
+ customAttributes: [...basicCartAttributes, ...ga4Attributes, ...customAttributes || []]
2416
2699
  });
2417
2700
  if (!resultCart) {
2418
2701
  throw new Error("Failed to create cart for buy now");
@@ -2437,7 +2720,17 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2437
2720
  }
2438
2721
  return resultCart;
2439
2722
  },
2440
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
2723
+ [
2724
+ client,
2725
+ locale,
2726
+ isLoggedIn,
2727
+ cartCookieAdapter,
2728
+ withTrack,
2729
+ customer,
2730
+ profile,
2731
+ memberSetting,
2732
+ appContext
2733
+ ]
2441
2734
  );
2442
2735
  return useSWRMutation("buy-now", buyNow, swrOptions);
2443
2736
  }
@@ -3233,13 +3526,14 @@ var CartContext = createContext(null);
3233
3526
  function CartProvider({
3234
3527
  children,
3235
3528
  // swrOptions,
3236
- autoFreeGiftConfig,
3237
- gradientGiftsConfig,
3529
+ functionAutoFreeGiftConfig,
3530
+ scriptAutoFreeGiftConfig,
3238
3531
  profile,
3239
3532
  customer,
3240
3533
  locale,
3241
3534
  metafieldIdentifiers,
3242
- memberSetting
3535
+ memberSetting,
3536
+ appContext
3243
3537
  }) {
3244
3538
  const { client, cartCookieAdapter } = useShopify();
3245
3539
  const [customAttributes, setCustomAttributes] = useState([]);
@@ -3284,7 +3578,8 @@ function CartProvider({
3284
3578
  profile,
3285
3579
  customer,
3286
3580
  cart,
3287
- memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
3581
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0),
3582
+ appContext
3288
3583
  });
3289
3584
  useRequest(
3290
3585
  () => {
@@ -3338,9 +3633,13 @@ function CartProvider({
3338
3633
  },
3339
3634
  [setCustomAttributes]
3340
3635
  );
3341
- const functionAutoFreeGiftResult = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer);
3636
+ const functionAutoFreeGiftResult = useCalcAutoFreeGift(
3637
+ cart,
3638
+ functionAutoFreeGiftConfig || [],
3639
+ customer
3640
+ );
3342
3641
  const scriptAutoFreeGiftResult = useScriptAutoFreeGift({
3343
- campaign: gradientGiftsConfig || null,
3642
+ campaign: scriptAutoFreeGiftConfig,
3344
3643
  _giveaway: CUSTOMER_SCRIPT_GIFT_KEY,
3345
3644
  cart,
3346
3645
  profile
@@ -3348,10 +3647,10 @@ function CartProvider({
3348
3647
  const formattedScriptGifts = useMemo(() => {
3349
3648
  return formatScriptAutoFreeGift({
3350
3649
  scriptAutoFreeGiftResult,
3351
- gradient_gifts: gradientGiftsConfig,
3650
+ gradient_gifts: scriptAutoFreeGiftConfig,
3352
3651
  locale
3353
3652
  });
3354
- }, [scriptAutoFreeGiftResult, gradientGiftsConfig, locale]);
3653
+ }, [scriptAutoFreeGiftResult, scriptAutoFreeGiftConfig, locale]);
3355
3654
  const formattedFunctionGifts = useMemo(() => {
3356
3655
  return formatFunctionAutoFreeGift({
3357
3656
  qualifyingGift: functionAutoFreeGiftResult?.qualifyingGift || null,
@@ -3399,6 +3698,12 @@ function CartProvider({
3399
3698
  const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
3400
3699
  return cartLinesCount + giftLinesCount;
3401
3700
  }, [cart?.lineItems, giftNeedAddToCartLines]);
3701
+ const autoRemoveFreeGiftsOptions = useMemo(() => {
3702
+ return {
3703
+ removeFunctionGifts: !!functionAutoFreeGiftConfig,
3704
+ removeScriptGifts: !!scriptAutoFreeGiftConfig
3705
+ };
3706
+ }, [functionAutoFreeGiftConfig, scriptAutoFreeGiftConfig]);
3402
3707
  const value = useMemo(
3403
3708
  () => ({
3404
3709
  totalQuantity,
@@ -3413,8 +3718,8 @@ function CartProvider({
3413
3718
  customer,
3414
3719
  isCodeChanging,
3415
3720
  setIsCodeChanging,
3416
- autoFreeGiftConfig,
3417
- gradientGiftsConfig,
3721
+ functionAutoFreeGiftConfig,
3722
+ scriptAutoFreeGiftConfig,
3418
3723
  setLoadingState,
3419
3724
  loadingState,
3420
3725
  // function满赠
@@ -3427,7 +3732,9 @@ function CartProvider({
3427
3732
  setScriptAutoFreeGift,
3428
3733
  giftNeedAddToCartLines,
3429
3734
  metafieldIdentifiers,
3430
- memberSetting
3735
+ memberSetting,
3736
+ appContext,
3737
+ autoRemoveFreeGiftsOptions
3431
3738
  }),
3432
3739
  [
3433
3740
  cart,
@@ -3439,8 +3746,8 @@ function CartProvider({
3439
3746
  removeCustomAttributes,
3440
3747
  locale,
3441
3748
  isCodeChanging,
3442
- autoFreeGiftConfig,
3443
- gradientGiftsConfig,
3749
+ functionAutoFreeGiftConfig,
3750
+ scriptAutoFreeGiftConfig,
3444
3751
  loadingState,
3445
3752
  // function满赠
3446
3753
  functionAutoFreeGift,
@@ -3454,7 +3761,9 @@ function CartProvider({
3454
3761
  metafieldIdentifiers,
3455
3762
  customer,
3456
3763
  profile,
3457
- memberSetting
3764
+ memberSetting,
3765
+ appContext,
3766
+ autoRemoveFreeGiftsOptions
3458
3767
  ]
3459
3768
  );
3460
3769
  return /* @__PURE__ */ jsx(CartContext.Provider, { value, children });
@@ -3467,6 +3776,6 @@ function useCartContext(options) {
3467
3776
  return context;
3468
3777
  }
3469
3778
 
3470
- export { BrowserPerformanceAdapter, BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, CartProvider, DeliveryPlusType, MAIN_PRODUCT_CODE, MEMBER_PRICE_ATTRIBUTE_KEY, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, ShopifyContext, ShopifyProvider, SpendMoneyType, browserCartCookieAdapter, browserCookieAdapter, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, gaTrack, getCachedGeoLocation, getCartAttributes, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, getUserType, hasPlusMemberInCart, hasPlusMemberInLines, normalizeAddToCartLines, preCheck, safeParse, trackAddToCartFBQ, trackAddToCartGA, trackBeginCheckoutGA, trackBuyNowFBQ, trackBuyNowGA, useAddCartLines, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useAvailableDeliveryCoupon, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartContext, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useHasPlusMemberInLines, useIntersection, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberNeedAddToCart, usePlusMemberVariants, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethods, useShopify, useSite, useUpdateBuyerIdentity, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3779
+ export { BrowserPerformanceAdapter, BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, CartProvider, DeliveryPlusType, MAIN_PRODUCT_CODE, MEMBER_PRICE_ATTRIBUTE_KEY, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, ShopifyContext, ShopifyProvider, SpendMoneyType, browserCartCookieAdapter, browserCookieAdapter, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, gaTrack, getCachedGeoLocation, getCartBasicAttributes, getDiscountEnvAttributeValue, getGA4Attributes, getGA4AttributesAsync, getGA4ClientId, getGA4Data, getGA4SessionId, getMatchedMainProductSubTotal, getOperatingSystem, getQuery, getReferralAttributes, getUserType, hasPlusMemberInCart, hasPlusMemberInLines, isAnyGift, isBuyGetGift, isFunctionGift, isScriptGift, normalizeAddToCartLines, preCheck, safeParse, trackAddToCartFBQ, trackAddToCartGA, trackBeginCheckoutGA, trackBuyNowFBQ, trackBuyNowGA, useAddCartLines, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemoveFreeGifts, useAutoRemovePlusMemberInCart, useAvailableDeliveryCoupon, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartContext, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useHasPlusMemberInLines, useIntersection, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberNeedAddToCart, usePlusMemberVariants, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethods, useShopify, useSite, useUpdateBuyerIdentity, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia, waitForGtagReady };
3471
3780
  //# sourceMappingURL=index.mjs.map
3472
3781
  //# sourceMappingURL=index.mjs.map