@numueg/theme-sdk 0.10.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkTBSNHHFH_cjs = require('./chunk-TBSNHHFH.cjs');
4
- var chunkO4GLTNLE_cjs = require('./chunk-O4GLTNLE.cjs');
4
+ var chunkH7RGDWSU_cjs = require('./chunk-H7RGDWSU.cjs');
5
5
  var chunkV3JDQXD3_cjs = require('./chunk-V3JDQXD3.cjs');
6
6
  var react = require('react');
7
7
  var client = require('react-dom/client');
@@ -25,6 +25,20 @@ function useCollection() {
25
25
  function useCollectionOptional() {
26
26
  return react.useContext(chunkV3JDQXD3_cjs.CollectionContext);
27
27
  }
28
+ function useListingHeading(options = {}) {
29
+ const collection = react.useContext(chunkV3JDQXD3_cjs.CollectionContext);
30
+ const clean = (v) => typeof v === "string" && v.trim() !== "" ? v.trim() : "";
31
+ const collectionName = clean(collection?.name);
32
+ const collectionDescription = clean(
33
+ collection?.description
34
+ );
35
+ return {
36
+ collection: collection ?? null,
37
+ isCollection: collectionName !== "",
38
+ title: collectionName || clean(options.title) || clean(options.defaultTitle) || "",
39
+ description: collectionDescription || clean(options.description) || ""
40
+ };
41
+ }
28
42
  function useCart() {
29
43
  const ctx = react.useContext(chunkV3JDQXD3_cjs.CartContext);
30
44
  if (!ctx) throw new Error("useCart must be used within NuMuProvider");
@@ -33,6 +47,59 @@ function useCart() {
33
47
  function useCurrentTemplate() {
34
48
  return react.useContext(chunkV3JDQXD3_cjs.CurrentTemplateContext);
35
49
  }
50
+ function isMetafield(value) {
51
+ return typeof value === "object" && value !== null && typeof value.namespace === "string" && typeof value.key === "string";
52
+ }
53
+ function pageMetafields(data) {
54
+ if (!data) return [];
55
+ const record = data.page;
56
+ for (const candidate of [record?.metafields, data.metafields]) {
57
+ if (Array.isArray(candidate)) return candidate.filter(isMetafield);
58
+ }
59
+ return [];
60
+ }
61
+ function useMetafields(owner) {
62
+ const product = react.useContext(chunkV3JDQXD3_cjs.ProductContext);
63
+ const collection = react.useContext(chunkV3JDQXD3_cjs.CollectionContext);
64
+ const page = react.useContext(chunkV3JDQXD3_cjs.PageContext);
65
+ switch (owner) {
66
+ case "product":
67
+ return product?.metafields ?? [];
68
+ case "collection":
69
+ return collection?.metafields ?? [];
70
+ case "page":
71
+ return pageMetafields(page?.data);
72
+ default:
73
+ return [];
74
+ }
75
+ }
76
+ function useMetafield(owner, namespace, key) {
77
+ const fields = useMetafields(owner);
78
+ return fields.find((m) => m.namespace === namespace && m.key === key) ?? null;
79
+ }
80
+ function pageData() {
81
+ return react.useContext(chunkV3JDQXD3_cjs.PageContext)?.data;
82
+ }
83
+ function useBlogs() {
84
+ const data = pageData();
85
+ const blogs = data?.blogs;
86
+ return Array.isArray(blogs) ? blogs : [];
87
+ }
88
+ function useBlog() {
89
+ const data = pageData();
90
+ const blog = data?.blog ?? data?.article?.blog;
91
+ return blog && typeof blog === "object" ? blog : null;
92
+ }
93
+ function useArticles() {
94
+ const data = pageData();
95
+ const articles = data?.articles;
96
+ return Array.isArray(articles) ? articles : [];
97
+ }
98
+ function useArticle() {
99
+ const data = pageData();
100
+ const article = data?.article;
101
+ return article && typeof article === "object" ? article : null;
102
+ }
36
103
  var SectionContext = react.createContext(null);
37
104
  function useSection() {
38
105
  const ctx = react.useContext(SectionContext);
@@ -82,16 +149,16 @@ function useCurrency() {
82
149
 
83
150
  // src/hooks/useMoney.ts
84
151
  function useMoney(currencyOverride) {
85
- const { formatMoney } = chunkV3JDQXD3_cjs.useLocalization();
152
+ const { formatMoney: formatMoney2 } = chunkV3JDQXD3_cjs.useLocalization();
86
153
  const shop = chunkV3JDQXD3_cjs.useShop();
87
154
  const { selected, base, autoConvert, convert } = useCurrency();
88
155
  return (amount) => {
89
156
  const shouldConvert = autoConvert && !currencyOverride && !!selected && selected !== base;
90
157
  if (shouldConvert) {
91
158
  const converted = convert(Math.round(amount * 100), selected) / 100;
92
- return formatMoney(converted, selected);
159
+ return formatMoney2(converted, selected);
93
160
  }
94
- return formatMoney(amount, currencyOverride || shop?.currency);
161
+ return formatMoney2(amount, currencyOverride || shop?.currency);
95
162
  };
96
163
  }
97
164
  var DEFAULT_WIDTHS = [320, 480, 640, 768, 1024, 1280, 1600, 1920];
@@ -956,6 +1023,133 @@ function useRelatedProducts(productId, options = {}) {
956
1023
  });
957
1024
  return { items: data ?? EMPTY4, loading: isLoading, error: error ?? null };
958
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
+ }
959
1153
  function useProductSizeChart(productOverride) {
960
1154
  const ctxProduct = useProductOptional();
961
1155
  const product = productOverride ?? ctxProduct;
@@ -1429,11 +1623,27 @@ var EMPTY_CART = {
1429
1623
  };
1430
1624
  function normalizeCartFromServer(cart) {
1431
1625
  const toMajor = (n) => typeof n === "number" ? n / 100 : 0;
1626
+ const { automatic_discount_cents: wireAutomaticCents, ...rest } = cart;
1432
1627
  return {
1433
- ...cart,
1628
+ ...rest,
1434
1629
  subtotal: toMajor(cart.subtotal),
1435
1630
  total: toMajor(cart.total),
1436
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
+ } : {},
1437
1647
  items: Array.isArray(cart.items) ? cart.items.map((it) => {
1438
1648
  const raw = it;
1439
1649
  return {
@@ -2255,13 +2465,13 @@ function pickDemo(ctx, themeSettings) {
2255
2465
  const t = themeSettings.templates;
2256
2466
  return !t || Object.keys(t).length === 0;
2257
2467
  }
2258
- function wrapEntityProviders(app, pageData) {
2468
+ function wrapEntityProviders(app, pageData2) {
2259
2469
  let inner = app;
2260
- if (pageData.collection) {
2261
- inner = /* @__PURE__ */ jsxRuntime.jsx(CollectionProvider, { collection: pageData.collection, children: inner });
2470
+ if (pageData2.collection) {
2471
+ inner = /* @__PURE__ */ jsxRuntime.jsx(CollectionProvider, { collection: pageData2.collection, children: inner });
2262
2472
  }
2263
- if (pageData.product) {
2264
- inner = /* @__PURE__ */ jsxRuntime.jsx(ProductProvider, { product: pageData.product, children: inner });
2473
+ if (pageData2.product) {
2474
+ inner = /* @__PURE__ */ jsxRuntime.jsx(ProductProvider, { product: pageData2.product, children: inner });
2265
2475
  }
2266
2476
  return inner;
2267
2477
  }
@@ -2284,7 +2494,7 @@ var ThemeMountBridge = react.forwardRef(function ThemeMountBridge2({ ctx, mountE
2284
2494
  const store = pickStore(ctx);
2285
2495
  const template = pickTemplate(ctx);
2286
2496
  const demo = pickDemo(ctx, themeSettings);
2287
- const pageData = ctx.page?.data ?? {};
2497
+ const pageData2 = ctx.page?.data ?? {};
2288
2498
  const app = renderApp({
2289
2499
  currentTemplate: template,
2290
2500
  demo,
@@ -2302,11 +2512,11 @@ var ThemeMountBridge = react.forwardRef(function ThemeMountBridge2({ ctx, mountE
2302
2512
  locale: ctx.locale,
2303
2513
  translations: ctx.translations,
2304
2514
  navigation: ctx.navigation,
2305
- initialProducts: pageData.products,
2306
- initialCollections: pageData.collections,
2515
+ initialProducts: pageData2.products,
2516
+ initialCollections: pageData2.collections,
2307
2517
  currentTemplate: template,
2308
2518
  pageTemplate: ctx.page?.template,
2309
- children: wrapEntityProviders(app, pageData)
2519
+ children: wrapEntityProviders(app, pageData2)
2310
2520
  }
2311
2521
  );
2312
2522
  });
@@ -2349,7 +2559,7 @@ function Money({
2349
2559
  className,
2350
2560
  as = "span"
2351
2561
  }) {
2352
- const { formatMoney } = chunkV3JDQXD3_cjs.useLocalization();
2562
+ const { formatMoney: formatMoney2 } = chunkV3JDQXD3_cjs.useLocalization();
2353
2563
  const shop = chunkV3JDQXD3_cjs.useShop();
2354
2564
  const { selected, base, autoConvert, convert } = useCurrency();
2355
2565
  const shouldConvert = autoConvert && !currency && !!selected && selected !== base;
@@ -2357,12 +2567,12 @@ function Money({
2357
2567
  const toDisplay = (major) => shouldConvert ? convert(Math.round(major * 100), selected) / 100 : major;
2358
2568
  const showCompare = compareAt != null && compareAt > amount;
2359
2569
  const children = [
2360
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatMoney(toDisplay(amount), ccy) }, "amt")
2570
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatMoney2(toDisplay(amount), ccy) }, "amt")
2361
2571
  ];
2362
2572
  if (showCompare) {
2363
2573
  children.push(" ");
2364
2574
  children.push(
2365
- /* @__PURE__ */ jsxRuntime.jsx("s", { style: { opacity: 0.6 }, children: formatMoney(toDisplay(compareAt), ccy) }, "cmp")
2575
+ /* @__PURE__ */ jsxRuntime.jsx("s", { style: { opacity: 0.6 }, children: formatMoney2(toDisplay(compareAt), ccy) }, "cmp")
2366
2576
  );
2367
2577
  }
2368
2578
  return react.createElement(
@@ -2382,7 +2592,7 @@ function asImageTransform(v) {
2382
2592
  return void 0;
2383
2593
  }
2384
2594
  function applyImageTransform(t, fit = "cover") {
2385
- if (!t) return { objectFit: fit };
2595
+ if (!t) return {};
2386
2596
  const fx = Math.round(_clampT(t.focal?.x ?? 0.5, 0, 1) * 1e4) / 100;
2387
2597
  const fy = Math.round(_clampT(t.focal?.y ?? 0.5, 0, 1) * 1e4) / 100;
2388
2598
  const zoom = _clampT(t.zoom ?? 1, 1, 4);
@@ -2585,7 +2795,10 @@ function HeroMedia({
2585
2795
  const activeBase = useMobile ? MOBILE_BASE_WIDTH : DESKTOP_BASE_WIDTH;
2586
2796
  const activeSrc = rawFallback ? activeUrl : focalSrc(activeUrl, { width: activeBase, ...activeCrop });
2587
2797
  const activeSrcSet = rawFallback ? void 0 : heroSrcSet(activeUrl, activeCrop);
2588
- const fitStyle = applyImageTransform(useMobile ? mobileTransform ?? transform : transform, fit);
2798
+ const fitStyle = {
2799
+ objectFit: fit,
2800
+ ...applyImageTransform(useMobile ? mobileTransform ?? transform : transform, fit)
2801
+ };
2589
2802
  return /* @__PURE__ */ jsxRuntime.jsx(
2590
2803
  "img",
2591
2804
  {
@@ -2926,6 +3139,20 @@ function Form({
2926
3139
  }
2927
3140
  );
2928
3141
  }
3142
+
3143
+ // src/utils/routes.ts
3144
+ function productHref(slugOrId) {
3145
+ if (!slugOrId) return "/products";
3146
+ return `/products/${slugOrId}`;
3147
+ }
3148
+ function collectionHref(category) {
3149
+ if (!category) return "/collections";
3150
+ if (typeof category === "string") {
3151
+ return category ? `/collections/${category}` : "/collections";
3152
+ }
3153
+ const key = category.slug || category.id;
3154
+ return key ? `/collections/${key}` : "/collections";
3155
+ }
2929
3156
  function joinClass(...names) {
2930
3157
  return names.filter(Boolean).join(" ");
2931
3158
  }
@@ -2936,7 +3163,7 @@ function ProductCard({
2936
3163
  slots,
2937
3164
  imageSizes
2938
3165
  }) {
2939
- const target = href ?? `/products/${product.slug}`;
3166
+ const target = href ?? productHref(product.slug);
2940
3167
  const firstImage = product.images?.[0];
2941
3168
  const inStock = product.in_stock;
2942
3169
  const badge = slots?.badge !== void 0 ? slots.badge : inStock ? null : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "numu-product-card__badge", children: "Sold out" });
@@ -3549,7 +3776,19 @@ function resolveSourcePath(path, ctx) {
3549
3776
  return null;
3550
3777
  }
3551
3778
  }
3779
+ function resolveMetafield(metafields, field) {
3780
+ const address = field.slice("metafield:".length);
3781
+ const dot = address.indexOf(".");
3782
+ if (dot === -1) return null;
3783
+ const namespace = address.slice(0, dot);
3784
+ const key = address.slice(dot + 1);
3785
+ const hit = (metafields ?? []).find(
3786
+ (m) => m.namespace === namespace && m.key === key
3787
+ );
3788
+ return hit ? hit.value ?? null : null;
3789
+ }
3552
3790
  function resolveProductField(p, field) {
3791
+ if (field.startsWith("metafield:")) return resolveMetafield(p.metafields, field);
3553
3792
  switch (field) {
3554
3793
  case "title":
3555
3794
  case "name":
@@ -3572,6 +3811,7 @@ function resolveProductField(p, field) {
3572
3811
  }
3573
3812
  }
3574
3813
  function resolveCollectionField(c, field) {
3814
+ if (field.startsWith("metafield:")) return resolveMetafield(c.metafields, field);
3575
3815
  switch (field) {
3576
3816
  case "title":
3577
3817
  case "name":
@@ -3754,6 +3994,50 @@ function assetUrl(name) {
3754
3994
  return `${cleanBase}${filename}`;
3755
3995
  }
3756
3996
 
3997
+ // src/utils/templates.ts
3998
+ function resolveSections(group) {
3999
+ if (!group) return [];
4000
+ if (Array.isArray(group.sections)) {
4001
+ return group.sections.map((instance, idx) => ({
4002
+ id: `${instance.type}-${idx}`,
4003
+ instance
4004
+ }));
4005
+ }
4006
+ const map = group.sections ?? {};
4007
+ const order = group.order ?? Object.keys(map);
4008
+ const out = [];
4009
+ for (const id of order) {
4010
+ const instance = map[id];
4011
+ if (instance) out.push({ id, instance });
4012
+ }
4013
+ return out;
4014
+ }
4015
+ function selectTemplateSections(hostTemplate, builtinTemplate, isKnown) {
4016
+ const hostSections = resolveSections(hostTemplate);
4017
+ if (hostSections.length === 0) {
4018
+ return resolveSections(builtinTemplate);
4019
+ }
4020
+ const anyKnown = hostSections.some(({ instance }) => isKnown(instance.type));
4021
+ if (!anyKnown) return resolveSections(builtinTemplate);
4022
+ return hostSections.filter(({ instance }) => isKnown(instance.type));
4023
+ }
4024
+ function selectChromeSections(options) {
4025
+ const { hostGroup, presetGroup, inline, templates, isChrome, isKnown } = options;
4026
+ const known = (list) => list.filter(({ instance }) => isKnown(instance.type));
4027
+ const fromHost = known(resolveSections(hostGroup));
4028
+ if (fromHost.length > 0) return fromHost;
4029
+ if (inline && inline.length > 0) return known(inline);
4030
+ const fromPreset = known(resolveSections(presetGroup));
4031
+ if (fromPreset.length > 0) return fromPreset;
4032
+ for (const template of templates ?? []) {
4033
+ const borrowed = known(resolveSections(template)).filter(
4034
+ ({ instance }) => isChrome(instance.type)
4035
+ );
4036
+ if (borrowed.length > 0) return borrowed;
4037
+ }
4038
+ return [];
4039
+ }
4040
+
3757
4041
  // src/utils/locales.ts
3758
4042
  function flattenMessages(source, prefix = "") {
3759
4043
  const out = {};
@@ -3804,43 +4088,43 @@ Object.defineProperty(exports, "resolveThemeSettings", {
3804
4088
  });
3805
4089
  Object.defineProperty(exports, "KNOWN_SETTING_TYPES", {
3806
4090
  enumerable: true,
3807
- get: function () { return chunkO4GLTNLE_cjs.KNOWN_SETTING_TYPES; }
4091
+ get: function () { return chunkH7RGDWSU_cjs.KNOWN_SETTING_TYPES; }
3808
4092
  });
3809
4093
  Object.defineProperty(exports, "KNOWN_TEMPLATES", {
3810
4094
  enumerable: true,
3811
- get: function () { return chunkO4GLTNLE_cjs.KNOWN_TEMPLATES; }
4095
+ get: function () { return chunkH7RGDWSU_cjs.KNOWN_TEMPLATES; }
3812
4096
  });
3813
4097
  Object.defineProperty(exports, "REQUIRED_TEMPLATES", {
3814
4098
  enumerable: true,
3815
- get: function () { return chunkO4GLTNLE_cjs.REQUIRED_TEMPLATES; }
4099
+ get: function () { return chunkH7RGDWSU_cjs.REQUIRED_TEMPLATES; }
3816
4100
  });
3817
4101
  Object.defineProperty(exports, "SDK_VERSION", {
3818
4102
  enumerable: true,
3819
- get: function () { return chunkO4GLTNLE_cjs.SDK_VERSION; }
4103
+ get: function () { return chunkH7RGDWSU_cjs.SDK_VERSION; }
3820
4104
  });
3821
4105
  Object.defineProperty(exports, "THEME_CONTRACT_VERSION", {
3822
4106
  enumerable: true,
3823
- get: function () { return chunkO4GLTNLE_cjs.THEME_CONTRACT_VERSION; }
4107
+ get: function () { return chunkH7RGDWSU_cjs.THEME_CONTRACT_VERSION; }
3824
4108
  });
3825
4109
  Object.defineProperty(exports, "mergeResults", {
3826
4110
  enumerable: true,
3827
- get: function () { return chunkO4GLTNLE_cjs.mergeResults; }
4111
+ get: function () { return chunkH7RGDWSU_cjs.mergeResults; }
3828
4112
  });
3829
4113
  Object.defineProperty(exports, "validateBuiltManifest", {
3830
4114
  enumerable: true,
3831
- get: function () { return chunkO4GLTNLE_cjs.validateBuiltManifest; }
4115
+ get: function () { return chunkH7RGDWSU_cjs.validateBuiltManifest; }
3832
4116
  });
3833
4117
  Object.defineProperty(exports, "validateManifest", {
3834
4118
  enumerable: true,
3835
- get: function () { return chunkO4GLTNLE_cjs.validateManifest; }
4119
+ get: function () { return chunkH7RGDWSU_cjs.validateManifest; }
3836
4120
  });
3837
4121
  Object.defineProperty(exports, "validateSectionSchema", {
3838
4122
  enumerable: true,
3839
- get: function () { return chunkO4GLTNLE_cjs.validateSectionSchema; }
4123
+ get: function () { return chunkH7RGDWSU_cjs.validateSectionSchema; }
3840
4124
  });
3841
4125
  Object.defineProperty(exports, "validateSettingsAgainstSchema", {
3842
4126
  enumerable: true,
3843
- get: function () { return chunkO4GLTNLE_cjs.validateSettingsAgainstSchema; }
4127
+ get: function () { return chunkH7RGDWSU_cjs.validateSettingsAgainstSchema; }
3844
4128
  });
3845
4129
  Object.defineProperty(exports, "CartContext", {
3846
4130
  enumerable: true,
@@ -3964,18 +4248,23 @@ exports.assetUrl = assetUrl;
3964
4248
  exports.availableValues = availableValues;
3965
4249
  exports.buildLocaleBundle = buildLocaleBundle;
3966
4250
  exports.buildThemeElement = buildThemeElement;
4251
+ exports.centsToMajor = centsToMajor;
3967
4252
  exports.clearSdkSingleton = clearSdkSingleton;
3968
4253
  exports.collectBlocks = collectBlocks;
3969
4254
  exports.collectSections = collectSections;
4255
+ exports.collectionHref = collectionHref;
3970
4256
  exports.computeGlobalStyleTokens = computeGlobalStyleTokens;
3971
4257
  exports.defaultVariant = defaultVariant;
3972
4258
  exports.defineBlock = defineBlock;
3973
4259
  exports.defineSection = defineSection;
3974
4260
  exports.defineThemeEntry = defineThemeEntry;
3975
4261
  exports.dynamicSource = dynamicSource;
4262
+ exports.eligibleUnitsInCart = eligibleUnitsInCart;
3976
4263
  exports.findVariantByOptions = findVariantByOptions;
3977
4264
  exports.flattenMessages = flattenMessages;
3978
4265
  exports.focalSrc = focalSrc;
4266
+ exports.formatMoney = formatMoney;
4267
+ exports.formatMoneyMajor = formatMoneyMajor;
3979
4268
  exports.getReactSingleton = getReactSingleton;
3980
4269
  exports.getSdkSingleton = getSdkSingleton;
3981
4270
  exports.isDefinedBlock = isDefinedBlock;
@@ -3984,8 +4273,14 @@ exports.isDynamicSource = isDynamicSource;
3984
4273
  exports.isSdkAvailable = isSdkAvailable;
3985
4274
  exports.logoImgStyle = logoImgStyle;
3986
4275
  exports.logoStyleTokens = logoStyleTokens;
4276
+ exports.majorToCents = majorToCents;
3987
4277
  exports.mountTheme = mountTheme;
4278
+ exports.multibuyOffers = multibuyOffers;
4279
+ exports.offerBeatsRegularPrice = offerBeatsRegularPrice;
4280
+ exports.offerIncludesProduct = offerIncludesProduct;
4281
+ exports.offerProgress = offerProgress;
3988
4282
  exports.pickTranslations = pickTranslations;
4283
+ exports.productHref = productHref;
3989
4284
  exports.publishVariantSelection = publishVariantSelection;
3990
4285
  exports.readVariantSelection = readVariantSelection;
3991
4286
  exports.registerReactSingleton = registerReactSingleton;
@@ -3993,12 +4288,20 @@ exports.registerSdkSingleton = registerSdkSingleton;
3993
4288
  exports.requestNavigate = requestNavigate;
3994
4289
  exports.resolveDynamicValue = resolveDynamicValue;
3995
4290
  exports.resolveFontStack = resolveFontStack;
4291
+ exports.resolveSections = resolveSections;
3996
4292
  exports.resolveSettingsMap = resolveSettingsMap;
3997
4293
  exports.resolveSizeChart = resolveSizeChart;
3998
4294
  exports.resolveSourcePath = resolveSourcePath;
3999
4295
  exports.sanitizeHtml = sanitizeHtml;
4296
+ exports.selectChromeSections = selectChromeSections;
4297
+ exports.selectTemplateSections = selectTemplateSections;
4298
+ exports.useActivePromotions = useActivePromotions;
4000
4299
  exports.useAnalytics = useAnalytics;
4001
4300
  exports.useApp = useApp;
4301
+ exports.useArticle = useArticle;
4302
+ exports.useArticles = useArticles;
4303
+ exports.useBlog = useBlog;
4304
+ exports.useBlogs = useBlogs;
4002
4305
  exports.useCachedResource = useCachedResource;
4003
4306
  exports.useCart = useCart;
4004
4307
  exports.useCheckout = useCheckout;
@@ -4010,6 +4313,9 @@ exports.useCustomerActions = useCustomerActions;
4010
4313
  exports.useCustomerAddresses = useCustomerAddresses;
4011
4314
  exports.useGiftCardBalance = useGiftCardBalance;
4012
4315
  exports.useImage = useImage;
4316
+ exports.useListingHeading = useListingHeading;
4317
+ exports.useMetafield = useMetafield;
4318
+ exports.useMetafields = useMetafields;
4013
4319
  exports.useMoney = useMoney;
4014
4320
  exports.useNavigation = useNavigation;
4015
4321
  exports.useOrder = useOrder;