@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/hooks/index.d.mts +39 -44
- package/dist/hooks/index.d.ts +39 -44
- package/dist/hooks/index.js +347 -92
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +340 -93
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +436 -115
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +425 -116
- package/dist/index.mjs.map +1 -1
- package/dist/provider/index.d.mts +26 -14
- package/dist/provider/index.d.ts +26 -14
- package/dist/provider/index.js +155 -32
- package/dist/provider/index.js.map +1 -1
- package/dist/provider/index.mjs +155 -32
- package/dist/provider/index.mjs.map +1 -1
- package/dist/{types-CMMWxyUF.d.mts → types-C4qc-wG4.d.mts} +167 -7
- package/dist/{types-CMMWxyUF.d.ts → types-C4qc-wG4.d.ts} +167 -7
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -885,15 +885,23 @@ var trackAddToCartGA = ({
|
|
|
885
885
|
currency: currencyCode,
|
|
886
886
|
value: totalPrice,
|
|
887
887
|
position: gtmParams?.position || "",
|
|
888
|
-
items: lineItems.map((
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
888
|
+
items: lineItems.map((item) => {
|
|
889
|
+
const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
|
|
890
|
+
const itemCategoryId = item.gtmParams?.item_category_id;
|
|
891
|
+
const itemVariantId = item.variant?.id ? shopifyCore.atobID(item.variant.id) : void 0;
|
|
892
|
+
return {
|
|
893
|
+
item_id: item.variant?.sku,
|
|
894
|
+
item_name: item.variant?.product?.title || item.variant?.product?.title,
|
|
895
|
+
item_brand: gtmParams?.brand || "",
|
|
896
|
+
item_category: item.variant?.product?.productType || "",
|
|
897
|
+
item_variant: item.variant?.title || item.variant?.title,
|
|
898
|
+
price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
|
|
899
|
+
quantity: item.quantity || 1,
|
|
900
|
+
...imageUrl && { image_url: imageUrl },
|
|
901
|
+
...itemCategoryId && { item_category_id: itemCategoryId },
|
|
902
|
+
...itemVariantId && { item_variant_id: itemVariantId }
|
|
903
|
+
};
|
|
904
|
+
}),
|
|
897
905
|
...gtmParams?.ga4Params
|
|
898
906
|
}
|
|
899
907
|
});
|
|
@@ -920,15 +928,23 @@ var trackBeginCheckoutGA = ({
|
|
|
920
928
|
position: gtmParams?.position,
|
|
921
929
|
currency: currencyCode,
|
|
922
930
|
value: totalPrice,
|
|
923
|
-
items: lineItems.map((item) =>
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
931
|
+
items: lineItems.map((item) => {
|
|
932
|
+
const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
|
|
933
|
+
const itemCategoryId = item.gtmParams?.item_category_id;
|
|
934
|
+
const itemVariantId = item.variant?.id ? shopifyCore.atobID(item.variant.id) : void 0;
|
|
935
|
+
return {
|
|
936
|
+
item_id: item.variant?.sku,
|
|
937
|
+
item_name: item.variant?.product?.title,
|
|
938
|
+
item_brand: gtmParams?.brand || "",
|
|
939
|
+
item_category: item.variant?.product?.productType,
|
|
940
|
+
item_variant: item.variant?.title,
|
|
941
|
+
price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
|
|
942
|
+
quantity: item.quantity || 1,
|
|
943
|
+
...imageUrl && { image_url: imageUrl },
|
|
944
|
+
...itemCategoryId !== void 0 && { item_category_id: itemCategoryId },
|
|
945
|
+
...itemVariantId && { item_variant_id: itemVariantId }
|
|
946
|
+
};
|
|
947
|
+
}),
|
|
932
948
|
...gtmParams?.ga4Params
|
|
933
949
|
}
|
|
934
950
|
});
|
|
@@ -956,19 +972,111 @@ var trackBuyNowGA = ({
|
|
|
956
972
|
position: gtmParams?.position,
|
|
957
973
|
currency: currencyCode,
|
|
958
974
|
value: totalPrice,
|
|
959
|
-
items: lineItems.map((item) =>
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
975
|
+
items: lineItems.map((item) => {
|
|
976
|
+
const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
|
|
977
|
+
const itemCategoryId = item.gtmParams?.item_category_id;
|
|
978
|
+
const itemVariantId = item.variant?.id ? shopifyCore.atobID(item.variant.id) : void 0;
|
|
979
|
+
return {
|
|
980
|
+
item_id: item.variant?.sku,
|
|
981
|
+
item_name: item.variant?.product?.title || item.variant?.title,
|
|
982
|
+
item_brand: gtmParams?.brand || "",
|
|
983
|
+
item_category: item.variant?.product?.productType || "",
|
|
984
|
+
item_variant: item.variant?.title,
|
|
985
|
+
price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
|
|
986
|
+
quantity: item.quantity || 1,
|
|
987
|
+
...imageUrl && { image_url: imageUrl },
|
|
988
|
+
...itemCategoryId !== void 0 && { item_category_id: itemCategoryId },
|
|
989
|
+
...itemVariantId && { item_variant_id: itemVariantId }
|
|
990
|
+
};
|
|
991
|
+
}),
|
|
968
992
|
...gtmParams?.ga4Params
|
|
969
993
|
}
|
|
970
994
|
});
|
|
971
995
|
};
|
|
996
|
+
function waitForGtagReady(timeout = 1e4) {
|
|
997
|
+
return new Promise((resolve, reject) => {
|
|
998
|
+
const start = Date.now();
|
|
999
|
+
function check() {
|
|
1000
|
+
if (typeof window !== "undefined" && typeof window.gtag !== "undefined") {
|
|
1001
|
+
resolve();
|
|
1002
|
+
} else if (Date.now() - start > timeout) {
|
|
1003
|
+
reject(new Error("GA4 gtag not loaded"));
|
|
1004
|
+
} else {
|
|
1005
|
+
setTimeout(check, 50);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
check();
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
var getGA4ClientId = async (measurementId = "G-R0BRMRK4CY") => {
|
|
1012
|
+
try {
|
|
1013
|
+
await waitForGtagReady();
|
|
1014
|
+
return new Promise((resolve, reject) => {
|
|
1015
|
+
if (!window.gtag) {
|
|
1016
|
+
reject(new Error("gtag is not defined"));
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
window.gtag("get", measurementId, "client_id", (clientId) => {
|
|
1020
|
+
if (clientId) {
|
|
1021
|
+
resolve(clientId);
|
|
1022
|
+
} else {
|
|
1023
|
+
reject(new Error("Failed to get client_id"));
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
});
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
console.error("Failed to get GA4 client_id:", error);
|
|
1029
|
+
return "";
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
var getGA4SessionId = async (measurementId = "G-R0BRMRK4CY") => {
|
|
1033
|
+
try {
|
|
1034
|
+
await waitForGtagReady();
|
|
1035
|
+
return new Promise((resolve) => {
|
|
1036
|
+
if (!window.gtag) {
|
|
1037
|
+
resolve("");
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
window.gtag("get", measurementId, "session_id", (sessionId) => {
|
|
1041
|
+
resolve(sessionId || "");
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
} catch (error) {
|
|
1045
|
+
console.error("Failed to get GA4 session_id:", error);
|
|
1046
|
+
return "";
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
var getGA4Data = async (measurementId = "G-R0BRMRK4CY") => {
|
|
1050
|
+
try {
|
|
1051
|
+
await waitForGtagReady();
|
|
1052
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
1053
|
+
setTimeout(() => {
|
|
1054
|
+
resolve({ clientId: "", sessionId: "" });
|
|
1055
|
+
}, 300);
|
|
1056
|
+
});
|
|
1057
|
+
const dataPromise = new Promise((resolve) => {
|
|
1058
|
+
if (!window.gtag) {
|
|
1059
|
+
resolve({ clientId: "", sessionId: "" });
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
window.gtag("get", measurementId, "client_id", (clientId) => {
|
|
1063
|
+
window.gtag("get", measurementId, "session_id", (sessionId) => {
|
|
1064
|
+
resolve({
|
|
1065
|
+
clientId: clientId || "",
|
|
1066
|
+
sessionId: sessionId || ""
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1069
|
+
});
|
|
1070
|
+
});
|
|
1071
|
+
return Promise.race([dataPromise, timeoutPromise]);
|
|
1072
|
+
} catch (error) {
|
|
1073
|
+
console.error("Failed to get GA4 data:", error);
|
|
1074
|
+
return {
|
|
1075
|
+
clientId: "",
|
|
1076
|
+
sessionId: ""
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
972
1080
|
|
|
973
1081
|
// src/tracking/fbq.ts
|
|
974
1082
|
var trackAddToCartFBQ = ({ lineItems = [] }) => {
|
|
@@ -1151,16 +1259,155 @@ var getLinesWithAttributes = ({
|
|
|
1151
1259
|
return functionLine;
|
|
1152
1260
|
});
|
|
1153
1261
|
};
|
|
1262
|
+
function useRemoveCartLines(options) {
|
|
1263
|
+
const { client, locale, cartCookieAdapter } = useShopify();
|
|
1264
|
+
const { mutateCart, metafieldIdentifiers } = useCartContext();
|
|
1265
|
+
const removeLines = react.useCallback(
|
|
1266
|
+
async (_key, { arg }) => {
|
|
1267
|
+
const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
|
|
1268
|
+
let updatedCart = await shopifySdk.removeCartLines(client, {
|
|
1269
|
+
cartId,
|
|
1270
|
+
lineIds,
|
|
1271
|
+
metafieldIdentifiers,
|
|
1272
|
+
cookieAdapter: cartCookieAdapter
|
|
1273
|
+
});
|
|
1274
|
+
if (updatedCart && autoRemoveInvalidCodes) {
|
|
1275
|
+
const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
|
|
1276
|
+
if (unApplicableCodes.length > 0) {
|
|
1277
|
+
if (onCodesRemoved) {
|
|
1278
|
+
const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
|
|
1279
|
+
if (handledCart) {
|
|
1280
|
+
updatedCart = handledCart;
|
|
1281
|
+
}
|
|
1282
|
+
} else {
|
|
1283
|
+
updatedCart = await shopifySdk.updateCartCodes(client, {
|
|
1284
|
+
cartId: updatedCart.id,
|
|
1285
|
+
discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
|
|
1286
|
+
metafieldIdentifiers,
|
|
1287
|
+
cookieAdapter: cartCookieAdapter
|
|
1288
|
+
}) || updatedCart;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
if (updatedCart) {
|
|
1293
|
+
mutateCart(updatedCart);
|
|
1294
|
+
}
|
|
1295
|
+
return updatedCart;
|
|
1296
|
+
},
|
|
1297
|
+
[client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
|
|
1298
|
+
);
|
|
1299
|
+
return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// src/hooks/cart/feature/use-auto-remove-free-gifts.ts
|
|
1303
|
+
function useAutoRemoveFreeGifts(options = {}) {
|
|
1304
|
+
const {
|
|
1305
|
+
removeFunctionGifts = true,
|
|
1306
|
+
removeScriptGifts = true,
|
|
1307
|
+
isGiftLineItem
|
|
1308
|
+
} = options;
|
|
1309
|
+
const [isRemoving, setIsRemoving] = react.useState(false);
|
|
1310
|
+
const { cart } = useCartContext();
|
|
1311
|
+
const { trigger: removeCartLines2 } = useRemoveCartLines();
|
|
1312
|
+
const giftsToRemove = react.useMemo(() => {
|
|
1313
|
+
if (!cart?.lineItems) {
|
|
1314
|
+
return [];
|
|
1315
|
+
}
|
|
1316
|
+
return cart.lineItems.filter((item) => {
|
|
1317
|
+
if (removeFunctionGifts) {
|
|
1318
|
+
const functionAttr = item.customAttributes?.find(
|
|
1319
|
+
(attr) => attr.key === "_discounts_function_env"
|
|
1320
|
+
)?.value;
|
|
1321
|
+
if (functionAttr) {
|
|
1322
|
+
try {
|
|
1323
|
+
const functionAttrObj = JSON.parse(functionAttr);
|
|
1324
|
+
if (functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money) {
|
|
1325
|
+
return true;
|
|
1326
|
+
}
|
|
1327
|
+
} catch (error) {
|
|
1328
|
+
console.error("Failed to parse _discounts_function_env:", error);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
if (removeScriptGifts) {
|
|
1333
|
+
const scriptGiftAttr = item.customAttributes?.find(
|
|
1334
|
+
(attr) => attr.key === "_giveaway_gradient_gifts"
|
|
1335
|
+
);
|
|
1336
|
+
if (scriptGiftAttr) {
|
|
1337
|
+
return true;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
if (isGiftLineItem && isGiftLineItem(item)) {
|
|
1341
|
+
return true;
|
|
1342
|
+
}
|
|
1343
|
+
return false;
|
|
1344
|
+
});
|
|
1345
|
+
}, [cart, removeFunctionGifts, removeScriptGifts, isGiftLineItem]);
|
|
1346
|
+
react.useEffect(() => {
|
|
1347
|
+
if (isRemoving || giftsToRemove.length === 0) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
const performRemoval = async () => {
|
|
1351
|
+
setIsRemoving(true);
|
|
1352
|
+
try {
|
|
1353
|
+
await removeCartLines2({
|
|
1354
|
+
lineIds: giftsToRemove.map((item) => item.id)
|
|
1355
|
+
});
|
|
1356
|
+
} catch (error) {
|
|
1357
|
+
console.error("Failed to remove free gifts:", error);
|
|
1358
|
+
} finally {
|
|
1359
|
+
setIsRemoving(false);
|
|
1360
|
+
}
|
|
1361
|
+
};
|
|
1362
|
+
performRemoval();
|
|
1363
|
+
}, [
|
|
1364
|
+
isRemoving,
|
|
1365
|
+
giftsToRemove,
|
|
1366
|
+
removeCartLines2
|
|
1367
|
+
]);
|
|
1368
|
+
return {
|
|
1369
|
+
isRemoving
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
function isFunctionGift(line) {
|
|
1373
|
+
const functionAttr = line.customAttributes?.find(
|
|
1374
|
+
(attr) => attr.key === "_discounts_function_env"
|
|
1375
|
+
)?.value;
|
|
1376
|
+
if (!functionAttr) {
|
|
1377
|
+
return false;
|
|
1378
|
+
}
|
|
1379
|
+
try {
|
|
1380
|
+
const functionAttrObj = JSON.parse(functionAttr);
|
|
1381
|
+
return Boolean(
|
|
1382
|
+
functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money
|
|
1383
|
+
);
|
|
1384
|
+
} catch {
|
|
1385
|
+
return false;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
function isScriptGift(line) {
|
|
1389
|
+
return line.customAttributes?.some(
|
|
1390
|
+
(attr) => attr.key === "_giveaway_gradient_gifts"
|
|
1391
|
+
) ?? false;
|
|
1392
|
+
}
|
|
1393
|
+
function isBuyGetGift(line) {
|
|
1394
|
+
return line.customAttributes?.some(
|
|
1395
|
+
(attr) => attr.key === "_freegift_related_handlesku"
|
|
1396
|
+
) ?? false;
|
|
1397
|
+
}
|
|
1398
|
+
function isAnyGift(line) {
|
|
1399
|
+
return isFunctionGift(line) || isScriptGift(line) || isBuyGetGift(line);
|
|
1400
|
+
}
|
|
1154
1401
|
function useCalcGiftsFromLines({
|
|
1155
1402
|
lines,
|
|
1156
1403
|
customer,
|
|
1157
1404
|
scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
|
|
1158
1405
|
}) {
|
|
1159
1406
|
const { locale } = useShopify();
|
|
1160
|
-
const { cart,
|
|
1161
|
-
const functionGift = useCalcAutoFreeGift(cart,
|
|
1407
|
+
const { cart, functionAutoFreeGiftConfig, scriptAutoFreeGiftConfig } = useCartContext();
|
|
1408
|
+
const functionGift = useCalcAutoFreeGift(cart, functionAutoFreeGiftConfig || [], customer, lines);
|
|
1162
1409
|
const scriptGift = useScriptAutoFreeGift({
|
|
1163
|
-
campaign:
|
|
1410
|
+
campaign: scriptAutoFreeGiftConfig,
|
|
1164
1411
|
_giveaway: scriptGiveawayKey,
|
|
1165
1412
|
cart,
|
|
1166
1413
|
locale,
|
|
@@ -1195,7 +1442,9 @@ function useCalcGiftsFromLines({
|
|
|
1195
1442
|
const variants = product?.variants;
|
|
1196
1443
|
const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
|
|
1197
1444
|
if (!variant) {
|
|
1198
|
-
console.warn(
|
|
1445
|
+
console.warn(
|
|
1446
|
+
`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`
|
|
1447
|
+
);
|
|
1199
1448
|
return null;
|
|
1200
1449
|
}
|
|
1201
1450
|
return {
|
|
@@ -1338,6 +1587,19 @@ var getReferralAttributes = () => {
|
|
|
1338
1587
|
}
|
|
1339
1588
|
return [];
|
|
1340
1589
|
};
|
|
1590
|
+
var getOperatingSystem = () => {
|
|
1591
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
1592
|
+
return "Unknown";
|
|
1593
|
+
}
|
|
1594
|
+
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
|
1595
|
+
if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
|
|
1596
|
+
return "IOS";
|
|
1597
|
+
}
|
|
1598
|
+
if (/android/i.test(userAgent)) {
|
|
1599
|
+
return "Android";
|
|
1600
|
+
}
|
|
1601
|
+
return "Unknown";
|
|
1602
|
+
};
|
|
1341
1603
|
var getUserType = (customer) => {
|
|
1342
1604
|
let userInfo = Cookies5__default.default.get("userInfo");
|
|
1343
1605
|
if (userInfo) {
|
|
@@ -1359,12 +1621,42 @@ var getUserType = (customer) => {
|
|
|
1359
1621
|
}
|
|
1360
1622
|
return "new_user_login";
|
|
1361
1623
|
};
|
|
1362
|
-
function
|
|
1624
|
+
function getGA4Attributes(ga4Data) {
|
|
1625
|
+
if (!ga4Data?.clientId && !ga4Data?.sessionId) {
|
|
1626
|
+
return [];
|
|
1627
|
+
}
|
|
1628
|
+
const attributes = [];
|
|
1629
|
+
if (ga4Data.clientId) {
|
|
1630
|
+
attributes.push({
|
|
1631
|
+
key: "_ga4_client_id",
|
|
1632
|
+
value: ga4Data.clientId
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
if (ga4Data.sessionId) {
|
|
1636
|
+
attributes.push({
|
|
1637
|
+
key: "_ga4_session_id",
|
|
1638
|
+
value: ga4Data.sessionId
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1641
|
+
return attributes;
|
|
1642
|
+
}
|
|
1643
|
+
async function getGA4AttributesAsync() {
|
|
1644
|
+
try {
|
|
1645
|
+
const ga4Data = await getGA4Data();
|
|
1646
|
+
return getGA4Attributes(ga4Data);
|
|
1647
|
+
} catch (error) {
|
|
1648
|
+
console.error("Failed to get GA4 attributes:", error);
|
|
1649
|
+
return [];
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
function getCartBasicAttributes({
|
|
1363
1653
|
profile,
|
|
1364
1654
|
customer,
|
|
1365
1655
|
cart,
|
|
1366
1656
|
memberType,
|
|
1367
|
-
currentUrl = ""
|
|
1657
|
+
currentUrl = "",
|
|
1658
|
+
appContext,
|
|
1659
|
+
buyPath
|
|
1368
1660
|
}) {
|
|
1369
1661
|
const userType = getUserType(customer);
|
|
1370
1662
|
const memberAttributes = [
|
|
@@ -1391,12 +1683,10 @@ function getCartAttributes({
|
|
|
1391
1683
|
value: "1"
|
|
1392
1684
|
});
|
|
1393
1685
|
}
|
|
1394
|
-
const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
|
|
1395
1686
|
const functionAttributes = [
|
|
1396
1687
|
{
|
|
1397
1688
|
key: CUSTOMER_ATTRIBUTE_KEY,
|
|
1398
1689
|
value: JSON.stringify({
|
|
1399
|
-
discount_code: discountCodes,
|
|
1400
1690
|
user_tags: customer?.tags || []
|
|
1401
1691
|
})
|
|
1402
1692
|
}
|
|
@@ -1404,26 +1694,38 @@ function getCartAttributes({
|
|
|
1404
1694
|
const presellAttributes = [
|
|
1405
1695
|
{
|
|
1406
1696
|
key: "_presale",
|
|
1407
|
-
value: cart?.lineItems
|
|
1697
|
+
value: cart?.lineItems?.some((item) => item?.variant?.metafields?.presell === "presell")
|
|
1408
1698
|
}
|
|
1409
1699
|
];
|
|
1410
1700
|
const weightAttributes = [
|
|
1411
1701
|
{
|
|
1412
1702
|
key: "_weight",
|
|
1413
|
-
value: cart?.lineItems
|
|
1703
|
+
value: cart?.lineItems?.reduce((acc, item) => {
|
|
1414
1704
|
const itemWeight = new Decimal2__default.default(item.variant.weight ?? 0).times(item.quantity);
|
|
1415
1705
|
return new Decimal2__default.default(acc).plus(itemWeight).toNumber();
|
|
1416
1706
|
}, 0).toString()
|
|
1417
|
-
},
|
|
1418
|
-
{
|
|
1419
|
-
key: "_app_source_name",
|
|
1420
|
-
value: "dtc"
|
|
1421
1707
|
}
|
|
1422
1708
|
];
|
|
1423
1709
|
const trackingAttributes = [
|
|
1424
1710
|
{
|
|
1425
1711
|
key: "utm_params",
|
|
1426
1712
|
value: currentUrl
|
|
1713
|
+
},
|
|
1714
|
+
{
|
|
1715
|
+
key: "_app_source_name",
|
|
1716
|
+
value: appContext?.isInApp && appContext?.appName ? appContext.appName : "dtc"
|
|
1717
|
+
},
|
|
1718
|
+
{
|
|
1719
|
+
key: "_operating_system",
|
|
1720
|
+
value: getOperatingSystem()
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
key: "_cart_id",
|
|
1724
|
+
value: cart?.id
|
|
1725
|
+
},
|
|
1726
|
+
{
|
|
1727
|
+
key: "_buy_path",
|
|
1728
|
+
value: buyPath
|
|
1427
1729
|
}
|
|
1428
1730
|
];
|
|
1429
1731
|
const commonAttributes = [
|
|
@@ -1443,21 +1745,41 @@ var useCartAttributes = ({
|
|
|
1443
1745
|
profile,
|
|
1444
1746
|
customer,
|
|
1445
1747
|
cart,
|
|
1446
|
-
memberType
|
|
1748
|
+
memberType,
|
|
1749
|
+
appContext,
|
|
1750
|
+
buyPath
|
|
1447
1751
|
}) => {
|
|
1448
1752
|
const [currentUrl, setCurrentUrl] = react.useState("");
|
|
1753
|
+
const [ga4Data, setGa4Data] = react.useState(null);
|
|
1449
1754
|
react.useEffect(() => {
|
|
1450
1755
|
setCurrentUrl(window.location.href);
|
|
1451
1756
|
}, []);
|
|
1757
|
+
react.useEffect(() => {
|
|
1758
|
+
let isMounted = true;
|
|
1759
|
+
getGA4Data().then((data) => {
|
|
1760
|
+
if (isMounted) {
|
|
1761
|
+
setGa4Data(data);
|
|
1762
|
+
}
|
|
1763
|
+
}).catch((error) => {
|
|
1764
|
+
console.error("Failed to get GA4 data in useCartAttributes:", error);
|
|
1765
|
+
});
|
|
1766
|
+
return () => {
|
|
1767
|
+
isMounted = false;
|
|
1768
|
+
};
|
|
1769
|
+
}, []);
|
|
1452
1770
|
const attributes = react.useMemo(() => {
|
|
1453
|
-
|
|
1771
|
+
const basicAttributes = getCartBasicAttributes({
|
|
1454
1772
|
profile,
|
|
1455
1773
|
customer,
|
|
1456
1774
|
cart,
|
|
1457
1775
|
memberType,
|
|
1458
|
-
currentUrl
|
|
1776
|
+
currentUrl,
|
|
1777
|
+
appContext,
|
|
1778
|
+
buyPath
|
|
1459
1779
|
});
|
|
1460
|
-
|
|
1780
|
+
const ga4Attributes = getGA4Attributes(ga4Data);
|
|
1781
|
+
return [...basicAttributes, ...ga4Attributes];
|
|
1782
|
+
}, [profile, customer, cart, memberType, currentUrl, appContext, buyPath, ga4Data]);
|
|
1461
1783
|
return react.useMemo(
|
|
1462
1784
|
() => ({
|
|
1463
1785
|
attributes
|
|
@@ -1520,12 +1842,9 @@ var useUpdateLineCodeAmountAttributes = ({
|
|
|
1520
1842
|
const codeDiscount = line.discountAllocations?.find(
|
|
1521
1843
|
(allocation) => mainProductDiscountCodes?.includes(allocation.code)
|
|
1522
1844
|
);
|
|
1523
|
-
const hasFunctionEnvAttribute = line.customAttributes?.find(
|
|
1524
|
-
(attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY
|
|
1525
|
-
);
|
|
1526
1845
|
const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
|
|
1527
1846
|
const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
|
|
1528
|
-
if (!hasSameFunctionEnvAttribute &&
|
|
1847
|
+
if (!hasSameFunctionEnvAttribute && !functionEnvValue.is_gift) {
|
|
1529
1848
|
attrNeedUpdate.push({
|
|
1530
1849
|
key: CUSTOMER_ATTRIBUTE_KEY,
|
|
1531
1850
|
value: JSON.stringify({
|
|
@@ -1946,47 +2265,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
|
|
|
1946
2265
|
return checkoutCustomAttributes;
|
|
1947
2266
|
}, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
|
|
1948
2267
|
};
|
|
1949
|
-
function useRemoveCartLines(options) {
|
|
1950
|
-
const { client, locale, cartCookieAdapter } = useShopify();
|
|
1951
|
-
const { mutateCart, metafieldIdentifiers } = useCartContext();
|
|
1952
|
-
const removeLines = react.useCallback(
|
|
1953
|
-
async (_key, { arg }) => {
|
|
1954
|
-
const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
|
|
1955
|
-
let updatedCart = await shopifySdk.removeCartLines(client, {
|
|
1956
|
-
cartId,
|
|
1957
|
-
lineIds,
|
|
1958
|
-
metafieldIdentifiers,
|
|
1959
|
-
cookieAdapter: cartCookieAdapter
|
|
1960
|
-
});
|
|
1961
|
-
if (updatedCart && autoRemoveInvalidCodes) {
|
|
1962
|
-
const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
|
|
1963
|
-
if (unApplicableCodes.length > 0) {
|
|
1964
|
-
if (onCodesRemoved) {
|
|
1965
|
-
const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
|
|
1966
|
-
if (handledCart) {
|
|
1967
|
-
updatedCart = handledCart;
|
|
1968
|
-
}
|
|
1969
|
-
} else {
|
|
1970
|
-
updatedCart = await shopifySdk.updateCartCodes(client, {
|
|
1971
|
-
cartId: updatedCart.id,
|
|
1972
|
-
discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
|
|
1973
|
-
metafieldIdentifiers,
|
|
1974
|
-
cookieAdapter: cartCookieAdapter
|
|
1975
|
-
}) || updatedCart;
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
if (updatedCart) {
|
|
1980
|
-
mutateCart(updatedCart);
|
|
1981
|
-
}
|
|
1982
|
-
return updatedCart;
|
|
1983
|
-
},
|
|
1984
|
-
[client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
|
|
1985
|
-
);
|
|
1986
|
-
return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
// src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
|
|
1990
2268
|
function useAutoRemovePlusMemberInCart({
|
|
1991
2269
|
cart,
|
|
1992
2270
|
profile,
|
|
@@ -2201,7 +2479,8 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
|
|
|
2201
2479
|
profile,
|
|
2202
2480
|
customer,
|
|
2203
2481
|
cart,
|
|
2204
|
-
memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
|
|
2482
|
+
memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0),
|
|
2483
|
+
buyPath: "hasCart"
|
|
2205
2484
|
});
|
|
2206
2485
|
const addToCart = react.useCallback(
|
|
2207
2486
|
async (_key, { arg }) => {
|
|
@@ -2374,7 +2653,7 @@ function useUpdateBuyerIdentity({
|
|
|
2374
2653
|
}
|
|
2375
2654
|
function useBuyNow({ withTrack = true } = {}, swrOptions) {
|
|
2376
2655
|
const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
|
|
2377
|
-
const { profile, customer, memberSetting } = useCartContext();
|
|
2656
|
+
const { profile, customer, memberSetting, appContext } = useCartContext();
|
|
2378
2657
|
const isLoggedIn = userAdapter?.isLoggedIn || false;
|
|
2379
2658
|
const buyNow = react.useCallback(
|
|
2380
2659
|
async (_key, { arg }) => {
|
|
@@ -2396,12 +2675,6 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
|
|
|
2396
2675
|
lines: lineItems
|
|
2397
2676
|
});
|
|
2398
2677
|
const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
|
|
2399
|
-
const cartAttributes = getCartAttributes({
|
|
2400
|
-
profile,
|
|
2401
|
-
customer,
|
|
2402
|
-
memberType,
|
|
2403
|
-
currentUrl: window.location.href
|
|
2404
|
-
});
|
|
2405
2678
|
const linesWithFunctionAttributes = getLinesWithAttributes({
|
|
2406
2679
|
lineItems
|
|
2407
2680
|
});
|
|
@@ -2414,13 +2687,23 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
|
|
|
2414
2687
|
if (lines.length === 0) {
|
|
2415
2688
|
return;
|
|
2416
2689
|
}
|
|
2690
|
+
const basicCartAttributes = getCartBasicAttributes({
|
|
2691
|
+
profile,
|
|
2692
|
+
customer,
|
|
2693
|
+
memberType,
|
|
2694
|
+
cart: { lineItems },
|
|
2695
|
+
currentUrl: window.location.href,
|
|
2696
|
+
appContext,
|
|
2697
|
+
buyPath: "buyNow"
|
|
2698
|
+
});
|
|
2699
|
+
const ga4Attributes = await getGA4AttributesAsync();
|
|
2417
2700
|
const resultCart = await shopifySdk.createCart(client, {
|
|
2418
2701
|
lines,
|
|
2419
2702
|
metafieldIdentifiers,
|
|
2420
2703
|
cookieAdapter: cartCookieAdapter,
|
|
2421
2704
|
buyerIdentity,
|
|
2422
2705
|
discountCodes,
|
|
2423
|
-
customAttributes: [...
|
|
2706
|
+
customAttributes: [...basicCartAttributes, ...ga4Attributes, ...customAttributes || []]
|
|
2424
2707
|
});
|
|
2425
2708
|
if (!resultCart) {
|
|
2426
2709
|
throw new Error("Failed to create cart for buy now");
|
|
@@ -2445,7 +2728,17 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
|
|
|
2445
2728
|
}
|
|
2446
2729
|
return resultCart;
|
|
2447
2730
|
},
|
|
2448
|
-
[
|
|
2731
|
+
[
|
|
2732
|
+
client,
|
|
2733
|
+
locale,
|
|
2734
|
+
isLoggedIn,
|
|
2735
|
+
cartCookieAdapter,
|
|
2736
|
+
withTrack,
|
|
2737
|
+
customer,
|
|
2738
|
+
profile,
|
|
2739
|
+
memberSetting,
|
|
2740
|
+
appContext
|
|
2741
|
+
]
|
|
2449
2742
|
);
|
|
2450
2743
|
return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
|
|
2451
2744
|
}
|
|
@@ -3241,13 +3534,14 @@ var CartContext = react.createContext(null);
|
|
|
3241
3534
|
function CartProvider({
|
|
3242
3535
|
children,
|
|
3243
3536
|
// swrOptions,
|
|
3244
|
-
|
|
3245
|
-
|
|
3537
|
+
functionAutoFreeGiftConfig,
|
|
3538
|
+
scriptAutoFreeGiftConfig,
|
|
3246
3539
|
profile,
|
|
3247
3540
|
customer,
|
|
3248
3541
|
locale,
|
|
3249
3542
|
metafieldIdentifiers,
|
|
3250
|
-
memberSetting
|
|
3543
|
+
memberSetting,
|
|
3544
|
+
appContext
|
|
3251
3545
|
}) {
|
|
3252
3546
|
const { client, cartCookieAdapter } = useShopify();
|
|
3253
3547
|
const [customAttributes, setCustomAttributes] = react.useState([]);
|
|
@@ -3292,7 +3586,8 @@ function CartProvider({
|
|
|
3292
3586
|
profile,
|
|
3293
3587
|
customer,
|
|
3294
3588
|
cart,
|
|
3295
|
-
memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
|
|
3589
|
+
memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0),
|
|
3590
|
+
appContext
|
|
3296
3591
|
});
|
|
3297
3592
|
ahooks.useRequest(
|
|
3298
3593
|
() => {
|
|
@@ -3346,9 +3641,13 @@ function CartProvider({
|
|
|
3346
3641
|
},
|
|
3347
3642
|
[setCustomAttributes]
|
|
3348
3643
|
);
|
|
3349
|
-
const functionAutoFreeGiftResult = useCalcAutoFreeGift(
|
|
3644
|
+
const functionAutoFreeGiftResult = useCalcAutoFreeGift(
|
|
3645
|
+
cart,
|
|
3646
|
+
functionAutoFreeGiftConfig || [],
|
|
3647
|
+
customer
|
|
3648
|
+
);
|
|
3350
3649
|
const scriptAutoFreeGiftResult = useScriptAutoFreeGift({
|
|
3351
|
-
campaign:
|
|
3650
|
+
campaign: scriptAutoFreeGiftConfig,
|
|
3352
3651
|
_giveaway: CUSTOMER_SCRIPT_GIFT_KEY,
|
|
3353
3652
|
cart,
|
|
3354
3653
|
profile
|
|
@@ -3356,10 +3655,10 @@ function CartProvider({
|
|
|
3356
3655
|
const formattedScriptGifts = react.useMemo(() => {
|
|
3357
3656
|
return formatScriptAutoFreeGift({
|
|
3358
3657
|
scriptAutoFreeGiftResult,
|
|
3359
|
-
gradient_gifts:
|
|
3658
|
+
gradient_gifts: scriptAutoFreeGiftConfig,
|
|
3360
3659
|
locale
|
|
3361
3660
|
});
|
|
3362
|
-
}, [scriptAutoFreeGiftResult,
|
|
3661
|
+
}, [scriptAutoFreeGiftResult, scriptAutoFreeGiftConfig, locale]);
|
|
3363
3662
|
const formattedFunctionGifts = react.useMemo(() => {
|
|
3364
3663
|
return formatFunctionAutoFreeGift({
|
|
3365
3664
|
qualifyingGift: functionAutoFreeGiftResult?.qualifyingGift || null,
|
|
@@ -3407,6 +3706,12 @@ function CartProvider({
|
|
|
3407
3706
|
const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
|
|
3408
3707
|
return cartLinesCount + giftLinesCount;
|
|
3409
3708
|
}, [cart?.lineItems, giftNeedAddToCartLines]);
|
|
3709
|
+
const autoRemoveFreeGiftsOptions = react.useMemo(() => {
|
|
3710
|
+
return {
|
|
3711
|
+
removeFunctionGifts: !!functionAutoFreeGiftConfig,
|
|
3712
|
+
removeScriptGifts: !!scriptAutoFreeGiftConfig
|
|
3713
|
+
};
|
|
3714
|
+
}, [functionAutoFreeGiftConfig, scriptAutoFreeGiftConfig]);
|
|
3410
3715
|
const value = react.useMemo(
|
|
3411
3716
|
() => ({
|
|
3412
3717
|
totalQuantity,
|
|
@@ -3421,8 +3726,8 @@ function CartProvider({
|
|
|
3421
3726
|
customer,
|
|
3422
3727
|
isCodeChanging,
|
|
3423
3728
|
setIsCodeChanging,
|
|
3424
|
-
|
|
3425
|
-
|
|
3729
|
+
functionAutoFreeGiftConfig,
|
|
3730
|
+
scriptAutoFreeGiftConfig,
|
|
3426
3731
|
setLoadingState,
|
|
3427
3732
|
loadingState,
|
|
3428
3733
|
// function满赠
|
|
@@ -3435,7 +3740,9 @@ function CartProvider({
|
|
|
3435
3740
|
setScriptAutoFreeGift,
|
|
3436
3741
|
giftNeedAddToCartLines,
|
|
3437
3742
|
metafieldIdentifiers,
|
|
3438
|
-
memberSetting
|
|
3743
|
+
memberSetting,
|
|
3744
|
+
appContext,
|
|
3745
|
+
autoRemoveFreeGiftsOptions
|
|
3439
3746
|
}),
|
|
3440
3747
|
[
|
|
3441
3748
|
cart,
|
|
@@ -3447,8 +3754,8 @@ function CartProvider({
|
|
|
3447
3754
|
removeCustomAttributes,
|
|
3448
3755
|
locale,
|
|
3449
3756
|
isCodeChanging,
|
|
3450
|
-
|
|
3451
|
-
|
|
3757
|
+
functionAutoFreeGiftConfig,
|
|
3758
|
+
scriptAutoFreeGiftConfig,
|
|
3452
3759
|
loadingState,
|
|
3453
3760
|
// function满赠
|
|
3454
3761
|
functionAutoFreeGift,
|
|
@@ -3462,7 +3769,9 @@ function CartProvider({
|
|
|
3462
3769
|
metafieldIdentifiers,
|
|
3463
3770
|
customer,
|
|
3464
3771
|
profile,
|
|
3465
|
-
memberSetting
|
|
3772
|
+
memberSetting,
|
|
3773
|
+
appContext,
|
|
3774
|
+
autoRemoveFreeGiftsOptions
|
|
3466
3775
|
]
|
|
3467
3776
|
);
|
|
3468
3777
|
return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
|
|
@@ -3508,14 +3817,24 @@ exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
|
|
|
3508
3817
|
exports.formatScriptAutoFreeGift = formatScriptAutoFreeGift;
|
|
3509
3818
|
exports.gaTrack = gaTrack;
|
|
3510
3819
|
exports.getCachedGeoLocation = getCachedGeoLocation;
|
|
3511
|
-
exports.
|
|
3820
|
+
exports.getCartBasicAttributes = getCartBasicAttributes;
|
|
3512
3821
|
exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
|
|
3822
|
+
exports.getGA4Attributes = getGA4Attributes;
|
|
3823
|
+
exports.getGA4AttributesAsync = getGA4AttributesAsync;
|
|
3824
|
+
exports.getGA4ClientId = getGA4ClientId;
|
|
3825
|
+
exports.getGA4Data = getGA4Data;
|
|
3826
|
+
exports.getGA4SessionId = getGA4SessionId;
|
|
3513
3827
|
exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
|
|
3828
|
+
exports.getOperatingSystem = getOperatingSystem;
|
|
3514
3829
|
exports.getQuery = getQuery;
|
|
3515
3830
|
exports.getReferralAttributes = getReferralAttributes;
|
|
3516
3831
|
exports.getUserType = getUserType;
|
|
3517
3832
|
exports.hasPlusMemberInCart = hasPlusMemberInCart;
|
|
3518
3833
|
exports.hasPlusMemberInLines = hasPlusMemberInLines;
|
|
3834
|
+
exports.isAnyGift = isAnyGift;
|
|
3835
|
+
exports.isBuyGetGift = isBuyGetGift;
|
|
3836
|
+
exports.isFunctionGift = isFunctionGift;
|
|
3837
|
+
exports.isScriptGift = isScriptGift;
|
|
3519
3838
|
exports.normalizeAddToCartLines = normalizeAddToCartLines;
|
|
3520
3839
|
exports.preCheck = preCheck;
|
|
3521
3840
|
exports.safeParse = safeParse;
|
|
@@ -3533,6 +3852,7 @@ exports.useApplyCartCodes = useApplyCartCodes;
|
|
|
3533
3852
|
exports.useArticle = useArticle;
|
|
3534
3853
|
exports.useArticles = useArticles;
|
|
3535
3854
|
exports.useArticlesInBlog = useArticlesInBlog;
|
|
3855
|
+
exports.useAutoRemoveFreeGifts = useAutoRemoveFreeGifts;
|
|
3536
3856
|
exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
|
|
3537
3857
|
exports.useAvailableDeliveryCoupon = useAvailableDeliveryCoupon;
|
|
3538
3858
|
exports.useBlog = useBlog;
|
|
@@ -3575,6 +3895,7 @@ exports.useUpdateLineCodeAmountAttributes = useUpdateLineCodeAmountAttributes;
|
|
|
3575
3895
|
exports.useUpdateVariantQuery = useUpdateVariantQuery;
|
|
3576
3896
|
exports.useVariant = useVariant;
|
|
3577
3897
|
exports.useVariantMedia = useVariantMedia;
|
|
3898
|
+
exports.waitForGtagReady = waitForGtagReady;
|
|
3578
3899
|
Object.keys(shopifySdk).forEach(function (k) {
|
|
3579
3900
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
3580
3901
|
enumerable: true,
|