@numueg/theme-sdk 0.12.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/{chunk-ZECKSIDL.mjs → chunk-AFOLV2U5.mjs} +3 -3
- package/dist/{chunk-ZECKSIDL.mjs.map → chunk-AFOLV2U5.mjs.map} +1 -1
- package/dist/{chunk-7RZISLP2.cjs → chunk-JXJP6FND.cjs} +3 -3
- package/dist/{chunk-7RZISLP2.cjs.map → chunk-JXJP6FND.cjs.map} +1 -1
- package/dist/{chunk-ZYZZG4JR.mjs → chunk-VZO2WMEM.mjs} +13 -4
- package/dist/chunk-VZO2WMEM.mjs.map +1 -0
- package/dist/{chunk-V3JDQXD3.cjs → chunk-WNMFED3F.cjs} +13 -4
- package/dist/chunk-WNMFED3F.cjs.map +1 -0
- package/dist/{entities-1XRRUTlO.d.mts → entities-DRKn04q0.d.mts} +32 -0
- package/dist/{entities-1XRRUTlO.d.ts → entities-DRKn04q0.d.ts} +32 -0
- package/dist/index.cjs +228 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +215 -5
- package/dist/index.d.ts +215 -5
- package/dist/index.mjs +156 -35
- package/dist/index.mjs.map +1 -1
- package/dist/{mount-DDFMacmj.d.mts → mount-BTaDtz8k.d.mts} +1 -1
- package/dist/{mount-qofjiBxw.d.ts → mount-CLQniVfc.d.ts} +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/v2-compat.cjs +6 -6
- package/dist/v2-compat.d.mts +1 -1
- package/dist/v2-compat.d.ts +1 -1
- package/dist/v2-compat.mjs +1 -1
- package/dist/validation.cjs +11 -11
- package/dist/validation.mjs +1 -1
- package/dist/verify.cjs +3 -3
- package/dist/verify.d.mts +2 -2
- package/dist/verify.d.ts +2 -2
- package/dist/verify.mjs +2 -2
- package/package.json +1 -1
- package/dist/chunk-V3JDQXD3.cjs.map +0 -1
- package/dist/chunk-ZYZZG4JR.mjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkTBSNHHFH_cjs = require('./chunk-TBSNHHFH.cjs');
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var chunkJXJP6FND_cjs = require('./chunk-JXJP6FND.cjs');
|
|
5
|
+
var chunkWNMFED3F_cjs = require('./chunk-WNMFED3F.cjs');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var client = require('react-dom/client');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -10,23 +10,23 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
10
10
|
// src/types/theme.ts
|
|
11
11
|
var MAX_BLOCK_DEPTH = 5;
|
|
12
12
|
function useProduct() {
|
|
13
|
-
const ctx = react.useContext(
|
|
13
|
+
const ctx = react.useContext(chunkWNMFED3F_cjs.ProductContext);
|
|
14
14
|
if (!ctx) throw new Error("useProduct must be used within ProductProvider");
|
|
15
15
|
return ctx;
|
|
16
16
|
}
|
|
17
17
|
function useProductOptional() {
|
|
18
|
-
return react.useContext(
|
|
18
|
+
return react.useContext(chunkWNMFED3F_cjs.ProductContext);
|
|
19
19
|
}
|
|
20
20
|
function useCollection() {
|
|
21
|
-
const ctx = react.useContext(
|
|
21
|
+
const ctx = react.useContext(chunkWNMFED3F_cjs.CollectionContext);
|
|
22
22
|
if (!ctx) throw new Error("useCollection must be used within CollectionProvider");
|
|
23
23
|
return ctx;
|
|
24
24
|
}
|
|
25
25
|
function useCollectionOptional() {
|
|
26
|
-
return react.useContext(
|
|
26
|
+
return react.useContext(chunkWNMFED3F_cjs.CollectionContext);
|
|
27
27
|
}
|
|
28
28
|
function useListingHeading(options = {}) {
|
|
29
|
-
const collection = react.useContext(
|
|
29
|
+
const collection = react.useContext(chunkWNMFED3F_cjs.CollectionContext);
|
|
30
30
|
const clean = (v) => typeof v === "string" && v.trim() !== "" ? v.trim() : "";
|
|
31
31
|
const collectionName = clean(collection?.name);
|
|
32
32
|
const collectionDescription = clean(
|
|
@@ -40,12 +40,12 @@ function useListingHeading(options = {}) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
function useCart() {
|
|
43
|
-
const ctx = react.useContext(
|
|
43
|
+
const ctx = react.useContext(chunkWNMFED3F_cjs.CartContext);
|
|
44
44
|
if (!ctx) throw new Error("useCart must be used within NuMuProvider");
|
|
45
45
|
return ctx;
|
|
46
46
|
}
|
|
47
47
|
function useCurrentTemplate() {
|
|
48
|
-
return react.useContext(
|
|
48
|
+
return react.useContext(chunkWNMFED3F_cjs.CurrentTemplateContext);
|
|
49
49
|
}
|
|
50
50
|
function isMetafield(value) {
|
|
51
51
|
return typeof value === "object" && value !== null && typeof value.namespace === "string" && typeof value.key === "string";
|
|
@@ -59,9 +59,9 @@ function pageMetafields(data) {
|
|
|
59
59
|
return [];
|
|
60
60
|
}
|
|
61
61
|
function useMetafields(owner) {
|
|
62
|
-
const product = react.useContext(
|
|
63
|
-
const collection = react.useContext(
|
|
64
|
-
const page = react.useContext(
|
|
62
|
+
const product = react.useContext(chunkWNMFED3F_cjs.ProductContext);
|
|
63
|
+
const collection = react.useContext(chunkWNMFED3F_cjs.CollectionContext);
|
|
64
|
+
const page = react.useContext(chunkWNMFED3F_cjs.PageContext);
|
|
65
65
|
switch (owner) {
|
|
66
66
|
case "product":
|
|
67
67
|
return product?.metafields ?? [];
|
|
@@ -78,7 +78,7 @@ function useMetafield(owner, namespace, key) {
|
|
|
78
78
|
return fields.find((m) => m.namespace === namespace && m.key === key) ?? null;
|
|
79
79
|
}
|
|
80
80
|
function pageData() {
|
|
81
|
-
return react.useContext(
|
|
81
|
+
return react.useContext(chunkWNMFED3F_cjs.PageContext)?.data;
|
|
82
82
|
}
|
|
83
83
|
function useBlogs() {
|
|
84
84
|
const data = pageData();
|
|
@@ -111,7 +111,7 @@ function useSectionOptional() {
|
|
|
111
111
|
}
|
|
112
112
|
var EMPTY = Object.freeze([]);
|
|
113
113
|
function useSectionGroup(group) {
|
|
114
|
-
const settings = react.useContext(
|
|
114
|
+
const settings = react.useContext(chunkWNMFED3F_cjs.ThemeSettingsContext);
|
|
115
115
|
return react.useMemo(() => {
|
|
116
116
|
const grp = settings?.section_groups?.[group];
|
|
117
117
|
if (!grp || !Array.isArray(grp.order) || grp.order.length === 0) {
|
|
@@ -128,8 +128,8 @@ function useSectionGroup(group) {
|
|
|
128
128
|
}, [settings, group]);
|
|
129
129
|
}
|
|
130
130
|
function useCurrency() {
|
|
131
|
-
const ctx = react.useContext(
|
|
132
|
-
const shop =
|
|
131
|
+
const ctx = react.useContext(chunkWNMFED3F_cjs.CurrencyContext);
|
|
132
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
133
133
|
const fallback = react.useMemo(() => {
|
|
134
134
|
const ccy = shop?.currency || "EGP";
|
|
135
135
|
return {
|
|
@@ -149,8 +149,8 @@ function useCurrency() {
|
|
|
149
149
|
|
|
150
150
|
// src/hooks/useMoney.ts
|
|
151
151
|
function useMoney(currencyOverride) {
|
|
152
|
-
const { formatMoney: formatMoney2 } =
|
|
153
|
-
const shop =
|
|
152
|
+
const { formatMoney: formatMoney2 } = chunkWNMFED3F_cjs.useLocalization();
|
|
153
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
154
154
|
const { selected, base, autoConvert, convert } = useCurrency();
|
|
155
155
|
return (amount) => {
|
|
156
156
|
const shouldConvert = autoConvert && !currencyOverride && !!selected && selected !== base;
|
|
@@ -198,7 +198,7 @@ function unwrap(json) {
|
|
|
198
198
|
return json;
|
|
199
199
|
}
|
|
200
200
|
function useOrders() {
|
|
201
|
-
const customer =
|
|
201
|
+
const customer = chunkWNMFED3F_cjs.useCustomer();
|
|
202
202
|
const [orders, setOrders] = react.useState([]);
|
|
203
203
|
const [loading, setLoading] = react.useState(false);
|
|
204
204
|
const [error, setError] = react.useState(null);
|
|
@@ -245,7 +245,7 @@ function useOrders() {
|
|
|
245
245
|
};
|
|
246
246
|
}
|
|
247
247
|
function useOrder(id) {
|
|
248
|
-
const customer =
|
|
248
|
+
const customer = chunkWNMFED3F_cjs.useCustomer();
|
|
249
249
|
const [order, setOrder] = react.useState(null);
|
|
250
250
|
const [loading, setLoading] = react.useState(false);
|
|
251
251
|
const [error, setError] = react.useState(null);
|
|
@@ -308,7 +308,7 @@ async function readBody(res) {
|
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
310
|
function useCustomerAddresses() {
|
|
311
|
-
const customer =
|
|
311
|
+
const customer = chunkWNMFED3F_cjs.useCustomer();
|
|
312
312
|
const [addresses, setAddresses] = react.useState([]);
|
|
313
313
|
const [loading, setLoading] = react.useState(false);
|
|
314
314
|
const [error, setError] = react.useState(null);
|
|
@@ -471,8 +471,8 @@ function toNavigationItem(raw, locale) {
|
|
|
471
471
|
};
|
|
472
472
|
}
|
|
473
473
|
function useNavigation(handle, options) {
|
|
474
|
-
const navMap = react.useContext(
|
|
475
|
-
const localization = react.useContext(
|
|
474
|
+
const navMap = react.useContext(chunkWNMFED3F_cjs.NavigationContext);
|
|
475
|
+
const localization = react.useContext(chunkWNMFED3F_cjs.LocalizationContext);
|
|
476
476
|
const locale = localization?.locale ?? "en";
|
|
477
477
|
const hostProvidedAny = !!navMap && Object.keys(navMap).length > 0;
|
|
478
478
|
const rawItems = handle ? navMap?.[handle] : void 0;
|
|
@@ -878,7 +878,7 @@ function useCachedResource(key, fetcher, options) {
|
|
|
878
878
|
|
|
879
879
|
// src/hooks/useApp.ts
|
|
880
880
|
function useApp(slug) {
|
|
881
|
-
const shop =
|
|
881
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
882
882
|
const key = slug ? `numu:app:${shop.id}:${slug}` : "";
|
|
883
883
|
const fetcher = react.useCallback(
|
|
884
884
|
async (signal) => {
|
|
@@ -1023,10 +1023,137 @@ function useRelatedProducts(productId, options = {}) {
|
|
|
1023
1023
|
});
|
|
1024
1024
|
return { items: data ?? EMPTY4, loading: isLoading, error: error ?? null };
|
|
1025
1025
|
}
|
|
1026
|
+
function useActivePromotions(page = "/", locale = "ar") {
|
|
1027
|
+
const key = `numu:promotions:${page}:${locale}`;
|
|
1028
|
+
const fetcher = react.useCallback(
|
|
1029
|
+
async (signal) => {
|
|
1030
|
+
const qs = new URLSearchParams({ page, locale });
|
|
1031
|
+
const res = await fetch(`/api/storefront/promotions?${qs.toString()}`, {
|
|
1032
|
+
credentials: "include",
|
|
1033
|
+
cache: "no-store",
|
|
1034
|
+
signal
|
|
1035
|
+
});
|
|
1036
|
+
if (!res.ok) return null;
|
|
1037
|
+
const json = await res.json();
|
|
1038
|
+
if (!json) return null;
|
|
1039
|
+
return (json.data ?? json) || null;
|
|
1040
|
+
},
|
|
1041
|
+
[page, locale]
|
|
1042
|
+
);
|
|
1043
|
+
const { data } = useCachedResource(
|
|
1044
|
+
key,
|
|
1045
|
+
fetcher,
|
|
1046
|
+
{ initialData: null }
|
|
1047
|
+
);
|
|
1048
|
+
return data ?? null;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// src/utils/money.ts
|
|
1052
|
+
function resolveLocale(locale) {
|
|
1053
|
+
return locale === "ar" ? "ar-EG" : "en-EG";
|
|
1054
|
+
}
|
|
1055
|
+
function formatMoney(cents, options = {}) {
|
|
1056
|
+
const { currency, locale, fractionDigits = 0 } = options;
|
|
1057
|
+
const safe = Number.isFinite(cents) ? cents : 0;
|
|
1058
|
+
return new Intl.NumberFormat(resolveLocale(locale), {
|
|
1059
|
+
style: "currency",
|
|
1060
|
+
currency: currency || "EGP",
|
|
1061
|
+
maximumFractionDigits: fractionDigits
|
|
1062
|
+
}).format(safe / 100);
|
|
1063
|
+
}
|
|
1064
|
+
function formatMoneyMajor(amount, options = {}) {
|
|
1065
|
+
return formatMoney(
|
|
1066
|
+
(Number.isFinite(amount) ? amount : 0) * 100,
|
|
1067
|
+
options
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
function centsToMajor(cents) {
|
|
1071
|
+
return (Number.isFinite(cents) ? cents : 0) / 100;
|
|
1072
|
+
}
|
|
1073
|
+
function majorToCents(amount) {
|
|
1074
|
+
return Math.round((Number.isFinite(amount) ? amount : 0) * 100);
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// src/lib/promotions.ts
|
|
1078
|
+
function multibuyOffers(promotions) {
|
|
1079
|
+
if (!promotions) return [];
|
|
1080
|
+
const list = Array.isArray(promotions) ? promotions : promotions.auto_discounts ?? [];
|
|
1081
|
+
const offers = [];
|
|
1082
|
+
for (const promo of list) {
|
|
1083
|
+
const rule = promo?.discount_rule;
|
|
1084
|
+
if (!rule || rule.kind !== "multibuy") continue;
|
|
1085
|
+
const quantity = rule.multibuy_quantity;
|
|
1086
|
+
const groupPriceCents = rule.multibuy_price_cents;
|
|
1087
|
+
if (typeof quantity !== "number" || quantity < 2) continue;
|
|
1088
|
+
if (typeof groupPriceCents !== "number" || groupPriceCents <= 0) continue;
|
|
1089
|
+
const eligibleProductIds = promo.eligible_product_ids ?? [];
|
|
1090
|
+
const eligibleCategoryIds = promo.eligible_category_ids ?? [];
|
|
1091
|
+
offers.push({
|
|
1092
|
+
promotionId: promo.promotion_id,
|
|
1093
|
+
quantity,
|
|
1094
|
+
groupPriceCents,
|
|
1095
|
+
groupPriceMajor: centsToMajor(groupPriceCents),
|
|
1096
|
+
headline: promo.translated_content?.headline,
|
|
1097
|
+
eligibleProductIds,
|
|
1098
|
+
eligibleCategoryIds,
|
|
1099
|
+
// No scoping rows at all ⇒ every product qualifies. Note an older
|
|
1100
|
+
// backend that doesn't send these fields also lands here, which is the
|
|
1101
|
+
// right default: counting everything is what themes did before.
|
|
1102
|
+
isStoreWide: eligibleProductIds.length === 0 && eligibleCategoryIds.length === 0,
|
|
1103
|
+
raw: promo
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
return offers;
|
|
1107
|
+
}
|
|
1108
|
+
function offerIncludesProduct(offer, product) {
|
|
1109
|
+
if (!offer) return false;
|
|
1110
|
+
if (offer.isStoreWide) return true;
|
|
1111
|
+
const id = product?.product_id ?? product?.id;
|
|
1112
|
+
if (id && offer.eligibleProductIds.includes(id)) return true;
|
|
1113
|
+
const category = product?.category_id;
|
|
1114
|
+
return Boolean(category && offer.eligibleCategoryIds.includes(category));
|
|
1115
|
+
}
|
|
1116
|
+
function eligibleUnitsInCart(offer, cart) {
|
|
1117
|
+
if (!offer) return 0;
|
|
1118
|
+
return (cart?.items ?? []).reduce((sum, item) => {
|
|
1119
|
+
if (!item) return sum;
|
|
1120
|
+
if (!offerIncludesProduct(offer, item)) return sum;
|
|
1121
|
+
return sum + (item.quantity || 0);
|
|
1122
|
+
}, 0);
|
|
1123
|
+
}
|
|
1124
|
+
function offerProgress(offer, cart, eligibleUnits) {
|
|
1125
|
+
const empty = {
|
|
1126
|
+
unitsInCart: 0,
|
|
1127
|
+
unitsNeeded: 0,
|
|
1128
|
+
groupsUnlocked: 0,
|
|
1129
|
+
savingMajor: 0
|
|
1130
|
+
};
|
|
1131
|
+
if (!offer) return empty;
|
|
1132
|
+
const unitsInCart = typeof eligibleUnits === "number" ? Math.max(0, eligibleUnits) : eligibleUnitsInCart(offer, cart);
|
|
1133
|
+
const groupsUnlocked = Math.floor(unitsInCart / offer.quantity);
|
|
1134
|
+
const remainder = unitsInCart % offer.quantity;
|
|
1135
|
+
const unitsNeeded = remainder === 0 ? 0 : offer.quantity - remainder;
|
|
1136
|
+
const applied = (cart?.applied_promotions ?? []).find(
|
|
1137
|
+
(p) => p && p.id === offer.promotionId
|
|
1138
|
+
);
|
|
1139
|
+
return {
|
|
1140
|
+
unitsInCart,
|
|
1141
|
+
unitsNeeded,
|
|
1142
|
+
groupsUnlocked,
|
|
1143
|
+
savingMajor: applied ? applied.amount || 0 : 0
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
function offerBeatsRegularPrice(offer, unitPriceMajor) {
|
|
1147
|
+
if (!offer || typeof unitPriceMajor !== "number" || unitPriceMajor <= 0) {
|
|
1148
|
+
return false;
|
|
1149
|
+
}
|
|
1150
|
+
const unitCents = Math.round(unitPriceMajor * 100);
|
|
1151
|
+
return unitCents * offer.quantity > offer.groupPriceCents;
|
|
1152
|
+
}
|
|
1026
1153
|
function useProductSizeChart(productOverride) {
|
|
1027
1154
|
const ctxProduct = useProductOptional();
|
|
1028
1155
|
const product = productOverride ?? ctxProduct;
|
|
1029
|
-
const shop =
|
|
1156
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
1030
1157
|
const storeSettings = shop?.settings;
|
|
1031
1158
|
return react.useMemo(
|
|
1032
1159
|
() => resolveSizeChart(product?.attributes, storeSettings),
|
|
@@ -1496,11 +1623,27 @@ var EMPTY_CART = {
|
|
|
1496
1623
|
};
|
|
1497
1624
|
function normalizeCartFromServer(cart) {
|
|
1498
1625
|
const toMajor = (n) => typeof n === "number" ? n / 100 : 0;
|
|
1626
|
+
const { automatic_discount_cents: wireAutomaticCents, ...rest } = cart;
|
|
1499
1627
|
return {
|
|
1500
|
-
...
|
|
1628
|
+
...rest,
|
|
1501
1629
|
subtotal: toMajor(cart.subtotal),
|
|
1502
1630
|
total: toMajor(cart.total),
|
|
1503
1631
|
...cart.discount_amount != null ? { discount_amount: toMajor(cart.discount_amount) } : {},
|
|
1632
|
+
// Offers-v2 automatic promotions. These MUST be converted here too —
|
|
1633
|
+
// they arrive in cents next to already-major totals, so forwarding them
|
|
1634
|
+
// raw makes every theme render a saving 100x too large. This function is
|
|
1635
|
+
// the one and only cents→major boundary for the cart.
|
|
1636
|
+
//
|
|
1637
|
+
// The backend field is `automatic_discount_cents`; themes get
|
|
1638
|
+
// `automatic_discount` (major), because a `_cents` name holding pounds
|
|
1639
|
+
// invites exactly the double-divide this conversion exists to prevent.
|
|
1640
|
+
...wireAutomaticCents != null ? { automatic_discount: toMajor(wireAutomaticCents) } : {},
|
|
1641
|
+
...Array.isArray(cart.applied_promotions) ? {
|
|
1642
|
+
applied_promotions: cart.applied_promotions.map((p) => ({
|
|
1643
|
+
...p,
|
|
1644
|
+
amount: toMajor(p.amount)
|
|
1645
|
+
}))
|
|
1646
|
+
} : {},
|
|
1504
1647
|
items: Array.isArray(cart.items) ? cart.items.map((it) => {
|
|
1505
1648
|
const raw = it;
|
|
1506
1649
|
return {
|
|
@@ -2071,13 +2214,13 @@ function NuMuProvider({
|
|
|
2071
2214
|
convertCurrency
|
|
2072
2215
|
]
|
|
2073
2216
|
);
|
|
2074
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2217
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.ShopContext.Provider, { value: store, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.ThemeSettingsContext.Provider, { value: themeSettings, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.CurrentTemplateContext.Provider, { value: currentTemplate, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.PageContext.Provider, { value: pageValue, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.LocalizationContext.Provider, { value: localization, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.CurrencyContext.Provider, { value: currencyValue, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.CartContext.Provider, { value: cartValue, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.CustomerContext.Provider, { value: customerState, children: /* @__PURE__ */ jsxRuntime.jsx(CustomerActionsContext.Provider, { value: customerActions, children: /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.NavigationContext.Provider, { value: navigation ?? {}, children }) }) }) }) }) }) }) }) }) });
|
|
2075
2218
|
}
|
|
2076
2219
|
function ProductProvider({ product, children }) {
|
|
2077
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2220
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.ProductContext.Provider, { value: product, children });
|
|
2078
2221
|
}
|
|
2079
2222
|
function CollectionProvider({ collection, children }) {
|
|
2080
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2223
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWNMFED3F_cjs.CollectionContext.Provider, { value: collection, children });
|
|
2081
2224
|
}
|
|
2082
2225
|
|
|
2083
2226
|
// src/utils/logoStyle.ts
|
|
@@ -2416,8 +2559,8 @@ function Money({
|
|
|
2416
2559
|
className,
|
|
2417
2560
|
as = "span"
|
|
2418
2561
|
}) {
|
|
2419
|
-
const { formatMoney: formatMoney2 } =
|
|
2420
|
-
const shop =
|
|
2562
|
+
const { formatMoney: formatMoney2 } = chunkWNMFED3F_cjs.useLocalization();
|
|
2563
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
2421
2564
|
const { selected, base, autoConvert, convert } = useCurrency();
|
|
2422
2565
|
const shouldConvert = autoConvert && !currency && !!selected && selected !== base;
|
|
2423
2566
|
const ccy = shouldConvert ? selected : currency || shop?.currency;
|
|
@@ -2464,16 +2607,20 @@ function applyImageTransform(t, fit = "cover") {
|
|
|
2464
2607
|
return style;
|
|
2465
2608
|
}
|
|
2466
2609
|
var clamp01 = (n) => Math.min(1, Math.max(0, n));
|
|
2610
|
+
function hostHonorsCropParams() {
|
|
2611
|
+
return globalThis.__NUMU_CF_IMAGE_RESIZING__ === true;
|
|
2612
|
+
}
|
|
2467
2613
|
function focalSrc(url, options = {}) {
|
|
2468
2614
|
if (!url) return "";
|
|
2469
2615
|
if (url.startsWith("data:") || /[?&](fp-x|fp-y)=/.test(url)) return url;
|
|
2616
|
+
const crop = hostHonorsCropParams();
|
|
2470
2617
|
const p = new URLSearchParams();
|
|
2471
2618
|
p.set("url", url);
|
|
2472
2619
|
if (options.width) p.set("w", String(Math.round(options.width)));
|
|
2473
|
-
if (options.focal?.x != null) p.set("fp-x", String(clamp01(options.focal.x)));
|
|
2474
|
-
if (options.focal?.y != null) p.set("fp-y", String(clamp01(options.focal.y)));
|
|
2475
|
-
if (options.aspect) p.set("ar", options.aspect);
|
|
2476
|
-
if (options.fit) p.set("fit", options.fit);
|
|
2620
|
+
if (crop && options.focal?.x != null) p.set("fp-x", String(clamp01(options.focal.x)));
|
|
2621
|
+
if (crop && options.focal?.y != null) p.set("fp-y", String(clamp01(options.focal.y)));
|
|
2622
|
+
if (crop && options.aspect) p.set("ar", options.aspect);
|
|
2623
|
+
if (crop && options.fit) p.set("fit", options.fit);
|
|
2477
2624
|
if (options.quality) p.set("q", String(Math.min(100, Math.max(1, Math.round(options.quality)))));
|
|
2478
2625
|
if (options.format) p.set("f", options.format.toLowerCase());
|
|
2479
2626
|
return `/api/image-transform?${p.toString()}`;
|
|
@@ -2684,8 +2831,8 @@ function Logo({
|
|
|
2684
2831
|
style,
|
|
2685
2832
|
fallback
|
|
2686
2833
|
}) {
|
|
2687
|
-
const settings =
|
|
2688
|
-
const shop =
|
|
2834
|
+
const settings = chunkWNMFED3F_cjs.useThemeSettings();
|
|
2835
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
2689
2836
|
const g = settings?.global_settings ?? {};
|
|
2690
2837
|
const url = str(src) || str(g.logo_url) || shop?.logo_url || "";
|
|
2691
2838
|
const resolvedShape = shape || str(g.logo_shape) || "none";
|
|
@@ -2721,7 +2868,7 @@ function requestNavigate(href) {
|
|
|
2721
2868
|
return !window.dispatchEvent(event);
|
|
2722
2869
|
}
|
|
2723
2870
|
function Link({ to, children, onClick, ...rest }) {
|
|
2724
|
-
const shop =
|
|
2871
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
2725
2872
|
const isAbsolute = ABSOLUTE_URL.test(to);
|
|
2726
2873
|
let href = to;
|
|
2727
2874
|
if (!isAbsolute && shop && !to.startsWith("/")) {
|
|
@@ -3300,8 +3447,8 @@ function LocaleSwitcher({
|
|
|
3300
3447
|
onSelect,
|
|
3301
3448
|
render
|
|
3302
3449
|
}) {
|
|
3303
|
-
const shop =
|
|
3304
|
-
const { locale } =
|
|
3450
|
+
const shop = chunkWNMFED3F_cjs.useShop();
|
|
3451
|
+
const { locale } = chunkWNMFED3F_cjs.useLocalization();
|
|
3305
3452
|
const available = shop.available_locales || [];
|
|
3306
3453
|
const list = available.length > 0 ? available : shop.default_language === "en" ? ["en"] : Array.from(/* @__PURE__ */ new Set([shop.default_language, "en"]));
|
|
3307
3454
|
const labelFor = react.useCallback((code) => {
|
|
@@ -3719,9 +3866,9 @@ function resolveSettingsMap(settings, ctx) {
|
|
|
3719
3866
|
return out;
|
|
3720
3867
|
}
|
|
3721
3868
|
function useResolvedSettings(instance) {
|
|
3722
|
-
const product = react.useContext(
|
|
3723
|
-
const collection = react.useContext(
|
|
3724
|
-
const store = react.useContext(
|
|
3869
|
+
const product = react.useContext(chunkWNMFED3F_cjs.ProductContext);
|
|
3870
|
+
const collection = react.useContext(chunkWNMFED3F_cjs.CollectionContext);
|
|
3871
|
+
const store = react.useContext(chunkWNMFED3F_cjs.ShopContext);
|
|
3725
3872
|
const ctx = react.useMemo(
|
|
3726
3873
|
() => ({ product, collection, store }),
|
|
3727
3874
|
[product, collection, store]
|
|
@@ -3851,32 +3998,6 @@ function assetUrl(name) {
|
|
|
3851
3998
|
return `${cleanBase}${filename}`;
|
|
3852
3999
|
}
|
|
3853
4000
|
|
|
3854
|
-
// src/utils/money.ts
|
|
3855
|
-
function resolveLocale(locale) {
|
|
3856
|
-
return locale === "ar" ? "ar-EG" : "en-EG";
|
|
3857
|
-
}
|
|
3858
|
-
function formatMoney(cents, options = {}) {
|
|
3859
|
-
const { currency, locale, fractionDigits = 0 } = options;
|
|
3860
|
-
const safe = Number.isFinite(cents) ? cents : 0;
|
|
3861
|
-
return new Intl.NumberFormat(resolveLocale(locale), {
|
|
3862
|
-
style: "currency",
|
|
3863
|
-
currency: currency || "EGP",
|
|
3864
|
-
maximumFractionDigits: fractionDigits
|
|
3865
|
-
}).format(safe / 100);
|
|
3866
|
-
}
|
|
3867
|
-
function formatMoneyMajor(amount, options = {}) {
|
|
3868
|
-
return formatMoney(
|
|
3869
|
-
(Number.isFinite(amount) ? amount : 0) * 100,
|
|
3870
|
-
options
|
|
3871
|
-
);
|
|
3872
|
-
}
|
|
3873
|
-
function centsToMajor(cents) {
|
|
3874
|
-
return (Number.isFinite(cents) ? cents : 0) / 100;
|
|
3875
|
-
}
|
|
3876
|
-
function majorToCents(amount) {
|
|
3877
|
-
return Math.round((Number.isFinite(amount) ? amount : 0) * 100);
|
|
3878
|
-
}
|
|
3879
|
-
|
|
3880
4001
|
// src/utils/templates.ts
|
|
3881
4002
|
function resolveSections(group) {
|
|
3882
4003
|
if (!group) return [];
|
|
@@ -3971,131 +4092,131 @@ Object.defineProperty(exports, "resolveThemeSettings", {
|
|
|
3971
4092
|
});
|
|
3972
4093
|
Object.defineProperty(exports, "KNOWN_SETTING_TYPES", {
|
|
3973
4094
|
enumerable: true,
|
|
3974
|
-
get: function () { return
|
|
4095
|
+
get: function () { return chunkJXJP6FND_cjs.KNOWN_SETTING_TYPES; }
|
|
3975
4096
|
});
|
|
3976
4097
|
Object.defineProperty(exports, "KNOWN_TEMPLATES", {
|
|
3977
4098
|
enumerable: true,
|
|
3978
|
-
get: function () { return
|
|
4099
|
+
get: function () { return chunkJXJP6FND_cjs.KNOWN_TEMPLATES; }
|
|
3979
4100
|
});
|
|
3980
4101
|
Object.defineProperty(exports, "REQUIRED_TEMPLATES", {
|
|
3981
4102
|
enumerable: true,
|
|
3982
|
-
get: function () { return
|
|
4103
|
+
get: function () { return chunkJXJP6FND_cjs.REQUIRED_TEMPLATES; }
|
|
3983
4104
|
});
|
|
3984
4105
|
Object.defineProperty(exports, "SDK_VERSION", {
|
|
3985
4106
|
enumerable: true,
|
|
3986
|
-
get: function () { return
|
|
4107
|
+
get: function () { return chunkJXJP6FND_cjs.SDK_VERSION; }
|
|
3987
4108
|
});
|
|
3988
4109
|
Object.defineProperty(exports, "THEME_CONTRACT_VERSION", {
|
|
3989
4110
|
enumerable: true,
|
|
3990
|
-
get: function () { return
|
|
4111
|
+
get: function () { return chunkJXJP6FND_cjs.THEME_CONTRACT_VERSION; }
|
|
3991
4112
|
});
|
|
3992
4113
|
Object.defineProperty(exports, "mergeResults", {
|
|
3993
4114
|
enumerable: true,
|
|
3994
|
-
get: function () { return
|
|
4115
|
+
get: function () { return chunkJXJP6FND_cjs.mergeResults; }
|
|
3995
4116
|
});
|
|
3996
4117
|
Object.defineProperty(exports, "validateBuiltManifest", {
|
|
3997
4118
|
enumerable: true,
|
|
3998
|
-
get: function () { return
|
|
4119
|
+
get: function () { return chunkJXJP6FND_cjs.validateBuiltManifest; }
|
|
3999
4120
|
});
|
|
4000
4121
|
Object.defineProperty(exports, "validateManifest", {
|
|
4001
4122
|
enumerable: true,
|
|
4002
|
-
get: function () { return
|
|
4123
|
+
get: function () { return chunkJXJP6FND_cjs.validateManifest; }
|
|
4003
4124
|
});
|
|
4004
4125
|
Object.defineProperty(exports, "validateSectionSchema", {
|
|
4005
4126
|
enumerable: true,
|
|
4006
|
-
get: function () { return
|
|
4127
|
+
get: function () { return chunkJXJP6FND_cjs.validateSectionSchema; }
|
|
4007
4128
|
});
|
|
4008
4129
|
Object.defineProperty(exports, "validateSettingsAgainstSchema", {
|
|
4009
4130
|
enumerable: true,
|
|
4010
|
-
get: function () { return
|
|
4131
|
+
get: function () { return chunkJXJP6FND_cjs.validateSettingsAgainstSchema; }
|
|
4011
4132
|
});
|
|
4012
4133
|
Object.defineProperty(exports, "CartContext", {
|
|
4013
4134
|
enumerable: true,
|
|
4014
|
-
get: function () { return
|
|
4135
|
+
get: function () { return chunkWNMFED3F_cjs.CartContext; }
|
|
4015
4136
|
});
|
|
4016
4137
|
Object.defineProperty(exports, "CollectionContext", {
|
|
4017
4138
|
enumerable: true,
|
|
4018
|
-
get: function () { return
|
|
4139
|
+
get: function () { return chunkWNMFED3F_cjs.CollectionContext; }
|
|
4019
4140
|
});
|
|
4020
4141
|
Object.defineProperty(exports, "CurrencyContext", {
|
|
4021
4142
|
enumerable: true,
|
|
4022
|
-
get: function () { return
|
|
4143
|
+
get: function () { return chunkWNMFED3F_cjs.CurrencyContext; }
|
|
4023
4144
|
});
|
|
4024
4145
|
Object.defineProperty(exports, "CustomerContext", {
|
|
4025
4146
|
enumerable: true,
|
|
4026
|
-
get: function () { return
|
|
4147
|
+
get: function () { return chunkWNMFED3F_cjs.CustomerContext; }
|
|
4027
4148
|
});
|
|
4028
4149
|
Object.defineProperty(exports, "LocalizationContext", {
|
|
4029
4150
|
enumerable: true,
|
|
4030
|
-
get: function () { return
|
|
4151
|
+
get: function () { return chunkWNMFED3F_cjs.LocalizationContext; }
|
|
4031
4152
|
});
|
|
4032
4153
|
Object.defineProperty(exports, "NavigationContext", {
|
|
4033
4154
|
enumerable: true,
|
|
4034
|
-
get: function () { return
|
|
4155
|
+
get: function () { return chunkWNMFED3F_cjs.NavigationContext; }
|
|
4035
4156
|
});
|
|
4036
4157
|
Object.defineProperty(exports, "PageContext", {
|
|
4037
4158
|
enumerable: true,
|
|
4038
|
-
get: function () { return
|
|
4159
|
+
get: function () { return chunkWNMFED3F_cjs.PageContext; }
|
|
4039
4160
|
});
|
|
4040
4161
|
Object.defineProperty(exports, "ProductContext", {
|
|
4041
4162
|
enumerable: true,
|
|
4042
|
-
get: function () { return
|
|
4163
|
+
get: function () { return chunkWNMFED3F_cjs.ProductContext; }
|
|
4043
4164
|
});
|
|
4044
4165
|
Object.defineProperty(exports, "ShopContext", {
|
|
4045
4166
|
enumerable: true,
|
|
4046
|
-
get: function () { return
|
|
4167
|
+
get: function () { return chunkWNMFED3F_cjs.ShopContext; }
|
|
4047
4168
|
});
|
|
4048
4169
|
Object.defineProperty(exports, "ThemeSettingsContext", {
|
|
4049
4170
|
enumerable: true,
|
|
4050
|
-
get: function () { return
|
|
4171
|
+
get: function () { return chunkWNMFED3F_cjs.ThemeSettingsContext; }
|
|
4051
4172
|
});
|
|
4052
4173
|
Object.defineProperty(exports, "useCollections", {
|
|
4053
4174
|
enumerable: true,
|
|
4054
|
-
get: function () { return
|
|
4175
|
+
get: function () { return chunkWNMFED3F_cjs.useCollections; }
|
|
4055
4176
|
});
|
|
4056
4177
|
Object.defineProperty(exports, "useCustomer", {
|
|
4057
4178
|
enumerable: true,
|
|
4058
|
-
get: function () { return
|
|
4179
|
+
get: function () { return chunkWNMFED3F_cjs.useCustomer; }
|
|
4059
4180
|
});
|
|
4060
4181
|
Object.defineProperty(exports, "useDirection", {
|
|
4061
4182
|
enumerable: true,
|
|
4062
|
-
get: function () { return
|
|
4183
|
+
get: function () { return chunkWNMFED3F_cjs.useDirection; }
|
|
4063
4184
|
});
|
|
4064
4185
|
Object.defineProperty(exports, "useFieldTranslation", {
|
|
4065
4186
|
enumerable: true,
|
|
4066
|
-
get: function () { return
|
|
4187
|
+
get: function () { return chunkWNMFED3F_cjs.useFieldTranslation; }
|
|
4067
4188
|
});
|
|
4068
4189
|
Object.defineProperty(exports, "useLocale", {
|
|
4069
4190
|
enumerable: true,
|
|
4070
|
-
get: function () { return
|
|
4191
|
+
get: function () { return chunkWNMFED3F_cjs.useLocale; }
|
|
4071
4192
|
});
|
|
4072
4193
|
Object.defineProperty(exports, "useLocalization", {
|
|
4073
4194
|
enumerable: true,
|
|
4074
|
-
get: function () { return
|
|
4195
|
+
get: function () { return chunkWNMFED3F_cjs.useLocalization; }
|
|
4075
4196
|
});
|
|
4076
4197
|
Object.defineProperty(exports, "useNumberFormat", {
|
|
4077
4198
|
enumerable: true,
|
|
4078
|
-
get: function () { return
|
|
4199
|
+
get: function () { return chunkWNMFED3F_cjs.useNumberFormat; }
|
|
4079
4200
|
});
|
|
4080
4201
|
Object.defineProperty(exports, "usePage", {
|
|
4081
4202
|
enumerable: true,
|
|
4082
|
-
get: function () { return
|
|
4203
|
+
get: function () { return chunkWNMFED3F_cjs.usePage; }
|
|
4083
4204
|
});
|
|
4084
4205
|
Object.defineProperty(exports, "useProducts", {
|
|
4085
4206
|
enumerable: true,
|
|
4086
|
-
get: function () { return
|
|
4207
|
+
get: function () { return chunkWNMFED3F_cjs.useProducts; }
|
|
4087
4208
|
});
|
|
4088
4209
|
Object.defineProperty(exports, "useShop", {
|
|
4089
4210
|
enumerable: true,
|
|
4090
|
-
get: function () { return
|
|
4211
|
+
get: function () { return chunkWNMFED3F_cjs.useShop; }
|
|
4091
4212
|
});
|
|
4092
4213
|
Object.defineProperty(exports, "useThemeSettings", {
|
|
4093
4214
|
enumerable: true,
|
|
4094
|
-
get: function () { return
|
|
4215
|
+
get: function () { return chunkWNMFED3F_cjs.useThemeSettings; }
|
|
4095
4216
|
});
|
|
4096
4217
|
Object.defineProperty(exports, "useTranslation", {
|
|
4097
4218
|
enumerable: true,
|
|
4098
|
-
get: function () { return
|
|
4219
|
+
get: function () { return chunkWNMFED3F_cjs.useTranslation; }
|
|
4099
4220
|
});
|
|
4100
4221
|
exports.AddToCartButton = AddToCartButton;
|
|
4101
4222
|
exports.Block = Block;
|
|
@@ -4142,6 +4263,7 @@ exports.defineBlock = defineBlock;
|
|
|
4142
4263
|
exports.defineSection = defineSection;
|
|
4143
4264
|
exports.defineThemeEntry = defineThemeEntry;
|
|
4144
4265
|
exports.dynamicSource = dynamicSource;
|
|
4266
|
+
exports.eligibleUnitsInCart = eligibleUnitsInCart;
|
|
4145
4267
|
exports.findVariantByOptions = findVariantByOptions;
|
|
4146
4268
|
exports.flattenMessages = flattenMessages;
|
|
4147
4269
|
exports.focalSrc = focalSrc;
|
|
@@ -4157,6 +4279,10 @@ exports.logoImgStyle = logoImgStyle;
|
|
|
4157
4279
|
exports.logoStyleTokens = logoStyleTokens;
|
|
4158
4280
|
exports.majorToCents = majorToCents;
|
|
4159
4281
|
exports.mountTheme = mountTheme;
|
|
4282
|
+
exports.multibuyOffers = multibuyOffers;
|
|
4283
|
+
exports.offerBeatsRegularPrice = offerBeatsRegularPrice;
|
|
4284
|
+
exports.offerIncludesProduct = offerIncludesProduct;
|
|
4285
|
+
exports.offerProgress = offerProgress;
|
|
4160
4286
|
exports.pickTranslations = pickTranslations;
|
|
4161
4287
|
exports.productHref = productHref;
|
|
4162
4288
|
exports.publishVariantSelection = publishVariantSelection;
|
|
@@ -4173,6 +4299,7 @@ exports.resolveSourcePath = resolveSourcePath;
|
|
|
4173
4299
|
exports.sanitizeHtml = sanitizeHtml;
|
|
4174
4300
|
exports.selectChromeSections = selectChromeSections;
|
|
4175
4301
|
exports.selectTemplateSections = selectTemplateSections;
|
|
4302
|
+
exports.useActivePromotions = useActivePromotions;
|
|
4176
4303
|
exports.useAnalytics = useAnalytics;
|
|
4177
4304
|
exports.useApp = useApp;
|
|
4178
4305
|
exports.useArticle = useArticle;
|