@anker-in/shopify-react 0.1.1-beta.43 → 0.1.1-beta.44

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.
@@ -525,7 +525,8 @@ var useScriptAutoFreeGift = ({
525
525
  _giveaway,
526
526
  cart,
527
527
  locale: providedLocale,
528
- lines
528
+ lines,
529
+ profile
529
530
  }) => {
530
531
  const { client, locale: contextLocale } = useShopify();
531
532
  const locale = providedLocale || contextLocale;
@@ -549,8 +550,9 @@ var useScriptAutoFreeGift = ({
549
550
  const utmCampaign = Cookies5__default.default.get("utm_campaign") || query?.utm_campaign;
550
551
  if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
551
552
  return false;
553
+ if (campaign.requireLogin && !profile?.email) return false;
552
554
  return true;
553
- }, [campaign]);
555
+ }, [campaign, profile]);
554
556
  const [upgrade_multiple, upgrade_value] = react.useMemo(() => {
555
557
  let upgrade_multiple2 = 1;
556
558
  let upgrade_value2 = 0;
@@ -689,7 +691,10 @@ function useCartContext(options) {
689
691
  }
690
692
 
691
693
  // src/hooks/cart/use-create-cart.ts
692
- function useCreateCart(options) {
694
+ function useCreateCart({
695
+ updateCookie = false,
696
+ options
697
+ }) {
693
698
  const { client, locale, cartCookieAdapter } = useShopify();
694
699
  const { mutateCart, metafieldIdentifiers } = useCartContext();
695
700
  const createNewCart = react.useCallback(
@@ -697,7 +702,8 @@ function useCreateCart(options) {
697
702
  let newCart = await shopifySdk.createCart(client, {
698
703
  ...arg,
699
704
  metafieldIdentifiers,
700
- cookieAdapter: cartCookieAdapter
705
+ cookieAdapter: cartCookieAdapter,
706
+ updateCookie
701
707
  });
702
708
  if (newCart) {
703
709
  const unApplicableCodes = newCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
@@ -1035,260 +1041,6 @@ var getLinesWithAttributes = ({
1035
1041
  return functionLine;
1036
1042
  });
1037
1043
  };
1038
-
1039
- // src/hooks/cart/use-add-to-cart.ts
1040
- function useAddToCart({ withTrack = true } = {}, swrOptions) {
1041
- const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
1042
- const { cart, addCustomAttributes } = useCartContext();
1043
- const { trigger: applyCartCodes } = useApplyCartCodes();
1044
- const { trigger: removeInvalidCodes } = useRemoveCartCodes();
1045
- const { trigger: addCartLines2 } = useAddCartLines();
1046
- const { trigger: createCart4 } = useCreateCart();
1047
- const addToCart = react.useCallback(
1048
- async (_key, { arg }) => {
1049
- const {
1050
- lineItems,
1051
- cartId: providedCartId,
1052
- discountCodes,
1053
- gtmParams = {},
1054
- buyerIdentity,
1055
- needCreateCart = false,
1056
- onCodesInvalid,
1057
- replaceExistingCodes,
1058
- customAttributes
1059
- } = arg;
1060
- if (!lineItems || lineItems.length === 0) {
1061
- return;
1062
- }
1063
- performanceAdapter?.addToCartStart();
1064
- const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
1065
- const lines = linesWithFunctionAttributes.map((item) => ({
1066
- merchandiseId: item.variant?.id || "",
1067
- quantity: item.quantity || 1,
1068
- attributes: item.attributes,
1069
- sellingPlanId: item.sellingPlanId
1070
- })).filter((item) => item.merchandiseId && item.quantity);
1071
- if (lines.length === 0) {
1072
- return;
1073
- }
1074
- let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
1075
- let resultCart = null;
1076
- if (!cartId) {
1077
- resultCart = await createCart4({
1078
- lines,
1079
- buyerIdentity,
1080
- discountCodes,
1081
- customAttributes
1082
- });
1083
- } else {
1084
- resultCart = await addCartLines2({
1085
- cartId,
1086
- lines
1087
- });
1088
- console.log("npm addCartLines resultCart", resultCart);
1089
- if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
1090
- const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1091
- if (unapplicableCodes.length > 0) {
1092
- if (onCodesInvalid) {
1093
- const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
1094
- if (handledCart) {
1095
- resultCart = handledCart;
1096
- }
1097
- } else {
1098
- await removeInvalidCodes({
1099
- discountCodes: unapplicableCodes
1100
- });
1101
- }
1102
- }
1103
- }
1104
- if (resultCart && discountCodes && discountCodes.length > 0) {
1105
- applyCartCodes({
1106
- replaceExistingCodes,
1107
- discountCodes
1108
- });
1109
- }
1110
- if (customAttributes && customAttributes.length > 0) {
1111
- addCustomAttributes(customAttributes);
1112
- }
1113
- }
1114
- if (withTrack) {
1115
- trackAddToCartGA({
1116
- lineItems,
1117
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1118
- });
1119
- trackAddToCartFBQ({ lineItems });
1120
- }
1121
- performanceAdapter?.addToCartEnd();
1122
- return resultCart;
1123
- },
1124
- [
1125
- client,
1126
- locale,
1127
- cartCookieAdapter,
1128
- userAdapter,
1129
- cart,
1130
- withTrack,
1131
- performanceAdapter,
1132
- createCart4,
1133
- addCartLines2,
1134
- applyCartCodes,
1135
- removeInvalidCodes,
1136
- addCustomAttributes,
1137
- config
1138
- ]
1139
- );
1140
- return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
1141
- }
1142
- function useUpdateCartLines(options) {
1143
- const { client, locale, cartCookieAdapter } = useShopify();
1144
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1145
- const updateLines = react.useCallback(
1146
- async (_key, { arg }) => {
1147
- const updatedCart = await shopifySdk.updateCartLines(client, {
1148
- ...arg,
1149
- metafieldIdentifiers,
1150
- cookieAdapter: cartCookieAdapter
1151
- });
1152
- if (updatedCart) {
1153
- mutateCart(updatedCart);
1154
- }
1155
- console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
1156
- return updatedCart;
1157
- },
1158
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1159
- );
1160
- return useSWRMutation__default.default("update-cart-lines", updateLines, options);
1161
- }
1162
- function useRemoveCartLines(options) {
1163
- const { client, locale, cartCookieAdapter } = useShopify();
1164
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1165
- const removeLines = react.useCallback(
1166
- async (_key, { arg }) => {
1167
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1168
- let updatedCart = await shopifySdk.removeCartLines(client, {
1169
- cartId,
1170
- lineIds,
1171
- metafieldIdentifiers,
1172
- cookieAdapter: cartCookieAdapter
1173
- });
1174
- if (updatedCart && autoRemoveInvalidCodes) {
1175
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1176
- if (unApplicableCodes.length > 0) {
1177
- if (onCodesRemoved) {
1178
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1179
- if (handledCart) {
1180
- updatedCart = handledCart;
1181
- }
1182
- } else {
1183
- updatedCart = await shopifySdk.updateCartCodes(client, {
1184
- cartId: updatedCart.id,
1185
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1186
- metafieldIdentifiers,
1187
- cookieAdapter: cartCookieAdapter
1188
- }) || updatedCart;
1189
- }
1190
- }
1191
- }
1192
- if (updatedCart) {
1193
- mutateCart(updatedCart);
1194
- }
1195
- return updatedCart;
1196
- },
1197
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1198
- );
1199
- return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1200
- }
1201
- function useUpdateCartAttributes({
1202
- mutate,
1203
- metafieldIdentifiers,
1204
- disabled = false,
1205
- swrOptions
1206
- }) {
1207
- const { client, locale, cartCookieAdapter } = useShopify();
1208
- const updateAttributes = react.useCallback(
1209
- async (_key, { arg }) => {
1210
- if (disabled || !cartCookieAdapter?.getCartId(locale)) {
1211
- return void 0;
1212
- }
1213
- const updatedCart = await shopifySdk.updateCartAttributes(client, {
1214
- ...arg,
1215
- metafieldIdentifiers,
1216
- cookieAdapter: cartCookieAdapter
1217
- });
1218
- if (updatedCart) {
1219
- mutate(updatedCart);
1220
- }
1221
- return updatedCart;
1222
- },
1223
- [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
1224
- );
1225
- return useSWRMutation__default.default("update-cart-attributes", updateAttributes, swrOptions);
1226
- }
1227
- function useBuyNow({ withTrack = true } = {}, swrOptions) {
1228
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
1229
- const isLoggedIn = userAdapter?.isLoggedIn || false;
1230
- const buyNow = react.useCallback(
1231
- async (_key, { arg }) => {
1232
- const {
1233
- lineItems,
1234
- discountCodes,
1235
- gtmParams = {},
1236
- buyerIdentity,
1237
- fbqTrackConfig,
1238
- customAttributes,
1239
- metafieldIdentifiers,
1240
- redirectToCheckout
1241
- } = arg;
1242
- if (!lineItems || lineItems.length === 0) {
1243
- return;
1244
- }
1245
- const linesWithFunctionAttributes = getLinesWithAttributes({
1246
- lineItems
1247
- });
1248
- const lines = linesWithFunctionAttributes.map((item) => ({
1249
- merchandiseId: item.variant?.id || "",
1250
- quantity: item.quantity || 1,
1251
- attributes: item.attributes,
1252
- sellingPlanId: item.sellingPlanId
1253
- })).filter((item) => item.merchandiseId);
1254
- if (lines.length === 0) {
1255
- return;
1256
- }
1257
- const resultCart = await shopifySdk.createCart(client, {
1258
- lines,
1259
- metafieldIdentifiers,
1260
- cookieAdapter: cartCookieAdapter,
1261
- buyerIdentity,
1262
- discountCodes,
1263
- customAttributes
1264
- });
1265
- if (!resultCart) {
1266
- throw new Error("Failed to create cart for buy now");
1267
- }
1268
- if (withTrack && resultCart.lineItems) {
1269
- trackBuyNowGA({
1270
- lineItems,
1271
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1272
- });
1273
- if (fbqTrackConfig) {
1274
- trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
1275
- }
1276
- }
1277
- if (redirectToCheckout) {
1278
- if (resultCart.url) {
1279
- if (typeof window !== "undefined") {
1280
- window.location.href = resultCart.url;
1281
- }
1282
- } else {
1283
- throw new Error("Failed to get checkout URL");
1284
- }
1285
- }
1286
- return resultCart;
1287
- },
1288
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
1289
- );
1290
- return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
1291
- }
1292
1044
  function useCalcGiftsFromLines({
1293
1045
  lines,
1294
1046
  customer,
@@ -1460,47 +1212,6 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1460
1212
  isLoading: isCustomerLoading
1461
1213
  };
1462
1214
  };
1463
- function hasPlusMemberInCart({
1464
- memberSetting,
1465
- cart
1466
- }) {
1467
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1468
- if (!cart?.lineItems) {
1469
- return {
1470
- hasPlusMember: false,
1471
- hasMonthlyPlus: false,
1472
- hasAnnualPlus: false
1473
- };
1474
- }
1475
- const monthlyPlusItem = cart.lineItems.find(
1476
- (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1477
- );
1478
- const annualPlusItem = cart.lineItems.find(
1479
- (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1480
- );
1481
- const hasMonthlyPlus = !!monthlyPlusItem;
1482
- const hasAnnualPlus = !!annualPlusItem;
1483
- const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1484
- return {
1485
- hasPlusMember,
1486
- hasMonthlyPlus,
1487
- hasAnnualPlus,
1488
- monthlyPlusItem,
1489
- annualPlusItem
1490
- };
1491
- }
1492
- function useHasPlusMemberInCart({
1493
- memberSetting,
1494
- cart
1495
- }) {
1496
- return react.useMemo(
1497
- () => hasPlusMemberInCart({
1498
- memberSetting,
1499
- cart
1500
- }),
1501
- [memberSetting, cart]
1502
- );
1503
- }
1504
1215
  var getReferralAttributes = () => {
1505
1216
  const inviteCode = shopifySdk.getLocalStorage("inviteCode") || Cookies5__default.default.get("inviteCode");
1506
1217
  const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
@@ -1517,158 +1228,130 @@ var getReferralAttributes = () => {
1517
1228
  }
1518
1229
  return [];
1519
1230
  };
1231
+ var getUserType = (customer) => {
1232
+ let userInfo = Cookies5__default.default.get("userInfo");
1233
+ if (userInfo) {
1234
+ userInfo = JSON.parse(userInfo);
1235
+ let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1236
+ userInfo.setId = arr[arr.length - 1];
1237
+ }
1238
+ const customerInfo = userInfo || customer;
1239
+ if (!customerInfo) {
1240
+ return "new_user_unlogin";
1241
+ }
1242
+ if (customer) {
1243
+ const { orders = {} } = customer;
1244
+ if (orders?.edges?.length === 1) {
1245
+ return "old_user_orders_once";
1246
+ } else if (orders?.edges?.length > 1) {
1247
+ return "old_user_orders_twice";
1248
+ }
1249
+ }
1250
+ return "new_user_login";
1251
+ };
1252
+ function getCartAttributes({
1253
+ profile,
1254
+ customer,
1255
+ cart,
1256
+ memberType,
1257
+ currentUrl = ""
1258
+ }) {
1259
+ const userType = getUserType(customer);
1260
+ const memberAttributes = [
1261
+ {
1262
+ key: "_token",
1263
+ value: profile?.token
1264
+ },
1265
+ {
1266
+ key: "_member_type",
1267
+ value: memberType ?? String(profile?.memberType || 0)
1268
+ },
1269
+ {
1270
+ key: "_user_type",
1271
+ value: userType
1272
+ },
1273
+ {
1274
+ key: "_is_login",
1275
+ value: profile?.token ? "true" : "false"
1276
+ }
1277
+ ];
1278
+ if (profile?.token) {
1279
+ memberAttributes.push({
1280
+ key: "_login_user",
1281
+ value: "1"
1282
+ });
1283
+ }
1284
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1285
+ const functionAttributes = [
1286
+ {
1287
+ key: CUSTOMER_ATTRIBUTE_KEY,
1288
+ value: JSON.stringify({
1289
+ discount_code: discountCodes,
1290
+ user_tags: customer?.tags || []
1291
+ })
1292
+ }
1293
+ ];
1294
+ const presellAttributes = [
1295
+ {
1296
+ key: "_presale",
1297
+ value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1298
+ }
1299
+ ];
1300
+ const weightAttributes = [
1301
+ {
1302
+ key: "_weight",
1303
+ value: cart?.lineItems.reduce((acc, item) => {
1304
+ return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1305
+ }, 0).toString()
1306
+ },
1307
+ {
1308
+ key: "_app_source_name",
1309
+ value: "dtc"
1310
+ }
1311
+ ];
1312
+ const trackingAttributes = [
1313
+ {
1314
+ key: "utm_params",
1315
+ value: currentUrl
1316
+ }
1317
+ ];
1318
+ const commonAttributes = [
1319
+ ...memberAttributes,
1320
+ ...functionAttributes,
1321
+ ...presellAttributes,
1322
+ ...weightAttributes,
1323
+ ...trackingAttributes,
1324
+ ...getReferralAttributes()
1325
+ ].filter((item) => item?.value);
1326
+ const extraAttributesInCart = cart?.customAttributes?.filter(
1327
+ (item) => !commonAttributes.some((attr) => attr.key === item.key)
1328
+ ) || [];
1329
+ return [...commonAttributes, ...extraAttributesInCart].filter((item) => item?.value);
1330
+ }
1520
1331
  var useCartAttributes = ({
1521
1332
  profile,
1522
1333
  customer,
1523
1334
  cart,
1524
- memberSetting
1335
+ memberType
1525
1336
  }) => {
1526
1337
  const [currentUrl, setCurrentUrl] = react.useState("");
1527
- const { hasPlusMember } = useHasPlusMemberInCart({
1528
- memberSetting,
1529
- cart
1530
- });
1531
1338
  react.useEffect(() => {
1532
1339
  setCurrentUrl(window.location.href);
1533
1340
  }, []);
1534
- const userType = react.useMemo(() => {
1535
- let userInfo = Cookies5__default.default.get("userInfo");
1536
- if (userInfo) {
1537
- userInfo = JSON.parse(userInfo);
1538
- let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1539
- userInfo.setId = arr[arr.length - 1];
1540
- }
1541
- const customerInfo = userInfo || customer;
1542
- if (!customerInfo) {
1543
- return "new_user_unlogin";
1544
- }
1545
- if (customer) {
1546
- const { orders = {} } = customer;
1547
- if (orders?.edges?.length === 1) {
1548
- return "old_user_orders_once";
1549
- } else if (orders?.edges?.length > 1) {
1550
- return "old_user_orders_twice";
1551
- }
1552
- }
1553
- return "new_user_login";
1554
- }, [customer]);
1555
- const memberAttributes = react.useMemo(() => {
1556
- const attributes = [
1557
- {
1558
- key: "_token",
1559
- value: profile?.token
1560
- //是否登录
1561
- },
1562
- {
1563
- key: "_member_type",
1564
- value: hasPlusMember ? "2" : profile?.memberType
1565
- //:0(游客),1(普通会员),2(付费会员)
1566
- },
1567
- {
1568
- key: "_user_type",
1569
- value: userType
1570
- // n
1571
- },
1572
- {
1573
- key: "_is_login",
1574
- value: profile?.token ? "true" : "false"
1575
- }
1576
- ];
1577
- if (profile?.token) {
1578
- attributes.push({
1579
- key: "_login_user",
1580
- value: "1"
1581
- });
1582
- }
1583
- return attributes;
1584
- }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1585
- const functionAttributes = react.useMemo(() => {
1586
- const hasFunctionEnvAttribute = cart?.lineItems.some(
1587
- (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1588
- );
1589
- const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1590
- return hasFunctionEnvAttribute ? [
1591
- {
1592
- key: "_discounts_function_env",
1593
- value: JSON.stringify({
1594
- discount_code: discountCodes,
1595
- user_tags: customer?.tags || []
1596
- })
1597
- }
1598
- ] : [];
1599
- }, [cart, customer]);
1600
- const presellAttributes = react.useMemo(() => {
1601
- return [
1602
- {
1603
- key: "_presale",
1604
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1605
- }
1606
- ];
1607
- }, [cart]);
1608
- const weightAttributes = react.useMemo(() => {
1609
- return [
1610
- {
1611
- key: "_weight",
1612
- value: cart?.lineItems.reduce((acc, item) => {
1613
- return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1614
- }, 0).toString()
1615
- },
1616
- {
1617
- key: "_app_source_name",
1618
- value: "dtc"
1619
- }
1620
- ];
1621
- }, [cart]);
1622
- const trackingAttributes = react.useMemo(() => {
1623
- return [
1624
- {
1625
- key: "utm_params",
1626
- value: currentUrl
1627
- }
1628
- ];
1629
- }, [currentUrl]);
1630
- const commonAttributes = react.useMemo(
1631
- () => [
1632
- ...memberAttributes,
1633
- ...functionAttributes,
1634
- ...presellAttributes,
1635
- ...weightAttributes,
1636
- ...trackingAttributes,
1637
- ...getReferralAttributes()
1638
- ].filter((item) => item?.value),
1639
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1640
- );
1641
- const extraAttributesInCart = react.useMemo(() => {
1642
- const commonAttributeKeys = [
1643
- // member attributes
1644
- "_token",
1645
- "_member_type",
1646
- "_user_type",
1647
- "_is_login",
1648
- "_login_user",
1649
- // function attributes
1650
- "_discounts_function_env",
1651
- // presell attributes
1652
- "_presale",
1653
- // weight attributes
1654
- "_weight",
1655
- "_app_source_name",
1656
- // tracking attributes
1657
- "utm_params",
1658
- // referral attributes
1659
- "_invite_code",
1660
- "_play_mode_id",
1661
- "_popup"
1662
- ];
1663
- return cart?.customAttributes?.filter((item) => !commonAttributeKeys.includes(item.key)) || [];
1664
- }, [cart]);
1341
+ const attributes = react.useMemo(() => {
1342
+ return getCartAttributes({
1343
+ profile,
1344
+ customer,
1345
+ cart,
1346
+ memberType,
1347
+ currentUrl
1348
+ });
1349
+ }, [profile, customer, cart, memberType, currentUrl]);
1665
1350
  return react.useMemo(
1666
1351
  () => ({
1667
- attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1668
- (item) => item?.value
1669
- )
1352
+ attributes
1670
1353
  }),
1671
- [commonAttributes, extraAttributesInCart]
1354
+ [attributes]
1672
1355
  );
1673
1356
  };
1674
1357
  var DEFAULT_MIN = 1;
@@ -1705,6 +1388,51 @@ var useCartItemQuantityLimit = ({
1705
1388
  }, [cartItem, cart]);
1706
1389
  return quantityLimit;
1707
1390
  };
1391
+ function hasPlusMemberInLines({
1392
+ memberSetting,
1393
+ lines
1394
+ }) {
1395
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1396
+ if (!lines || lines.length === 0) {
1397
+ return {
1398
+ hasPlusMember: false,
1399
+ hasMonthlyPlus: false,
1400
+ hasAnnualPlus: false
1401
+ };
1402
+ }
1403
+ const monthlyPlusLine = lines.find((line) => {
1404
+ const variantHandle = line.variant?.product?.handle;
1405
+ const variantSku = line.variant?.sku;
1406
+ return variantHandle === plus_monthly_product?.handle && variantSku === plus_monthly_product?.sku;
1407
+ });
1408
+ const annualPlusLine = lines.find((line) => {
1409
+ const variantHandle = line.variant?.product?.handle;
1410
+ const variantSku = line.variant?.sku;
1411
+ return variantHandle === plus_annual_product?.handle && variantSku === plus_annual_product?.sku;
1412
+ });
1413
+ const hasMonthlyPlus = !!monthlyPlusLine;
1414
+ const hasAnnualPlus = !!annualPlusLine;
1415
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1416
+ return {
1417
+ hasPlusMember,
1418
+ hasMonthlyPlus,
1419
+ hasAnnualPlus,
1420
+ monthlyPlusLine,
1421
+ annualPlusLine
1422
+ };
1423
+ }
1424
+ function useHasPlusMemberInLines({
1425
+ memberSetting,
1426
+ lines
1427
+ }) {
1428
+ return react.useMemo(
1429
+ () => hasPlusMemberInLines({
1430
+ memberSetting,
1431
+ lines
1432
+ }),
1433
+ [memberSetting, lines]
1434
+ );
1435
+ }
1708
1436
  var useUpdateLineCodeAmountAttributes = ({
1709
1437
  cart,
1710
1438
  mutateCart,
@@ -1820,45 +1548,61 @@ var useUpdateLineCodeAmountAttributes = ({
1820
1548
  }, [loading, setLoadingState]);
1821
1549
  };
1822
1550
 
1823
- // src/hooks/cart/types/price-discount.ts
1824
- var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
1825
- PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1826
- PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1827
- return PriceDiscountType2;
1828
- })(PriceDiscountType || {});
1829
- var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
1830
- PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
1831
- PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
1832
- return PriceBasePriceType2;
1833
- })(PriceBasePriceType || {});
1834
- function useProduct(options = {}) {
1835
- const { client, locale } = useShopify();
1836
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
1837
- return useSWR__default.default(
1838
- handle ? ["product", locale, handle, metafieldIdentifiers] : null,
1839
- () => shopifySdk.getProduct(client, {
1840
- handle,
1841
- locale,
1842
- metafieldIdentifiers
1843
- }),
1844
- swrOptions
1845
- );
1846
- }
1847
- function useAllProducts(options = {}) {
1848
- const { client, locale } = useShopify();
1849
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
1850
- return useSWR__default.default(
1851
- ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
1852
- () => shopifySdk.getAllProducts(client, {
1853
- locale,
1854
- first,
1855
- query,
1856
- sortKey,
1857
- reverse,
1858
- metafieldIdentifiers
1859
- }),
1860
- swrOptions
1861
- );
1551
+ // src/hooks/member/plus/types.ts
1552
+ var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
1553
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
1554
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
1555
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
1556
+ return PLUS_MEMBER_TYPE2;
1557
+ })(PLUS_MEMBER_TYPE || {});
1558
+ var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
1559
+ PlusMemberMode2["MONTHLY"] = "monthly";
1560
+ PlusMemberMode2["ANNUAL"] = "annual";
1561
+ return PlusMemberMode2;
1562
+ })(PlusMemberMode || {});
1563
+ var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
1564
+ DeliveryPlusType2["FREE"] = "free";
1565
+ DeliveryPlusType2["MONTHLY"] = "monthly";
1566
+ DeliveryPlusType2["ANNUAL"] = "annual";
1567
+ return DeliveryPlusType2;
1568
+ })(DeliveryPlusType || {});
1569
+ var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
1570
+ ShippingMethodMode2["FREE"] = "free";
1571
+ ShippingMethodMode2["TDD"] = "tdd";
1572
+ ShippingMethodMode2["NDD"] = "ndd";
1573
+ return ShippingMethodMode2;
1574
+ })(ShippingMethodMode || {});
1575
+ var createInitialValue = () => ({
1576
+ plusMemberMetafields: {},
1577
+ selectedPlusMemberMode: "free",
1578
+ setSelectedPlusMemberMode: () => {
1579
+ },
1580
+ selectedShippingMethod: void 0,
1581
+ setSelectedShippingMethod: () => {
1582
+ },
1583
+ showMoreShippingMethod: false,
1584
+ setShowMoreShippingMethod: () => {
1585
+ },
1586
+ variant: {},
1587
+ product: {},
1588
+ shippingMethodsContext: {
1589
+ freeShippingMethods: [],
1590
+ paymentShippingMethods: [],
1591
+ nddOverweight: false,
1592
+ tddOverweight: false,
1593
+ nddCoupon: void 0,
1594
+ tddCoupon: void 0,
1595
+ isLoadingCoupon: false
1596
+ },
1597
+ selectedPlusMemberVariant: void 0,
1598
+ showPlusMemberBenefit: false,
1599
+ setShowPlusMemberBenefit: () => {
1600
+ },
1601
+ profile: void 0
1602
+ });
1603
+ var PlusMemberContext = react.createContext(createInitialValue());
1604
+ function usePlusMemberContext() {
1605
+ return react.useContext(PlusMemberContext);
1862
1606
  }
1863
1607
  function useProductsByHandles(options = {}) {
1864
1608
  const { client, locale } = useShopify();
@@ -1884,994 +1628,1298 @@ function useProductsByHandles(options = {}) {
1884
1628
  }
1885
1629
  );
1886
1630
  }
1887
- function getFirstAvailableVariant(product) {
1888
- const availableVariant = product.variants.find((v) => v.availableForSale);
1889
- return availableVariant || product.variants[0];
1890
- }
1891
- function getVariantFromSelectedOptions(product, selectedOptions) {
1892
- return product.variants.find((variant) => {
1893
- return variant.selectedOptions.every((option) => {
1894
- return selectedOptions[option.name] === option.value;
1895
- });
1896
- });
1897
- }
1898
- function useVariant({
1899
- product,
1900
- selectedOptions
1631
+
1632
+ // src/hooks/member/plus/use-plus-member-variants.ts
1633
+ function usePlusMemberVariants({
1634
+ memberSetting
1901
1635
  }) {
1902
- const [variant, setVariant] = react.useState(
1903
- product ? getFirstAvailableVariant(product) : void 0
1904
- );
1905
- react.useEffect(() => {
1906
- if (!product) {
1907
- setVariant(void 0);
1908
- return;
1909
- }
1910
- const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
1911
- if (newVariant && newVariant.id !== variant?.id) {
1912
- setVariant(newVariant);
1913
- } else if (!newVariant) {
1914
- setVariant(getFirstAvailableVariant(product));
1915
- }
1916
- }, [selectedOptions, product, variant?.id]);
1917
- return variant;
1918
- }
1919
- var FAKE_PRICE = 999999999e-2;
1920
- function formatPrice({
1921
- amount,
1922
- currencyCode,
1923
- locale,
1924
- maximumFractionDigits,
1925
- minimumFractionDigits,
1926
- removeTrailingZeros
1927
- }) {
1928
- const formatter = new Intl.NumberFormat(locale, {
1929
- style: "currency",
1930
- currency: currencyCode,
1931
- maximumFractionDigits: maximumFractionDigits ?? 2,
1932
- minimumFractionDigits: minimumFractionDigits ?? 2
1636
+ const plusMonthly = memberSetting?.plus_monthly_product;
1637
+ const plusAnnual = memberSetting?.plus_annual_product;
1638
+ const plusMemberHandles = react.useMemo(() => {
1639
+ return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
1640
+ }, [plusMonthly?.handle, plusAnnual?.handle]);
1641
+ const { data: plusMemberProducts = [] } = useProductsByHandles({
1642
+ handles: plusMemberHandles
1933
1643
  });
1934
- let formatted = formatter.format(amount);
1935
- if (removeTrailingZeros) {
1936
- formatted = formatted.replace(/\.00$/, "");
1937
- }
1938
- return formatted;
1939
- }
1940
- function formatVariantPrice({
1941
- amount,
1942
- baseAmount,
1943
- currencyCode,
1944
- locale,
1945
- maximumFractionDigits,
1946
- minimumFractionDigits,
1947
- removeTrailingZeros
1948
- }) {
1644
+ const monthlyProduct = react.useMemo(() => {
1645
+ return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
1646
+ }, [plusMemberProducts, plusMonthly]);
1647
+ const annualProduct = react.useMemo(() => {
1648
+ return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
1649
+ }, [plusMemberProducts, plusAnnual]);
1650
+ const monthlyVariant = react.useMemo(() => {
1651
+ return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
1652
+ }, [monthlyProduct, plusMonthly]);
1653
+ const annualVariant = react.useMemo(() => {
1654
+ return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
1655
+ }, [annualProduct, plusAnnual]);
1949
1656
  return {
1950
- price: formatPrice({
1951
- amount,
1952
- currencyCode,
1953
- locale,
1954
- maximumFractionDigits,
1955
- minimumFractionDigits,
1956
- removeTrailingZeros
1957
- }),
1958
- basePrice: formatPrice({
1959
- amount: baseAmount,
1960
- currencyCode,
1961
- locale,
1962
- maximumFractionDigits,
1963
- minimumFractionDigits,
1964
- removeTrailingZeros
1965
- })
1657
+ monthlyVariant: monthlyVariant ? {
1658
+ ...monthlyVariant,
1659
+ product: monthlyProduct
1660
+ } : void 0,
1661
+ annualVariant: annualVariant ? {
1662
+ ...annualVariant,
1663
+ product: annualProduct
1664
+ } : void 0
1966
1665
  };
1967
1666
  }
1968
- function usePrice({
1969
- amount,
1970
- baseAmount,
1971
- currencyCode,
1972
- soldOutDescription = "",
1973
- maximumFractionDigits,
1974
- minimumFractionDigits,
1975
- removeTrailingZeros
1976
- }) {
1977
- const { locale } = useShopify();
1978
- const value = react.useMemo(() => {
1979
- if (typeof amount !== "number" || !currencyCode) {
1980
- return "";
1981
- }
1982
- if (soldOutDescription && amount >= FAKE_PRICE) {
1983
- return soldOutDescription;
1667
+ var useAvailableDeliveryCoupon = ({
1668
+ profile
1669
+ }) => {
1670
+ const { data: availableDeliveryCoupon, isLoading } = useSWR__default.default(
1671
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
1672
+ async ([apiPath]) => {
1673
+ return fetch(apiPath).then((res) => res.json());
1984
1674
  }
1985
- return baseAmount ? formatVariantPrice({
1986
- amount,
1987
- baseAmount,
1988
- currencyCode,
1989
- locale,
1990
- maximumFractionDigits,
1991
- minimumFractionDigits,
1992
- removeTrailingZeros
1993
- }) : formatPrice({
1994
- amount,
1995
- currencyCode,
1996
- locale,
1997
- maximumFractionDigits,
1998
- minimumFractionDigits,
1999
- removeTrailingZeros
1675
+ );
1676
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
1677
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
1678
+ return {
1679
+ nddCoupon,
1680
+ tddCoupon,
1681
+ isLoading
1682
+ };
1683
+ };
1684
+
1685
+ // src/hooks/member/plus/use-shipping-methods.ts
1686
+ function useShippingMethods(options) {
1687
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
1688
+ const isPlus = profile?.isPlus || false;
1689
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
1690
+ const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
1691
+ const nddOverweight = react.useMemo(() => {
1692
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
1693
+ }, [shippingMethod?.overWeight_ndd, variant?.weight]);
1694
+ const tddOverweight = react.useMemo(() => {
1695
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
1696
+ }, [shippingMethod?.overWeight_tdd, variant?.weight]);
1697
+ const paymentShippingMethods = react.useMemo(() => {
1698
+ const weight = variant?.weight || 0;
1699
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
1700
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1701
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
1702
+ }) || [];
1703
+ return methods.map((method) => {
1704
+ let disabled = false;
1705
+ const selectedFreeMember = selectedPlusMemberMode === "free";
1706
+ if (method.__mode === "ndd" /* NDD */) {
1707
+ disabled = selectedFreeMember || nddOverweight;
1708
+ } else if (method.__mode === "tdd" /* TDD */) {
1709
+ disabled = selectedFreeMember || tddOverweight;
1710
+ }
1711
+ return {
1712
+ ...method,
1713
+ id: method.__mode + method.__code,
1714
+ useCoupon: false,
1715
+ subtitle: plus_shipping?.directly || "",
1716
+ disabled
1717
+ };
2000
1718
  });
2001
1719
  }, [
2002
- amount,
2003
- baseAmount,
2004
- currencyCode,
2005
- locale,
2006
- maximumFractionDigits,
2007
- minimumFractionDigits,
2008
- soldOutDescription,
2009
- removeTrailingZeros
1720
+ nddOverweight,
1721
+ plus_shipping?.directly,
1722
+ plus_shipping?.shipping_methods,
1723
+ selectedPlusMemberMode,
1724
+ tddOverweight,
1725
+ variant?.weight
2010
1726
  ]);
2011
- const result = react.useMemo(() => {
2012
- const free = Boolean(amount && amount <= 0);
2013
- return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
2014
- }, [value, amount]);
2015
- return result;
2016
- }
2017
- function optionsConstructor(selectedOptions) {
2018
- return selectedOptions.reduce((acc, option) => {
2019
- acc[option.name] = option.value;
2020
- return acc;
2021
- }, {});
2022
- }
2023
- function decodeShopifyId(gid) {
2024
- try {
2025
- const base64 = gid.split("/").pop() || "";
2026
- return atob(base64);
2027
- } catch {
2028
- return gid;
2029
- }
2030
- }
2031
- function useSelectedOptions(product, sku) {
2032
- const [options, setOptions] = react.useState({});
2033
- react.useEffect(() => {
2034
- if (!product || !product.variants.length) {
2035
- setOptions({});
2036
- return;
2037
- }
2038
- let variant = product.variants[0];
2039
- if (typeof window !== "undefined") {
2040
- const searchParams = new URLSearchParams(window.location.search);
2041
- const variantIdParam = searchParams.get("variant");
2042
- if (variantIdParam) {
2043
- const foundVariant = product.variants.find((v) => {
2044
- if (sku) return v.sku === sku;
2045
- return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
2046
- });
2047
- if (foundVariant) {
2048
- variant = foundVariant;
2049
- }
1727
+ const nddPrice = react.useMemo(() => {
1728
+ const weight = variant?.weight || 0;
1729
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1730
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1731
+ return __mode === "ndd" && fitWeight;
1732
+ });
1733
+ return nddMethod?.price || 0;
1734
+ }, [variant?.weight, paymentShippingMethods]);
1735
+ const tddPrice = react.useMemo(() => {
1736
+ const weight = variant?.weight || 0;
1737
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1738
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1739
+ return __mode === "tdd" && fitWeight;
1740
+ });
1741
+ return tddMethod?.price || 0;
1742
+ }, [variant?.weight, paymentShippingMethods]);
1743
+ const freeShippingMethods = react.useMemo(() => {
1744
+ const weight = variant?.weight || 0;
1745
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
1746
+ if (__mode === "free" /* FREE */) {
1747
+ return true;
2050
1748
  }
1749
+ if (isPlus) {
1750
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
1751
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1752
+ return hasCoupon && fitWeight && !__plus;
1753
+ } else {
1754
+ return __plus;
1755
+ }
1756
+ }) || [];
1757
+ if (isPlus) {
1758
+ methods = methods.sort((a, b) => {
1759
+ if (b.__mode === "free" /* FREE */) return -1;
1760
+ return 0;
1761
+ });
2051
1762
  }
2052
- if (variant) {
2053
- const newOptions = optionsConstructor(variant.selectedOptions);
2054
- setOptions(newOptions);
2055
- }
2056
- }, [product, sku]);
2057
- return [options, setOptions];
2058
- }
2059
- function decodeShopifyId2(gid) {
2060
- try {
2061
- const parts = gid.split("/");
2062
- return parts[parts.length - 1] || gid;
2063
- } catch {
2064
- return gid;
2065
- }
2066
- }
2067
- function useProductUrl(otherQuery) {
2068
- const { routerAdapter } = useShopify();
2069
- return react.useCallback(
2070
- ({ product, variant }) => {
2071
- if (!product) return "";
2072
- const queryParams = new URLSearchParams();
2073
- if (variant?.id) {
2074
- const variantId = decodeShopifyId2(variant.id);
2075
- if (variantId) {
2076
- queryParams.set("variant", variantId);
1763
+ return methods.map((method) => {
1764
+ let price = 0;
1765
+ let coupon;
1766
+ let disabled;
1767
+ if (method.__mode !== "free" /* FREE */) {
1768
+ switch (method.__mode) {
1769
+ case "tdd":
1770
+ price = tddPrice;
1771
+ coupon = tddCoupon || nddCoupon;
1772
+ break;
1773
+ case "ndd":
1774
+ price = nddPrice;
1775
+ coupon = nddCoupon;
1776
+ break;
1777
+ }
1778
+ disabled = selectedPlusMemberMode === "free";
1779
+ if (method.__mode === "ndd" /* NDD */) {
1780
+ disabled = disabled || nddOverweight;
1781
+ } else if (method.__mode === "tdd" /* TDD */) {
1782
+ disabled = disabled || tddOverweight;
2077
1783
  }
2078
1784
  }
2079
- if (otherQuery) {
2080
- Object.entries(otherQuery).forEach(([key, value]) => {
2081
- queryParams.set(key, value);
2082
- });
1785
+ return {
1786
+ ...method,
1787
+ id: method.__mode + method.__code,
1788
+ useCoupon: true,
1789
+ disabled,
1790
+ coupon,
1791
+ price
1792
+ };
1793
+ });
1794
+ }, [
1795
+ variant?.weight,
1796
+ plus_shipping?.shipping_methods,
1797
+ isPlus,
1798
+ nddCoupon,
1799
+ tddCoupon,
1800
+ selectedPlusMemberMode,
1801
+ tddPrice,
1802
+ nddPrice,
1803
+ nddOverweight,
1804
+ tddOverweight
1805
+ ]);
1806
+ return {
1807
+ freeShippingMethods,
1808
+ paymentShippingMethods,
1809
+ nddOverweight,
1810
+ tddOverweight,
1811
+ nddCoupon,
1812
+ tddCoupon,
1813
+ isLoadingCoupon: isLoading
1814
+ };
1815
+ }
1816
+ var useReplaceCartPlusMember = () => {
1817
+ const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
1818
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1819
+ const { cart } = useCartContext();
1820
+ const plusMonthly = plusMemberMetafields?.plus_monthly_product;
1821
+ const plusAnnual = plusMemberMetafields?.plus_annual_product;
1822
+ const handler = react.useCallback(async () => {
1823
+ const plusMonthlyInCart = cart?.lineItems.find(
1824
+ (item) => item.variant?.sku === plusMonthly?.sku
1825
+ );
1826
+ const plusAnnualInCart = cart?.lineItems.find(
1827
+ (item) => item.variant?.sku === plusAnnual?.sku
1828
+ );
1829
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
1830
+ await removeCartLines2({
1831
+ lineIds: [plusMonthlyInCart.id]
1832
+ });
1833
+ } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
1834
+ await removeCartLines2({
1835
+ lineIds: [plusAnnualInCart.id]
1836
+ });
1837
+ }
1838
+ }, [
1839
+ cart?.lineItems,
1840
+ selectedPlusMemberMode,
1841
+ plusMonthly?.sku,
1842
+ plusAnnual?.sku,
1843
+ removeCartLines2
1844
+ ]);
1845
+ return handler;
1846
+ };
1847
+ var usePlusMemberCheckoutCustomAttributes = ({
1848
+ disableShipping = false,
1849
+ isPresaleContains = false
1850
+ }) => {
1851
+ const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
1852
+ return react.useMemo(() => {
1853
+ const checkoutCustomAttributes = [
1854
+ {
1855
+ key: "_last_url",
1856
+ value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2083
1857
  }
2084
- const queryString = queryParams.toString();
2085
- const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
2086
- if (routerAdapter?.getLocalizedPath) {
2087
- return routerAdapter.getLocalizedPath(path);
1858
+ ];
1859
+ checkoutCustomAttributes.push({
1860
+ key: "_checkout_delivery_custom",
1861
+ value: JSON.stringify({
1862
+ allow_nextday_delivery: true,
1863
+ allow_thirdday_delivery: true,
1864
+ selected_delivery_option: {
1865
+ code: selectedShippingMethod?.__code,
1866
+ mode: selectedShippingMethod?.__mode
1867
+ },
1868
+ is_presale: isPresaleContains,
1869
+ discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
1870
+ plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
1871
+ is_prime: profile?.isPlus
1872
+ })
1873
+ });
1874
+ if (disableShipping) {
1875
+ checkoutCustomAttributes.push({
1876
+ key: "_hide_shipping",
1877
+ value: "true"
1878
+ });
1879
+ }
1880
+ return checkoutCustomAttributes;
1881
+ }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1882
+ };
1883
+ function useRemoveCartLines(options) {
1884
+ const { client, locale, cartCookieAdapter } = useShopify();
1885
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1886
+ const removeLines = react.useCallback(
1887
+ async (_key, { arg }) => {
1888
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1889
+ let updatedCart = await shopifySdk.removeCartLines(client, {
1890
+ cartId,
1891
+ lineIds,
1892
+ metafieldIdentifiers,
1893
+ cookieAdapter: cartCookieAdapter
1894
+ });
1895
+ if (updatedCart && autoRemoveInvalidCodes) {
1896
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1897
+ if (unApplicableCodes.length > 0) {
1898
+ if (onCodesRemoved) {
1899
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1900
+ if (handledCart) {
1901
+ updatedCart = handledCart;
1902
+ }
1903
+ } else {
1904
+ updatedCart = await shopifySdk.updateCartCodes(client, {
1905
+ cartId: updatedCart.id,
1906
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1907
+ metafieldIdentifiers,
1908
+ cookieAdapter: cartCookieAdapter
1909
+ }) || updatedCart;
1910
+ }
1911
+ }
2088
1912
  }
2089
- return path;
1913
+ if (updatedCart) {
1914
+ mutateCart(updatedCart);
1915
+ }
1916
+ return updatedCart;
2090
1917
  },
2091
- [routerAdapter, otherQuery]
1918
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2092
1919
  );
1920
+ return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
2093
1921
  }
2094
- function decodeShopifyId3(gid) {
2095
- try {
2096
- const parts = gid.split("/");
2097
- return parts[parts.length - 1] || gid;
2098
- } catch {
2099
- return gid;
2100
- }
2101
- }
2102
- function useUpdateVariantQuery(variant) {
1922
+
1923
+ // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1924
+ function useAutoRemovePlusMemberInCart({
1925
+ cart,
1926
+ profile,
1927
+ memberSetting
1928
+ }) {
1929
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1930
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
2103
1931
  react.useEffect(() => {
2104
- if (!variant || typeof window === "undefined") {
2105
- return;
1932
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
1933
+ const removePlusProduct = async (productType) => {
1934
+ if (!productType) return;
1935
+ const product = cart.lineItems?.find(
1936
+ (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
1937
+ );
1938
+ if (product) {
1939
+ await removeCartLines2({
1940
+ lineIds: [product.id]
1941
+ });
1942
+ }
1943
+ };
1944
+ if (profile?.isMonthlyPlus) {
1945
+ removePlusProduct(plus_monthly_product);
2106
1946
  }
2107
- const searchParams = new URLSearchParams(window.location.search);
2108
- const currentVariantId = searchParams.get("variant");
2109
- const newVariantId = decodeShopifyId3(variant.id);
2110
- if (newVariantId && currentVariantId !== newVariantId) {
2111
- searchParams.set("variant", newVariantId);
2112
- const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
2113
- window.history.replaceState({}, "", newUrl);
1947
+ if (profile?.isAnnualPlus) {
1948
+ removePlusProduct(plus_annual_product);
2114
1949
  }
2115
- }, [variant]);
1950
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2116
1951
  }
2117
- function getVariantMediaList({
2118
- product,
2119
- variant
1952
+ function hasPlusMemberInCart({
1953
+ memberSetting,
1954
+ cart
2120
1955
  }) {
2121
- if (variant.image?.url) {
2122
- const variantMediaId = variant.image.url;
2123
- const variantMedia = product.media.filter((media) => {
2124
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
2125
- return media.previewImage?.url === variantMediaId;
2126
- }
2127
- return false;
2128
- });
2129
- if (variantMedia.length > 0) {
2130
- const otherMedia = product.media.filter((media) => {
2131
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
2132
- return media.previewImage.url !== variantMediaId;
2133
- }
2134
- return true;
2135
- });
2136
- return [...variantMedia, ...otherMedia];
2137
- }
1956
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1957
+ if (!cart?.lineItems) {
1958
+ return {
1959
+ hasPlusMember: false,
1960
+ hasMonthlyPlus: false,
1961
+ hasAnnualPlus: false
1962
+ };
2138
1963
  }
2139
- return product.media;
2140
- }
2141
- function useVariantMedia({
2142
- product,
2143
- variant
2144
- }) {
2145
- const [imageList, setImageList] = react.useState([]);
2146
- const [sceneList, setSceneList] = react.useState([]);
2147
- const [videoList, setVideoList] = react.useState([]);
2148
- react.useEffect(() => {
2149
- if (!product || !variant) {
2150
- setImageList([]);
2151
- setSceneList([]);
2152
- setVideoList([]);
2153
- return;
2154
- }
2155
- const mediaList = getVariantMediaList({ product, variant });
2156
- const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
2157
- const videos = mediaList.filter(
2158
- (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
2159
- );
2160
- setImageList(images.length > 0 && images[0] ? [images[0]] : []);
2161
- setSceneList(images.length > 1 ? images.slice(1) : []);
2162
- setVideoList(videos);
2163
- }, [product, variant]);
2164
- return {
2165
- productList: imageList,
2166
- sceneList,
2167
- videoList
2168
- };
2169
- }
2170
- function useCollection(options = {}) {
2171
- const { client, locale } = useShopify();
2172
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2173
- return useSWR__default.default(
2174
- handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2175
- () => shopifySdk.getCollection(client, {
2176
- handle,
2177
- locale,
2178
- metafieldIdentifiers
2179
- }),
2180
- swrOptions
2181
- );
2182
- }
2183
- function useAllCollections(options = {}) {
2184
- const { client, locale } = useShopify();
2185
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2186
- return useSWR__default.default(
2187
- ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2188
- () => shopifySdk.getAllCollections(client, {
2189
- locale,
2190
- first,
2191
- query,
2192
- sortKey,
2193
- reverse,
2194
- metafieldIdentifiers
2195
- }),
2196
- swrOptions
2197
- );
2198
- }
2199
- function useCollections(options = {}) {
2200
- const { client, locale } = useShopify();
2201
- const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2202
- return useSWR__default.default(
2203
- ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2204
- () => shopifySdk.getCollections(client, {
2205
- locale,
2206
- first,
2207
- after,
2208
- query,
2209
- sortKey,
2210
- reverse,
2211
- metafieldIdentifiers
2212
- }),
2213
- swrOptions
1964
+ const monthlyPlusItem = cart.lineItems.find(
1965
+ (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
2214
1966
  );
2215
- }
2216
- function useBlog(options = {}) {
2217
- const { client, locale } = useShopify();
2218
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2219
- return useSWR__default.default(
2220
- handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2221
- () => shopifySdk.getBlog(client, { handle, locale, metafieldIdentifiers }),
2222
- swrOptions
1967
+ const annualPlusItem = cart.lineItems.find(
1968
+ (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
2223
1969
  );
1970
+ const hasMonthlyPlus = !!monthlyPlusItem;
1971
+ const hasAnnualPlus = !!annualPlusItem;
1972
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1973
+ return {
1974
+ hasPlusMember,
1975
+ hasMonthlyPlus,
1976
+ hasAnnualPlus,
1977
+ monthlyPlusItem,
1978
+ annualPlusItem
1979
+ };
2224
1980
  }
2225
- function useAllBlogs(options = {}) {
2226
- const { client, locale } = useShopify();
2227
- const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2228
- return useSWR__default.default(
2229
- ["all-blogs", locale, first, query, metafieldIdentifiers],
2230
- () => shopifySdk.getAllBlogs(client, {
2231
- locale,
2232
- first,
2233
- query,
2234
- metafieldIdentifiers
1981
+ function useHasPlusMemberInCart({
1982
+ memberSetting,
1983
+ cart
1984
+ }) {
1985
+ return react.useMemo(
1986
+ () => hasPlusMemberInCart({
1987
+ memberSetting,
1988
+ cart
2235
1989
  }),
2236
- swrOptions
1990
+ [memberSetting, cart]
2237
1991
  );
2238
1992
  }
2239
- function useArticle(options = {}) {
2240
- const { client, locale } = useShopify();
2241
- const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2242
- return useSWR__default.default(
2243
- blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2244
- () => shopifySdk.getArticle(client, {
2245
- blogHandle,
2246
- articleHandle,
2247
- locale,
2248
- metafieldIdentifiers
2249
- }),
2250
- swrOptions
2251
- );
1993
+ function usePlusMemberNeedAddToCart({
1994
+ cart,
1995
+ profile
1996
+ }) {
1997
+ const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
1998
+ const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
1999
+ memberSetting: plusMemberMetafields,
2000
+ cart
2001
+ });
2002
+ const plusMemberVariant = react.useMemo(() => {
2003
+ if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
2004
+ return void 0;
2005
+ }
2006
+ if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2007
+ return void 0;
2008
+ }
2009
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2010
+ return void 0;
2011
+ }
2012
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2013
+ return void 0;
2014
+ }
2015
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2016
+ return void 0;
2017
+ }
2018
+ return selectedPlusMemberVariant;
2019
+ }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2020
+ return plusMemberVariant;
2252
2021
  }
2253
- function useArticles(options = {}) {
2254
- const { client, locale } = useShopify();
2255
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2256
- return useSWR__default.default(
2257
- ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2258
- () => shopifySdk.getArticles(client, {
2259
- locale,
2260
- first,
2261
- query,
2262
- sortKey,
2263
- reverse,
2264
- metafieldIdentifiers
2265
- }),
2266
- swrOptions
2022
+ var PlusMemberProvider = ({
2023
+ variant,
2024
+ product,
2025
+ memberSetting,
2026
+ initialSelectedPlusMemberMode = "free",
2027
+ profile,
2028
+ children
2029
+ }) => {
2030
+ const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2031
+ initialSelectedPlusMemberMode
2267
2032
  );
2268
- }
2269
- function useArticlesInBlog(options = {}) {
2270
- const { client, locale } = useShopify();
2271
- const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2272
- return useSWR__default.default(
2273
- blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2274
- () => shopifySdk.getArticlesInBlog(client, {
2275
- blogHandle,
2276
- locale,
2277
- first,
2278
- sortKey,
2279
- reverse,
2280
- metafieldIdentifiers
2281
- }),
2282
- swrOptions
2033
+ const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2034
+ const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2035
+ const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2036
+ const shippingMethodsContext = useShippingMethods({
2037
+ variant,
2038
+ plusMemberMetafields: memberSetting,
2039
+ selectedPlusMemberMode,
2040
+ profile
2041
+ });
2042
+ const { monthlyVariant, annualVariant } = usePlusMemberVariants({
2043
+ memberSetting
2044
+ });
2045
+ const selectedPlusMemberVariant = react.useMemo(() => {
2046
+ if (selectedPlusMemberMode === "free" /* FREE */) {
2047
+ return void 0;
2048
+ }
2049
+ return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
2050
+ }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
2051
+ return /* @__PURE__ */ jsxRuntime.jsx(
2052
+ PlusMemberContext.Provider,
2053
+ {
2054
+ value: {
2055
+ variant,
2056
+ plusMemberMetafields: memberSetting,
2057
+ selectedPlusMemberMode,
2058
+ setSelectedPlusMemberMode,
2059
+ selectedShippingMethod,
2060
+ setSelectedShippingMethod,
2061
+ shippingMethodsContext,
2062
+ showMoreShippingMethod,
2063
+ setShowMoreShippingMethod,
2064
+ selectedPlusMemberVariant,
2065
+ product,
2066
+ showPlusMemberBenefit,
2067
+ setShowPlusMemberBenefit,
2068
+ profile
2069
+ },
2070
+ children
2071
+ }
2283
2072
  );
2284
- }
2285
- async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2286
- if (!searchQuery) {
2287
- return void 0;
2288
- }
2289
- const query = (
2290
- /* GraphQL */
2291
- `
2292
- query search($query: String!, $first: Int!, $types: [SearchType!])
2293
- @inContext(language: $language) {
2294
- search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2295
- totalCount
2296
- edges {
2297
- node {
2298
- ... on Article {
2299
- __typename
2300
- id
2301
- handle
2302
- title
2303
- excerpt
2304
- image {
2305
- url
2306
- altText
2307
- }
2308
- }
2309
- ... on Page {
2310
- __typename
2311
- id
2312
- handle
2313
- title
2314
- }
2315
- ... on Product {
2316
- __typename
2317
- id
2318
- handle
2319
- title
2320
- description
2321
- featuredImage {
2322
- url
2323
- altText
2073
+ };
2074
+
2075
+ // src/hooks/cart/use-add-to-cart.ts
2076
+ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2077
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
2078
+ const { cart, addCustomAttributes, memberSetting, profile, customer } = useCartContext();
2079
+ const { trigger: applyCartCodes } = useApplyCartCodes();
2080
+ const { trigger: removeInvalidCodes } = useRemoveCartCodes();
2081
+ const { trigger: addCartLines2 } = useAddCartLines();
2082
+ const { trigger: createCart4 } = useCreateCart({
2083
+ updateCookie: true
2084
+ });
2085
+ const { hasPlusMember } = useHasPlusMemberInCart({
2086
+ memberSetting,
2087
+ cart
2088
+ });
2089
+ const { attributes: cartAttributes } = useCartAttributes({
2090
+ profile,
2091
+ customer,
2092
+ cart,
2093
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2094
+ });
2095
+ const addToCart = react.useCallback(
2096
+ async (_key, { arg }) => {
2097
+ const {
2098
+ lineItems,
2099
+ cartId: providedCartId,
2100
+ discountCodes,
2101
+ gtmParams = {},
2102
+ buyerIdentity,
2103
+ needCreateCart = false,
2104
+ onCodesInvalid,
2105
+ replaceExistingCodes,
2106
+ customAttributes
2107
+ } = arg;
2108
+ if (!lineItems || lineItems.length === 0) {
2109
+ return;
2110
+ }
2111
+ performanceAdapter?.addToCartStart();
2112
+ const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
2113
+ const lines = linesWithFunctionAttributes.map((item) => ({
2114
+ merchandiseId: item.variant?.id || "",
2115
+ quantity: item.quantity || 1,
2116
+ attributes: item.attributes,
2117
+ sellingPlanId: item.sellingPlanId
2118
+ })).filter((item) => item.merchandiseId && item.quantity);
2119
+ if (lines.length === 0) {
2120
+ return;
2121
+ }
2122
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
2123
+ let resultCart = null;
2124
+ if (!cartId) {
2125
+ resultCart = await createCart4({
2126
+ lines,
2127
+ buyerIdentity,
2128
+ discountCodes,
2129
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2130
+ // 初次加购时,就把所有 cart attributes 带上
2131
+ });
2132
+ } else {
2133
+ resultCart = await addCartLines2({
2134
+ cartId,
2135
+ lines
2136
+ });
2137
+ console.log("npm addCartLines resultCart", resultCart);
2138
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
2139
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
2140
+ if (unapplicableCodes.length > 0) {
2141
+ if (onCodesInvalid) {
2142
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
2143
+ if (handledCart) {
2144
+ resultCart = handledCart;
2324
2145
  }
2146
+ } else {
2147
+ await removeInvalidCodes({
2148
+ discountCodes: unapplicableCodes
2149
+ });
2325
2150
  }
2326
2151
  }
2327
2152
  }
2328
- pageInfo {
2329
- hasNextPage
2330
- endCursor
2153
+ if (resultCart && discountCodes && discountCodes.length > 0) {
2154
+ applyCartCodes({
2155
+ replaceExistingCodes,
2156
+ discountCodes
2157
+ });
2158
+ }
2159
+ if (customAttributes && customAttributes.length > 0) {
2160
+ addCustomAttributes(customAttributes);
2331
2161
  }
2332
2162
  }
2333
- }
2334
- `
2163
+ if (withTrack) {
2164
+ trackAddToCartGA({
2165
+ lineItems,
2166
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2167
+ });
2168
+ trackAddToCartFBQ({ lineItems });
2169
+ }
2170
+ performanceAdapter?.addToCartEnd();
2171
+ return resultCart;
2172
+ },
2173
+ [
2174
+ client,
2175
+ locale,
2176
+ cartCookieAdapter,
2177
+ userAdapter,
2178
+ cart,
2179
+ withTrack,
2180
+ performanceAdapter,
2181
+ createCart4,
2182
+ addCartLines2,
2183
+ applyCartCodes,
2184
+ removeInvalidCodes,
2185
+ addCustomAttributes,
2186
+ config
2187
+ ]
2335
2188
  );
2336
- const data = await client.query(query, {
2337
- query: searchQuery,
2338
- first,
2339
- types
2340
- });
2341
- if (!data || !data.search) {
2342
- return void 0;
2343
- }
2344
- const items = data.search.edges?.map((edge) => {
2345
- const node = edge.node;
2346
- const item = {
2347
- type: node.__typename.toUpperCase(),
2348
- id: node.id,
2349
- handle: node.handle,
2350
- title: node.title
2351
- };
2352
- if (node.__typename === "Product") {
2353
- item.description = node.description;
2354
- item.image = node.featuredImage ? {
2355
- url: node.featuredImage.url,
2356
- altText: node.featuredImage.altText
2357
- } : void 0;
2358
- } else if (node.__typename === "Article") {
2359
- item.description = node.excerpt;
2360
- item.image = node.image ? {
2361
- url: node.image.url,
2362
- altText: node.image.altText
2363
- } : void 0;
2364
- }
2365
- return item;
2366
- }) || [];
2367
- return {
2368
- items,
2369
- totalCount: data.search.totalCount || 0,
2370
- pageInfo: data.search.pageInfo
2371
- };
2189
+ return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
2372
2190
  }
2373
- function useSearch(options = {}) {
2374
- const { client, locale } = useShopify();
2375
- const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2376
- return useSWR__default.default(
2377
- query ? ["search", locale, query, first, types] : null,
2378
- () => performSearch(client, locale, query, first, types),
2379
- swrOptions
2191
+ function useUpdateCartLines(options) {
2192
+ const { client, locale, cartCookieAdapter } = useShopify();
2193
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
2194
+ const updateLines = react.useCallback(
2195
+ async (_key, { arg }) => {
2196
+ const updatedCart = await shopifySdk.updateCartLines(client, {
2197
+ ...arg,
2198
+ metafieldIdentifiers,
2199
+ cookieAdapter: cartCookieAdapter
2200
+ });
2201
+ if (updatedCart) {
2202
+ mutateCart(updatedCart);
2203
+ }
2204
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
2205
+ return updatedCart;
2206
+ },
2207
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2380
2208
  );
2209
+ return useSWRMutation__default.default("update-cart-lines", updateLines, options);
2381
2210
  }
2382
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
2383
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2384
- const query = (
2385
- /* GraphQL */
2386
- `
2387
- query getSiteInfo(
2388
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2389
- ) @inContext(language: $language) {
2390
- shop {
2391
- name
2392
- description
2393
- primaryDomain {
2394
- url
2395
- host
2396
- }
2397
- brand {
2398
- logo {
2399
- image {
2400
- url
2401
- }
2402
- }
2403
- colors {
2404
- primary {
2405
- background
2406
- }
2407
- secondary {
2408
- background
2409
- }
2410
- }
2411
- }
2412
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2211
+ function useUpdateCartAttributes({
2212
+ mutate,
2213
+ metafieldIdentifiers,
2214
+ disabled = false,
2215
+ swrOptions
2216
+ }) {
2217
+ const { client, locale, cartCookieAdapter } = useShopify();
2218
+ const updateAttributes = react.useCallback(
2219
+ async (_key, { arg }) => {
2220
+ if (disabled) {
2221
+ return void 0;
2413
2222
  }
2414
- }
2415
- `
2223
+ const updatedCart = await shopifySdk.updateCartAttributes(client, {
2224
+ ...arg,
2225
+ metafieldIdentifiers,
2226
+ cookieAdapter: cartCookieAdapter
2227
+ });
2228
+ if (updatedCart) {
2229
+ mutate(updatedCart);
2230
+ }
2231
+ return updatedCart;
2232
+ },
2233
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
2416
2234
  );
2417
- const variables = {};
2418
- if (hasMetafields) {
2419
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2420
- }
2421
- const data = await client.query(query, variables);
2422
- if (!data || !data.shop) {
2423
- return void 0;
2424
- }
2425
- const shop = data.shop;
2426
- const metafields = shop.metafields?.reduce((acc, mf) => {
2427
- if (mf && mf.key) {
2428
- acc[mf.key] = mf.value;
2429
- }
2430
- return acc;
2431
- }, {});
2432
- return {
2433
- name: shop.name,
2434
- description: shop.description,
2435
- primaryDomain: shop.primaryDomain,
2436
- brand: shop.brand ? {
2437
- logo: shop.brand.logo,
2438
- colors: shop.brand.colors ? {
2439
- primary: shop.brand.colors.primary?.background,
2440
- secondary: shop.brand.colors.secondary?.background
2441
- } : void 0
2442
- } : void 0,
2443
- metafields
2444
- };
2235
+ return useSWRMutation__default.default("update-cart-attributes", updateAttributes, swrOptions);
2445
2236
  }
2446
- function useSite(options = {}) {
2237
+ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2238
+ const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2239
+ const { profile, customer, memberSetting } = useCartContext();
2240
+ const isLoggedIn = userAdapter?.isLoggedIn || false;
2241
+ const buyNow = react.useCallback(
2242
+ async (_key, { arg }) => {
2243
+ const {
2244
+ lineItems,
2245
+ discountCodes,
2246
+ gtmParams = {},
2247
+ buyerIdentity,
2248
+ fbqTrackConfig,
2249
+ customAttributes,
2250
+ metafieldIdentifiers,
2251
+ redirectToCheckout
2252
+ } = arg;
2253
+ if (!lineItems || lineItems.length === 0) {
2254
+ return;
2255
+ }
2256
+ const { hasPlusMember } = useHasPlusMemberInLines({
2257
+ memberSetting,
2258
+ lines: lineItems
2259
+ });
2260
+ const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2261
+ const cartAttributes = getCartAttributes({
2262
+ profile,
2263
+ customer,
2264
+ memberType,
2265
+ currentUrl: window.location.href
2266
+ });
2267
+ const linesWithFunctionAttributes = getLinesWithAttributes({
2268
+ lineItems
2269
+ });
2270
+ const lines = linesWithFunctionAttributes.map((item) => ({
2271
+ merchandiseId: item.variant?.id || "",
2272
+ quantity: item.quantity || 1,
2273
+ attributes: item.attributes,
2274
+ sellingPlanId: item.sellingPlanId
2275
+ })).filter((item) => item.merchandiseId);
2276
+ if (lines.length === 0) {
2277
+ return;
2278
+ }
2279
+ const resultCart = await shopifySdk.createCart(client, {
2280
+ lines,
2281
+ metafieldIdentifiers,
2282
+ cookieAdapter: cartCookieAdapter,
2283
+ buyerIdentity,
2284
+ discountCodes,
2285
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2286
+ });
2287
+ if (!resultCart) {
2288
+ throw new Error("Failed to create cart for buy now");
2289
+ }
2290
+ if (withTrack && resultCart.lineItems) {
2291
+ trackBuyNowGA({
2292
+ lineItems,
2293
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2294
+ });
2295
+ if (fbqTrackConfig) {
2296
+ trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
2297
+ }
2298
+ }
2299
+ if (redirectToCheckout) {
2300
+ if (resultCart.url) {
2301
+ if (typeof window !== "undefined") {
2302
+ window.location.href = resultCart.url;
2303
+ }
2304
+ } else {
2305
+ throw new Error("Failed to get checkout URL");
2306
+ }
2307
+ }
2308
+ return resultCart;
2309
+ },
2310
+ [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
2311
+ );
2312
+ return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
2313
+ }
2314
+
2315
+ // src/hooks/cart/types/price-discount.ts
2316
+ var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
2317
+ PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
2318
+ PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
2319
+ return PriceDiscountType2;
2320
+ })(PriceDiscountType || {});
2321
+ var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
2322
+ PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
2323
+ PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
2324
+ return PriceBasePriceType2;
2325
+ })(PriceBasePriceType || {});
2326
+ function useProduct(options = {}) {
2447
2327
  const { client, locale } = useShopify();
2448
- const { metafieldIdentifiers, ...swrOptions } = options;
2328
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2449
2329
  return useSWR__default.default(
2450
- ["site", locale, metafieldIdentifiers],
2451
- () => getSiteInfo(client, locale, metafieldIdentifiers),
2330
+ handle ? ["product", locale, handle, metafieldIdentifiers] : null,
2331
+ () => shopifySdk.getProduct(client, {
2332
+ handle,
2333
+ locale,
2334
+ metafieldIdentifiers
2335
+ }),
2452
2336
  swrOptions
2453
2337
  );
2454
2338
  }
2455
-
2456
- // src/hooks/member/plus/types.ts
2457
- var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
2458
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
2459
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
2460
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
2461
- return PLUS_MEMBER_TYPE2;
2462
- })(PLUS_MEMBER_TYPE || {});
2463
- var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
2464
- PlusMemberMode2["MONTHLY"] = "monthly";
2465
- PlusMemberMode2["ANNUAL"] = "annual";
2466
- return PlusMemberMode2;
2467
- })(PlusMemberMode || {});
2468
- var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
2469
- DeliveryPlusType2["FREE"] = "free";
2470
- DeliveryPlusType2["MONTHLY"] = "monthly";
2471
- DeliveryPlusType2["ANNUAL"] = "annual";
2472
- return DeliveryPlusType2;
2473
- })(DeliveryPlusType || {});
2474
- var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
2475
- ShippingMethodMode2["FREE"] = "free";
2476
- ShippingMethodMode2["TDD"] = "tdd";
2477
- ShippingMethodMode2["NDD"] = "ndd";
2478
- return ShippingMethodMode2;
2479
- })(ShippingMethodMode || {});
2480
- var createInitialValue = () => ({
2481
- plusMemberMetafields: {},
2482
- selectedPlusMemberMode: "free",
2483
- setSelectedPlusMemberMode: () => {
2484
- },
2485
- selectedShippingMethod: void 0,
2486
- setSelectedShippingMethod: () => {
2487
- },
2488
- showMoreShippingMethod: false,
2489
- setShowMoreShippingMethod: () => {
2490
- },
2491
- variant: {},
2492
- product: {},
2493
- shippingMethodsContext: {
2494
- freeShippingMethods: [],
2495
- paymentShippingMethods: [],
2496
- nddOverweight: false,
2497
- tddOverweight: false,
2498
- nddCoupon: void 0,
2499
- tddCoupon: void 0,
2500
- isLoadingCoupon: false
2501
- },
2502
- selectedPlusMemberVariant: void 0,
2503
- showPlusMemberBenefit: false,
2504
- setShowPlusMemberBenefit: () => {
2505
- },
2506
- profile: void 0
2507
- });
2508
- var PlusMemberContext = react.createContext(createInitialValue());
2509
- function usePlusMemberContext() {
2510
- return react.useContext(PlusMemberContext);
2339
+ function useAllProducts(options = {}) {
2340
+ const { client, locale } = useShopify();
2341
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2342
+ return useSWR__default.default(
2343
+ ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2344
+ () => shopifySdk.getAllProducts(client, {
2345
+ locale,
2346
+ first,
2347
+ query,
2348
+ sortKey,
2349
+ reverse,
2350
+ metafieldIdentifiers
2351
+ }),
2352
+ swrOptions
2353
+ );
2511
2354
  }
2512
- function usePlusMemberVariants({
2513
- memberSetting
2514
- }) {
2515
- const plusMonthly = memberSetting?.plus_monthly_product;
2516
- const plusAnnual = memberSetting?.plus_annual_product;
2517
- const plusMemberHandles = react.useMemo(() => {
2518
- return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
2519
- }, [plusMonthly?.handle, plusAnnual?.handle]);
2520
- const { data: plusMemberProducts = [] } = useProductsByHandles({
2521
- handles: plusMemberHandles
2355
+ function getFirstAvailableVariant(product) {
2356
+ const availableVariant = product.variants.find((v) => v.availableForSale);
2357
+ return availableVariant || product.variants[0];
2358
+ }
2359
+ function getVariantFromSelectedOptions(product, selectedOptions) {
2360
+ return product.variants.find((variant) => {
2361
+ return variant.selectedOptions.every((option) => {
2362
+ return selectedOptions[option.name] === option.value;
2363
+ });
2522
2364
  });
2523
- const monthlyProduct = react.useMemo(() => {
2524
- return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
2525
- }, [plusMemberProducts, plusMonthly]);
2526
- const annualProduct = react.useMemo(() => {
2527
- return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
2528
- }, [plusMemberProducts, plusAnnual]);
2529
- const monthlyVariant = react.useMemo(() => {
2530
- return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
2531
- }, [monthlyProduct, plusMonthly]);
2532
- const annualVariant = react.useMemo(() => {
2533
- return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
2534
- }, [annualProduct, plusAnnual]);
2535
- return {
2536
- monthlyVariant: monthlyVariant ? {
2537
- ...monthlyVariant,
2538
- product: monthlyProduct
2539
- } : void 0,
2540
- annualVariant: annualVariant ? {
2541
- ...annualVariant,
2542
- product: annualProduct
2543
- } : void 0
2544
- };
2545
2365
  }
2546
- var useAvailableDeliveryCoupon = ({
2547
- profile
2548
- }) => {
2549
- const { data: availableDeliveryCoupon, isLoading } = useSWR__default.default(
2550
- profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
2551
- async ([apiPath]) => {
2552
- return fetch(apiPath).then((res) => res.json());
2553
- }
2366
+ function useVariant({
2367
+ product,
2368
+ selectedOptions
2369
+ }) {
2370
+ const [variant, setVariant] = react.useState(
2371
+ product ? getFirstAvailableVariant(product) : void 0
2554
2372
  );
2555
- console.log("availableDeliveryCoupon", availableDeliveryCoupon);
2556
- const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
2557
- return {
2558
- nddCoupon,
2559
- tddCoupon,
2560
- isLoading
2561
- };
2562
- };
2563
-
2564
- // src/hooks/member/plus/use-shipping-methods.ts
2565
- function useShippingMethods(options) {
2566
- const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
2567
- const isPlus = profile?.isPlus || false;
2568
- const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
2569
- const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2570
- const nddOverweight = react.useMemo(() => {
2571
- return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
2572
- }, [shippingMethod?.overWeight_ndd, variant?.weight]);
2573
- const tddOverweight = react.useMemo(() => {
2574
- return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
2575
- }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2576
- const paymentShippingMethods = react.useMemo(() => {
2577
- const weight = variant?.weight || 0;
2578
- const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
2579
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2580
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2581
- }) || [];
2582
- return methods.map((method) => {
2583
- let disabled = false;
2584
- const selectedFreeMember = selectedPlusMemberMode === "free";
2585
- if (method.__mode === "ndd" /* NDD */) {
2586
- disabled = selectedFreeMember || nddOverweight;
2587
- } else if (method.__mode === "tdd" /* TDD */) {
2588
- disabled = selectedFreeMember || tddOverweight;
2589
- }
2590
- return {
2591
- ...method,
2592
- id: method.__mode + method.__code,
2593
- useCoupon: false,
2594
- subtitle: plus_shipping?.directly || "",
2595
- disabled
2596
- };
2373
+ react.useEffect(() => {
2374
+ if (!product) {
2375
+ setVariant(void 0);
2376
+ return;
2377
+ }
2378
+ const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
2379
+ if (newVariant && newVariant.id !== variant?.id) {
2380
+ setVariant(newVariant);
2381
+ } else if (!newVariant) {
2382
+ setVariant(getFirstAvailableVariant(product));
2383
+ }
2384
+ }, [selectedOptions, product, variant?.id]);
2385
+ return variant;
2386
+ }
2387
+ var FAKE_PRICE = 999999999e-2;
2388
+ function formatPrice({
2389
+ amount,
2390
+ currencyCode,
2391
+ locale,
2392
+ maximumFractionDigits,
2393
+ minimumFractionDigits,
2394
+ removeTrailingZeros
2395
+ }) {
2396
+ const formatter = new Intl.NumberFormat(locale, {
2397
+ style: "currency",
2398
+ currency: currencyCode,
2399
+ maximumFractionDigits: maximumFractionDigits ?? 2,
2400
+ minimumFractionDigits: minimumFractionDigits ?? 2
2401
+ });
2402
+ let formatted = formatter.format(amount);
2403
+ if (removeTrailingZeros) {
2404
+ formatted = formatted.replace(/\.00$/, "");
2405
+ }
2406
+ return formatted;
2407
+ }
2408
+ function formatVariantPrice({
2409
+ amount,
2410
+ baseAmount,
2411
+ currencyCode,
2412
+ locale,
2413
+ maximumFractionDigits,
2414
+ minimumFractionDigits,
2415
+ removeTrailingZeros
2416
+ }) {
2417
+ return {
2418
+ price: formatPrice({
2419
+ amount,
2420
+ currencyCode,
2421
+ locale,
2422
+ maximumFractionDigits,
2423
+ minimumFractionDigits,
2424
+ removeTrailingZeros
2425
+ }),
2426
+ basePrice: formatPrice({
2427
+ amount: baseAmount,
2428
+ currencyCode,
2429
+ locale,
2430
+ maximumFractionDigits,
2431
+ minimumFractionDigits,
2432
+ removeTrailingZeros
2433
+ })
2434
+ };
2435
+ }
2436
+ function usePrice({
2437
+ amount,
2438
+ baseAmount,
2439
+ currencyCode,
2440
+ soldOutDescription = "",
2441
+ maximumFractionDigits,
2442
+ minimumFractionDigits,
2443
+ removeTrailingZeros
2444
+ }) {
2445
+ const { locale } = useShopify();
2446
+ const value = react.useMemo(() => {
2447
+ if (typeof amount !== "number" || !currencyCode) {
2448
+ return "";
2449
+ }
2450
+ if (soldOutDescription && amount >= FAKE_PRICE) {
2451
+ return soldOutDescription;
2452
+ }
2453
+ return baseAmount ? formatVariantPrice({
2454
+ amount,
2455
+ baseAmount,
2456
+ currencyCode,
2457
+ locale,
2458
+ maximumFractionDigits,
2459
+ minimumFractionDigits,
2460
+ removeTrailingZeros
2461
+ }) : formatPrice({
2462
+ amount,
2463
+ currencyCode,
2464
+ locale,
2465
+ maximumFractionDigits,
2466
+ minimumFractionDigits,
2467
+ removeTrailingZeros
2597
2468
  });
2598
2469
  }, [
2599
- nddOverweight,
2600
- plus_shipping?.directly,
2601
- plus_shipping?.shipping_methods,
2602
- selectedPlusMemberMode,
2603
- tddOverweight,
2604
- variant?.weight
2470
+ amount,
2471
+ baseAmount,
2472
+ currencyCode,
2473
+ locale,
2474
+ maximumFractionDigits,
2475
+ minimumFractionDigits,
2476
+ soldOutDescription,
2477
+ removeTrailingZeros
2605
2478
  ]);
2606
- const nddPrice = react.useMemo(() => {
2607
- const weight = variant?.weight || 0;
2608
- const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2609
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2610
- return __mode === "ndd" && fitWeight;
2611
- });
2612
- return nddMethod?.price || 0;
2613
- }, [variant?.weight, paymentShippingMethods]);
2614
- const tddPrice = react.useMemo(() => {
2615
- const weight = variant?.weight || 0;
2616
- const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2617
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2618
- return __mode === "tdd" && fitWeight;
2619
- });
2620
- return tddMethod?.price || 0;
2621
- }, [variant?.weight, paymentShippingMethods]);
2622
- const freeShippingMethods = react.useMemo(() => {
2623
- const weight = variant?.weight || 0;
2624
- let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
2625
- if (__mode === "free" /* FREE */) {
2626
- return true;
2627
- }
2628
- if (isPlus) {
2629
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2630
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2631
- return hasCoupon && fitWeight && !__plus;
2632
- } else {
2633
- return __plus;
2634
- }
2635
- }) || [];
2636
- if (isPlus) {
2637
- methods = methods.sort((a, b) => {
2638
- if (b.__mode === "free" /* FREE */) return -1;
2639
- return 0;
2640
- });
2479
+ const result = react.useMemo(() => {
2480
+ const free = Boolean(amount && amount <= 0);
2481
+ return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
2482
+ }, [value, amount]);
2483
+ return result;
2484
+ }
2485
+ function optionsConstructor(selectedOptions) {
2486
+ return selectedOptions.reduce((acc, option) => {
2487
+ acc[option.name] = option.value;
2488
+ return acc;
2489
+ }, {});
2490
+ }
2491
+ function decodeShopifyId(gid) {
2492
+ try {
2493
+ const base64 = gid.split("/").pop() || "";
2494
+ return atob(base64);
2495
+ } catch {
2496
+ return gid;
2497
+ }
2498
+ }
2499
+ function useSelectedOptions(product, sku) {
2500
+ const [options, setOptions] = react.useState({});
2501
+ react.useEffect(() => {
2502
+ if (!product || !product.variants.length) {
2503
+ setOptions({});
2504
+ return;
2641
2505
  }
2642
- return methods.map((method) => {
2643
- let price = 0;
2644
- let coupon;
2645
- let disabled;
2646
- if (method.__mode !== "free" /* FREE */) {
2647
- switch (method.__mode) {
2648
- case "tdd":
2649
- price = tddPrice;
2650
- coupon = tddCoupon || nddCoupon;
2651
- break;
2652
- case "ndd":
2653
- price = nddPrice;
2654
- coupon = nddCoupon;
2655
- break;
2506
+ let variant = product.variants[0];
2507
+ if (typeof window !== "undefined") {
2508
+ const searchParams = new URLSearchParams(window.location.search);
2509
+ const variantIdParam = searchParams.get("variant");
2510
+ if (variantIdParam) {
2511
+ const foundVariant = product.variants.find((v) => {
2512
+ if (sku) return v.sku === sku;
2513
+ return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
2514
+ });
2515
+ if (foundVariant) {
2516
+ variant = foundVariant;
2656
2517
  }
2657
- disabled = selectedPlusMemberMode === "free";
2658
- if (method.__mode === "ndd" /* NDD */) {
2659
- disabled = disabled || nddOverweight;
2660
- } else if (method.__mode === "tdd" /* TDD */) {
2661
- disabled = disabled || tddOverweight;
2518
+ }
2519
+ }
2520
+ if (variant) {
2521
+ const newOptions = optionsConstructor(variant.selectedOptions);
2522
+ setOptions(newOptions);
2523
+ }
2524
+ }, [product, sku]);
2525
+ return [options, setOptions];
2526
+ }
2527
+ function decodeShopifyId2(gid) {
2528
+ try {
2529
+ const parts = gid.split("/");
2530
+ return parts[parts.length - 1] || gid;
2531
+ } catch {
2532
+ return gid;
2533
+ }
2534
+ }
2535
+ function useProductUrl(otherQuery) {
2536
+ const { routerAdapter } = useShopify();
2537
+ return react.useCallback(
2538
+ ({ product, variant }) => {
2539
+ if (!product) return "";
2540
+ const queryParams = new URLSearchParams();
2541
+ if (variant?.id) {
2542
+ const variantId = decodeShopifyId2(variant.id);
2543
+ if (variantId) {
2544
+ queryParams.set("variant", variantId);
2662
2545
  }
2663
2546
  }
2664
- return {
2665
- ...method,
2666
- id: method.__mode + method.__code,
2667
- useCoupon: true,
2668
- disabled,
2669
- coupon,
2670
- price
2671
- };
2672
- });
2673
- }, [
2674
- variant?.weight,
2675
- plus_shipping?.shipping_methods,
2676
- isPlus,
2677
- nddCoupon,
2678
- tddCoupon,
2679
- selectedPlusMemberMode,
2680
- tddPrice,
2681
- nddPrice,
2682
- nddOverweight,
2683
- tddOverweight
2684
- ]);
2685
- return {
2686
- freeShippingMethods,
2687
- paymentShippingMethods,
2688
- nddOverweight,
2689
- tddOverweight,
2690
- nddCoupon,
2691
- tddCoupon,
2692
- isLoadingCoupon: isLoading
2693
- };
2547
+ if (otherQuery) {
2548
+ Object.entries(otherQuery).forEach(([key, value]) => {
2549
+ queryParams.set(key, value);
2550
+ });
2551
+ }
2552
+ const queryString = queryParams.toString();
2553
+ const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
2554
+ if (routerAdapter?.getLocalizedPath) {
2555
+ return routerAdapter.getLocalizedPath(path);
2556
+ }
2557
+ return path;
2558
+ },
2559
+ [routerAdapter, otherQuery]
2560
+ );
2694
2561
  }
2695
- var useReplaceCartPlusMember = () => {
2696
- const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
2697
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2698
- const { cart } = useCartContext();
2699
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2700
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2701
- const handler = react.useCallback(async () => {
2702
- const plusMonthlyInCart = cart?.lineItems.find(
2703
- (item) => item.variant?.sku === plusMonthly?.sku
2704
- );
2705
- const plusAnnualInCart = cart?.lineItems.find(
2706
- (item) => item.variant?.sku === plusAnnual?.sku
2707
- );
2708
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
2709
- await removeCartLines2({
2710
- lineIds: [plusMonthlyInCart.id]
2711
- });
2712
- } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
2713
- await removeCartLines2({
2714
- lineIds: [plusAnnualInCart.id]
2715
- });
2562
+ function decodeShopifyId3(gid) {
2563
+ try {
2564
+ const parts = gid.split("/");
2565
+ return parts[parts.length - 1] || gid;
2566
+ } catch {
2567
+ return gid;
2568
+ }
2569
+ }
2570
+ function useUpdateVariantQuery(variant) {
2571
+ react.useEffect(() => {
2572
+ if (!variant || typeof window === "undefined") {
2573
+ return;
2716
2574
  }
2717
- }, [
2718
- cart?.lineItems,
2719
- selectedPlusMemberMode,
2720
- plusMonthly?.sku,
2721
- plusAnnual?.sku,
2722
- removeCartLines2
2723
- ]);
2724
- return handler;
2725
- };
2726
- var usePlusMemberDeliveryCodes = () => {
2727
- const { selectedShippingMethod } = usePlusMemberContext();
2728
- return react.useMemo(() => [selectedShippingMethod?.coupon], [selectedShippingMethod?.coupon]);
2729
- };
2730
- var usePlusMemberCheckoutCustomAttributes = ({
2731
- disableShipping = false,
2732
- isPresaleContains = false
2733
- }) => {
2734
- const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
2735
- return react.useMemo(() => {
2736
- const checkoutCustomAttributes = [
2737
- {
2738
- key: "_last_url",
2739
- value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2575
+ const searchParams = new URLSearchParams(window.location.search);
2576
+ const currentVariantId = searchParams.get("variant");
2577
+ const newVariantId = decodeShopifyId3(variant.id);
2578
+ if (newVariantId && currentVariantId !== newVariantId) {
2579
+ searchParams.set("variant", newVariantId);
2580
+ const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
2581
+ window.history.replaceState({}, "", newUrl);
2582
+ }
2583
+ }, [variant]);
2584
+ }
2585
+ function getVariantMediaList({
2586
+ product,
2587
+ variant
2588
+ }) {
2589
+ if (variant.image?.url) {
2590
+ const variantMediaId = variant.image.url;
2591
+ const variantMedia = product.media.filter((media) => {
2592
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2593
+ return media.previewImage?.url === variantMediaId;
2740
2594
  }
2741
- ];
2742
- checkoutCustomAttributes.push({
2743
- key: "_checkout_delivery_custom",
2744
- value: JSON.stringify({
2745
- allow_nextday_delivery: true,
2746
- allow_thirdday_delivery: true,
2747
- selected_delivery_option: {
2748
- code: selectedShippingMethod?.__code,
2749
- mode: selectedShippingMethod?.__mode
2750
- },
2751
- is_presale: isPresaleContains,
2752
- discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
2753
- plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
2754
- is_prime: profile?.isPlus
2755
- })
2595
+ return false;
2756
2596
  });
2757
- if (disableShipping) {
2758
- checkoutCustomAttributes.push({
2759
- key: "_hide_shipping",
2760
- value: "true"
2597
+ if (variantMedia.length > 0) {
2598
+ const otherMedia = product.media.filter((media) => {
2599
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2600
+ return media.previewImage.url !== variantMediaId;
2601
+ }
2602
+ return true;
2761
2603
  });
2604
+ return [...variantMedia, ...otherMedia];
2762
2605
  }
2763
- return checkoutCustomAttributes;
2764
- }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
2765
- };
2766
- function useAutoRemovePlusMemberInCart({
2767
- cart,
2768
- profile,
2769
- memberSetting
2606
+ }
2607
+ return product.media;
2608
+ }
2609
+ function useVariantMedia({
2610
+ product,
2611
+ variant
2770
2612
  }) {
2771
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2772
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2613
+ const [imageList, setImageList] = react.useState([]);
2614
+ const [sceneList, setSceneList] = react.useState([]);
2615
+ const [videoList, setVideoList] = react.useState([]);
2773
2616
  react.useEffect(() => {
2774
- if (!cart || !plus_monthly_product || !plus_annual_product) return;
2775
- const removePlusProduct = async (productType) => {
2776
- if (!productType) return;
2777
- const product = cart.lineItems?.find(
2778
- (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2779
- );
2780
- if (product) {
2781
- await removeCartLines2({
2782
- lineIds: [product.id]
2783
- });
2617
+ if (!product || !variant) {
2618
+ setImageList([]);
2619
+ setSceneList([]);
2620
+ setVideoList([]);
2621
+ return;
2622
+ }
2623
+ const mediaList = getVariantMediaList({ product, variant });
2624
+ const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
2625
+ const videos = mediaList.filter(
2626
+ (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
2627
+ );
2628
+ setImageList(images.length > 0 && images[0] ? [images[0]] : []);
2629
+ setSceneList(images.length > 1 ? images.slice(1) : []);
2630
+ setVideoList(videos);
2631
+ }, [product, variant]);
2632
+ return {
2633
+ productList: imageList,
2634
+ sceneList,
2635
+ videoList
2636
+ };
2637
+ }
2638
+ function useCollection(options = {}) {
2639
+ const { client, locale } = useShopify();
2640
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2641
+ return useSWR__default.default(
2642
+ handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2643
+ () => shopifySdk.getCollection(client, {
2644
+ handle,
2645
+ locale,
2646
+ metafieldIdentifiers
2647
+ }),
2648
+ swrOptions
2649
+ );
2650
+ }
2651
+ function useAllCollections(options = {}) {
2652
+ const { client, locale } = useShopify();
2653
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2654
+ return useSWR__default.default(
2655
+ ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2656
+ () => shopifySdk.getAllCollections(client, {
2657
+ locale,
2658
+ first,
2659
+ query,
2660
+ sortKey,
2661
+ reverse,
2662
+ metafieldIdentifiers
2663
+ }),
2664
+ swrOptions
2665
+ );
2666
+ }
2667
+ function useCollections(options = {}) {
2668
+ const { client, locale } = useShopify();
2669
+ const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2670
+ return useSWR__default.default(
2671
+ ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2672
+ () => shopifySdk.getCollections(client, {
2673
+ locale,
2674
+ first,
2675
+ after,
2676
+ query,
2677
+ sortKey,
2678
+ reverse,
2679
+ metafieldIdentifiers
2680
+ }),
2681
+ swrOptions
2682
+ );
2683
+ }
2684
+ function useBlog(options = {}) {
2685
+ const { client, locale } = useShopify();
2686
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2687
+ return useSWR__default.default(
2688
+ handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2689
+ () => shopifySdk.getBlog(client, { handle, locale, metafieldIdentifiers }),
2690
+ swrOptions
2691
+ );
2692
+ }
2693
+ function useAllBlogs(options = {}) {
2694
+ const { client, locale } = useShopify();
2695
+ const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2696
+ return useSWR__default.default(
2697
+ ["all-blogs", locale, first, query, metafieldIdentifiers],
2698
+ () => shopifySdk.getAllBlogs(client, {
2699
+ locale,
2700
+ first,
2701
+ query,
2702
+ metafieldIdentifiers
2703
+ }),
2704
+ swrOptions
2705
+ );
2706
+ }
2707
+ function useArticle(options = {}) {
2708
+ const { client, locale } = useShopify();
2709
+ const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2710
+ return useSWR__default.default(
2711
+ blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2712
+ () => shopifySdk.getArticle(client, {
2713
+ blogHandle,
2714
+ articleHandle,
2715
+ locale,
2716
+ metafieldIdentifiers
2717
+ }),
2718
+ swrOptions
2719
+ );
2720
+ }
2721
+ function useArticles(options = {}) {
2722
+ const { client, locale } = useShopify();
2723
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2724
+ return useSWR__default.default(
2725
+ ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2726
+ () => shopifySdk.getArticles(client, {
2727
+ locale,
2728
+ first,
2729
+ query,
2730
+ sortKey,
2731
+ reverse,
2732
+ metafieldIdentifiers
2733
+ }),
2734
+ swrOptions
2735
+ );
2736
+ }
2737
+ function useArticlesInBlog(options = {}) {
2738
+ const { client, locale } = useShopify();
2739
+ const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2740
+ return useSWR__default.default(
2741
+ blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2742
+ () => shopifySdk.getArticlesInBlog(client, {
2743
+ blogHandle,
2744
+ locale,
2745
+ first,
2746
+ sortKey,
2747
+ reverse,
2748
+ metafieldIdentifiers
2749
+ }),
2750
+ swrOptions
2751
+ );
2752
+ }
2753
+ async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2754
+ if (!searchQuery) {
2755
+ return void 0;
2756
+ }
2757
+ const query = (
2758
+ /* GraphQL */
2759
+ `
2760
+ query search($query: String!, $first: Int!, $types: [SearchType!])
2761
+ @inContext(language: $language) {
2762
+ search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2763
+ totalCount
2764
+ edges {
2765
+ node {
2766
+ ... on Article {
2767
+ __typename
2768
+ id
2769
+ handle
2770
+ title
2771
+ excerpt
2772
+ image {
2773
+ url
2774
+ altText
2775
+ }
2776
+ }
2777
+ ... on Page {
2778
+ __typename
2779
+ id
2780
+ handle
2781
+ title
2782
+ }
2783
+ ... on Product {
2784
+ __typename
2785
+ id
2786
+ handle
2787
+ title
2788
+ description
2789
+ featuredImage {
2790
+ url
2791
+ altText
2792
+ }
2793
+ }
2794
+ }
2795
+ }
2796
+ pageInfo {
2797
+ hasNextPage
2798
+ endCursor
2799
+ }
2784
2800
  }
2785
- };
2786
- if (profile?.isMonthlyPlus) {
2787
- removePlusProduct(plus_monthly_product);
2788
- }
2789
- if (profile?.isAnnualPlus) {
2790
- removePlusProduct(plus_annual_product);
2791
2801
  }
2792
- }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2793
- }
2794
- function usePlusMemberNeedAddToCart({
2795
- cart,
2796
- profile
2797
- }) {
2798
- const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
2799
- const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2800
- memberSetting: plusMemberMetafields,
2801
- cart
2802
+ `
2803
+ );
2804
+ const data = await client.query(query, {
2805
+ query: searchQuery,
2806
+ first,
2807
+ types
2802
2808
  });
2803
- const plusMemberVariant = react.useMemo(() => {
2804
- if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
2805
- return void 0;
2806
- }
2807
- if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2808
- return void 0;
2809
- }
2810
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2811
- return void 0;
2812
- }
2813
- if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2814
- return void 0;
2815
- }
2816
- if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2817
- return void 0;
2809
+ if (!data || !data.search) {
2810
+ return void 0;
2811
+ }
2812
+ const items = data.search.edges?.map((edge) => {
2813
+ const node = edge.node;
2814
+ const item = {
2815
+ type: node.__typename.toUpperCase(),
2816
+ id: node.id,
2817
+ handle: node.handle,
2818
+ title: node.title
2819
+ };
2820
+ if (node.__typename === "Product") {
2821
+ item.description = node.description;
2822
+ item.image = node.featuredImage ? {
2823
+ url: node.featuredImage.url,
2824
+ altText: node.featuredImage.altText
2825
+ } : void 0;
2826
+ } else if (node.__typename === "Article") {
2827
+ item.description = node.excerpt;
2828
+ item.image = node.image ? {
2829
+ url: node.image.url,
2830
+ altText: node.image.altText
2831
+ } : void 0;
2818
2832
  }
2819
- return selectedPlusMemberVariant;
2820
- }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2821
- return plusMemberVariant;
2833
+ return item;
2834
+ }) || [];
2835
+ return {
2836
+ items,
2837
+ totalCount: data.search.totalCount || 0,
2838
+ pageInfo: data.search.pageInfo
2839
+ };
2822
2840
  }
2823
- var PlusMemberProvider = ({
2824
- variant,
2825
- product,
2826
- memberSetting,
2827
- initialSelectedPlusMemberMode = "free",
2828
- profile,
2829
- children
2830
- }) => {
2831
- const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2832
- initialSelectedPlusMemberMode
2841
+ function useSearch(options = {}) {
2842
+ const { client, locale } = useShopify();
2843
+ const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2844
+ return useSWR__default.default(
2845
+ query ? ["search", locale, query, first, types] : null,
2846
+ () => performSearch(client, locale, query, first, types),
2847
+ swrOptions
2833
2848
  );
2834
- const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2835
- const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2836
- const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2837
- const shippingMethodsContext = useShippingMethods({
2838
- variant,
2839
- plusMemberMetafields: memberSetting,
2840
- selectedPlusMemberMode,
2841
- profile
2842
- });
2843
- const { monthlyVariant, annualVariant } = usePlusMemberVariants({
2844
- memberSetting
2845
- });
2846
- const selectedPlusMemberVariant = react.useMemo(() => {
2847
- if (selectedPlusMemberMode === "free" /* FREE */) {
2848
- return void 0;
2849
+ }
2850
+ async function getSiteInfo(client, locale, metafieldIdentifiers) {
2851
+ const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2852
+ const query = (
2853
+ /* GraphQL */
2854
+ `
2855
+ query getSiteInfo(
2856
+ ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2857
+ ) @inContext(language: $language) {
2858
+ shop {
2859
+ name
2860
+ description
2861
+ primaryDomain {
2862
+ url
2863
+ host
2864
+ }
2865
+ brand {
2866
+ logo {
2867
+ image {
2868
+ url
2869
+ }
2870
+ }
2871
+ colors {
2872
+ primary {
2873
+ background
2874
+ }
2875
+ secondary {
2876
+ background
2877
+ }
2878
+ }
2879
+ }
2880
+ ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2881
+ }
2849
2882
  }
2850
- return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
2851
- }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
2852
- return /* @__PURE__ */ jsxRuntime.jsx(
2853
- PlusMemberContext.Provider,
2854
- {
2855
- value: {
2856
- variant,
2857
- plusMemberMetafields: memberSetting,
2858
- selectedPlusMemberMode,
2859
- setSelectedPlusMemberMode,
2860
- selectedShippingMethod,
2861
- setSelectedShippingMethod,
2862
- shippingMethodsContext,
2863
- showMoreShippingMethod,
2864
- setShowMoreShippingMethod,
2865
- selectedPlusMemberVariant,
2866
- product,
2867
- showPlusMemberBenefit,
2868
- setShowPlusMemberBenefit,
2869
- profile
2870
- },
2871
- children
2883
+ `
2884
+ );
2885
+ const variables = {};
2886
+ if (hasMetafields) {
2887
+ variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2888
+ }
2889
+ const data = await client.query(query, variables);
2890
+ if (!data || !data.shop) {
2891
+ return void 0;
2892
+ }
2893
+ const shop = data.shop;
2894
+ const metafields = shop.metafields?.reduce((acc, mf) => {
2895
+ if (mf && mf.key) {
2896
+ acc[mf.key] = mf.value;
2872
2897
  }
2898
+ return acc;
2899
+ }, {});
2900
+ return {
2901
+ name: shop.name,
2902
+ description: shop.description,
2903
+ primaryDomain: shop.primaryDomain,
2904
+ brand: shop.brand ? {
2905
+ logo: shop.brand.logo,
2906
+ colors: shop.brand.colors ? {
2907
+ primary: shop.brand.colors.primary?.background,
2908
+ secondary: shop.brand.colors.secondary?.background
2909
+ } : void 0
2910
+ } : void 0,
2911
+ metafields
2912
+ };
2913
+ }
2914
+ function useSite(options = {}) {
2915
+ const { client, locale } = useShopify();
2916
+ const { metafieldIdentifiers, ...swrOptions } = options;
2917
+ return useSWR__default.default(
2918
+ ["site", locale, metafieldIdentifiers],
2919
+ () => getSiteInfo(client, locale, metafieldIdentifiers),
2920
+ swrOptions
2873
2921
  );
2874
- };
2922
+ }
2875
2923
  function useIntersection(targetRef, options) {
2876
2924
  const {
2877
2925
  callback,
@@ -3079,11 +3127,14 @@ exports.defaultSWRMutationConfiguration = defaultSWRMutationConfiguration;
3079
3127
  exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
3080
3128
  exports.formatScriptAutoFreeGift = formatScriptAutoFreeGift;
3081
3129
  exports.getCachedGeoLocation = getCachedGeoLocation;
3130
+ exports.getCartAttributes = getCartAttributes;
3082
3131
  exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
3083
3132
  exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
3084
3133
  exports.getQuery = getQuery;
3085
3134
  exports.getReferralAttributes = getReferralAttributes;
3135
+ exports.getUserType = getUserType;
3086
3136
  exports.hasPlusMemberInCart = hasPlusMemberInCart;
3137
+ exports.hasPlusMemberInLines = hasPlusMemberInLines;
3087
3138
  exports.normalizeAddToCartLines = normalizeAddToCartLines;
3088
3139
  exports.preCheck = preCheck;
3089
3140
  exports.safeParse = safeParse;
@@ -3111,10 +3162,10 @@ exports.useCreateCart = useCreateCart;
3111
3162
  exports.useExposure = useExposure;
3112
3163
  exports.useGeoLocation = useGeoLocation;
3113
3164
  exports.useHasPlusMemberInCart = useHasPlusMemberInCart;
3165
+ exports.useHasPlusMemberInLines = useHasPlusMemberInLines;
3114
3166
  exports.useIntersection = useIntersection;
3115
3167
  exports.usePlusMemberCheckoutCustomAttributes = usePlusMemberCheckoutCustomAttributes;
3116
3168
  exports.usePlusMemberContext = usePlusMemberContext;
3117
- exports.usePlusMemberDeliveryCodes = usePlusMemberDeliveryCodes;
3118
3169
  exports.usePlusMemberNeedAddToCart = usePlusMemberNeedAddToCart;
3119
3170
  exports.usePlusMemberVariants = usePlusMemberVariants;
3120
3171
  exports.usePrice = usePrice;