@numueg/theme-sdk 0.6.0 → 0.9.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/CHANGELOG.md +144 -0
- package/dist/chunk-3C37JX2X.cjs +207 -0
- package/dist/chunk-3C37JX2X.cjs.map +1 -0
- package/dist/chunk-JIAA7TGR.mjs +397 -0
- package/dist/chunk-JIAA7TGR.mjs.map +1 -0
- package/dist/chunk-PUR3FRGQ.mjs +183 -0
- package/dist/chunk-PUR3FRGQ.mjs.map +1 -0
- package/dist/chunk-TBSNHHFH.cjs +96 -0
- package/dist/chunk-TBSNHHFH.cjs.map +1 -0
- package/dist/chunk-X3J4GDI7.cjs +408 -0
- package/dist/chunk-X3J4GDI7.cjs.map +1 -0
- package/dist/chunk-XF2FGIVS.mjs +94 -0
- package/dist/chunk-XF2FGIVS.mjs.map +1 -0
- package/dist/{entities-6MGANln7.d.mts → entities-B8378GKp.d.mts} +12 -0
- package/dist/{entities-6MGANln7.d.ts → entities-B8378GKp.d.ts} +12 -0
- package/dist/index.cjs +643 -965
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +215 -82
- package/dist/index.d.ts +215 -82
- package/dist/index.mjs +485 -908
- package/dist/index.mjs.map +1 -1
- package/dist/{mount-BGumg1JM.d.mts → mount-CM4kGg9w.d.ts} +87 -14
- package/dist/{mount-Bt-4ken5.d.ts → mount-NLjFNyBv.d.mts} +87 -14
- package/dist/normalize.cjs +7 -91
- package/dist/normalize.cjs.map +1 -1
- package/dist/normalize.d.mts +1 -1
- package/dist/normalize.d.ts +1 -1
- package/dist/normalize.mjs +1 -92
- package/dist/normalize.mjs.map +1 -1
- package/dist/{theme-D8MOopvi.d.mts → theme-CNTB4KnU.d.mts} +29 -3
- package/dist/{theme-D8MOopvi.d.ts → theme-CNTB4KnU.d.ts} +29 -3
- package/dist/types.d.mts +2 -2
- package/dist/types.d.ts +2 -2
- package/dist/v2-compat.cjs +6 -163
- package/dist/v2-compat.cjs.map +1 -1
- package/dist/v2-compat.d.mts +1 -1
- package/dist/v2-compat.d.ts +1 -1
- package/dist/v2-compat.mjs +2 -159
- package/dist/v2-compat.mjs.map +1 -1
- package/dist/validation.cjs +43 -403
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.mts +1 -1
- package/dist/validation.d.ts +1 -1
- package/dist/validation.mjs +1 -395
- package/dist/validation.mjs.map +1 -1
- package/dist/verify.cjs +6 -21
- package/dist/verify.cjs.map +1 -1
- package/dist/verify.d.mts +3 -3
- package/dist/verify.d.ts +3 -3
- package/dist/verify.mjs +3 -20
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, ReactElement } from 'react';
|
|
3
|
-
import { C as Cart, b as Collection, c as Customer, P as Page, e as Product, i as Store } from './entities-
|
|
4
|
-
import { T as ThemeSettingsV3, M as MountResult } from './theme-
|
|
3
|
+
import { C as Cart, b as Collection, c as Customer, P as Page, e as Product, i as Store } from './entities-B8378GKp.js';
|
|
4
|
+
import { T as ThemeSettingsV3, M as MountResult } from './theme-CNTB4KnU.js';
|
|
5
5
|
|
|
6
6
|
interface LocalizationState {
|
|
7
7
|
locale: string;
|
|
@@ -33,20 +33,40 @@ interface LocalizationState {
|
|
|
33
33
|
*/
|
|
34
34
|
availableLocales: string[];
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Result of a cart mutation (add / remove / update / discount / note).
|
|
38
|
+
*
|
|
39
|
+
* `ok` mirrors the HTTP result: `false` for any non-2xx response — an
|
|
40
|
+
* out-of-stock or validation rejection, a 403 CSRF failure, etc. — so a
|
|
41
|
+
* theme can surface the failure (toast, inline error) instead of assuming
|
|
42
|
+
* the write landed. `status` is the HTTP status (0 for a network throw that
|
|
43
|
+
* the caller catches); `message` carries the backend's error text when the
|
|
44
|
+
* error body parses.
|
|
45
|
+
*
|
|
46
|
+
* Back-compat: the cart methods previously resolved `Promise<void>`; callers
|
|
47
|
+
* that `await` them and ignore the return keep working unchanged — the
|
|
48
|
+
* resolved value is purely additive.
|
|
49
|
+
*/
|
|
50
|
+
interface CartMutationResult {
|
|
51
|
+
ok: boolean;
|
|
52
|
+
status: number;
|
|
53
|
+
message?: string;
|
|
54
|
+
}
|
|
55
|
+
interface CartContextValue {
|
|
40
56
|
cart: Cart;
|
|
41
|
-
addItem: (productId: string, variantId?: string, quantity?: number) => Promise<
|
|
42
|
-
removeItem: (itemId: string) => Promise<
|
|
43
|
-
updateQuantity: (itemId: string, quantity: number) => Promise<
|
|
44
|
-
applyDiscount: (code: string) => Promise<
|
|
45
|
-
removeDiscount: () => Promise<
|
|
46
|
-
updateNote: (note: string) => Promise<
|
|
57
|
+
addItem: (productId: string, variantId?: string, quantity?: number) => Promise<CartMutationResult>;
|
|
58
|
+
removeItem: (itemId: string) => Promise<CartMutationResult>;
|
|
59
|
+
updateQuantity: (itemId: string, quantity: number) => Promise<CartMutationResult>;
|
|
60
|
+
applyDiscount: (code: string) => Promise<CartMutationResult>;
|
|
61
|
+
removeDiscount: () => Promise<CartMutationResult>;
|
|
62
|
+
updateNote: (note: string) => Promise<CartMutationResult>;
|
|
47
63
|
clearCart: () => Promise<void>;
|
|
48
64
|
loading: boolean;
|
|
49
|
-
}
|
|
65
|
+
}
|
|
66
|
+
declare const ShopContext: react.Context<Store | null>;
|
|
67
|
+
declare const ProductContext: react.Context<Product | null>;
|
|
68
|
+
declare const CollectionContext: react.Context<Collection | null>;
|
|
69
|
+
declare const CartContext: react.Context<CartContextValue | null>;
|
|
50
70
|
declare const CustomerContext: react.Context<Customer | null>;
|
|
51
71
|
declare const ThemeSettingsContext: react.Context<ThemeSettingsV3 | null>;
|
|
52
72
|
declare const LocalizationContext: react.Context<LocalizationState | null>;
|
|
@@ -86,6 +106,52 @@ interface MenuItemData {
|
|
|
86
106
|
* doesn't exist (render nothing / fallback), no fetch attempted.
|
|
87
107
|
*/
|
|
88
108
|
declare const NavigationContext: react.Context<Record<string, MenuItemData[]>>;
|
|
109
|
+
/**
|
|
110
|
+
* Multi-currency presentment config, as returned by
|
|
111
|
+
* `GET /api/storefront/currencies`. Display-only — the store's *capture*
|
|
112
|
+
* currency never changes mid-session; this just lets visitors browse prices
|
|
113
|
+
* in a currency they recognize.
|
|
114
|
+
*/
|
|
115
|
+
interface CurrencyConfig {
|
|
116
|
+
base: string;
|
|
117
|
+
default_presentment: string;
|
|
118
|
+
presentment: string[];
|
|
119
|
+
rates: Record<string, string>;
|
|
120
|
+
auto_convert: boolean;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The value `useCurrency()` returns and `CurrencyContext` carries.
|
|
124
|
+
*
|
|
125
|
+
* `convert(cents, target?)` returns the converted **cents** in `target`
|
|
126
|
+
* (defaults to `selected`), using the API rates; returns the input unchanged
|
|
127
|
+
* when no rate exists (theme renders base — better than a wrong number).
|
|
128
|
+
*/
|
|
129
|
+
interface CurrencyState {
|
|
130
|
+
base: string;
|
|
131
|
+
selected: string;
|
|
132
|
+
presentment: string[];
|
|
133
|
+
rates: Record<string, number>;
|
|
134
|
+
autoConvert: boolean;
|
|
135
|
+
loading: boolean;
|
|
136
|
+
setSelected: (currency: string) => void;
|
|
137
|
+
convert: (cents: number, target?: string) => number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Phase 2 (correctness) — multi-currency lifted into a provider context.
|
|
141
|
+
*
|
|
142
|
+
* Previously `useCurrency()` fetched `/api/storefront/currencies` and held
|
|
143
|
+
* the selected currency in per-instance `useState`, so each `<Money>`,
|
|
144
|
+
* `useMoney()` and `<CurrencySwitcher>` owned an INDEPENDENT copy: switching
|
|
145
|
+
* currency in the switcher never reached the price tags, and every consumer
|
|
146
|
+
* re-fetched. `NuMuProvider` now fetches ONCE and publishes a single
|
|
147
|
+
* `CurrencyState` here, so a `<CurrencySwitcher>` change re-renders every
|
|
148
|
+
* `<Money>` on the page without a reload.
|
|
149
|
+
*
|
|
150
|
+
* Null when no provider is present (SSR before hydrate, or a theme mounted
|
|
151
|
+
* outside `NuMuProvider`); `useCurrency()` then falls back to a base-only,
|
|
152
|
+
* no-convert state derived from the store currency so `<Money>` still renders.
|
|
153
|
+
*/
|
|
154
|
+
declare const CurrencyContext: react.Context<CurrencyState | null>;
|
|
89
155
|
|
|
90
156
|
/**
|
|
91
157
|
* `mountTheme(el, ctx, renderApp)` — the canonical V3 bundle entry helper.
|
|
@@ -148,6 +214,13 @@ interface ThemeMountPage {
|
|
|
148
214
|
handle?: string;
|
|
149
215
|
title?: string;
|
|
150
216
|
data?: Record<string, unknown>;
|
|
217
|
+
/**
|
|
218
|
+
* Resolved alternate template key for this page (e.g. `"product.wholesale"`)
|
|
219
|
+
* when the storefront routed it to a template suffix. `mountTheme` forwards
|
|
220
|
+
* it to `NuMuProvider` so a theme reads it via `usePage()?.template`. Absent
|
|
221
|
+
* for pages on their default template. Additive/optional.
|
|
222
|
+
*/
|
|
223
|
+
template?: string;
|
|
151
224
|
}
|
|
152
225
|
/**
|
|
153
226
|
* The mount context a host (or dev harness) passes to a bundle's `mount`.
|
|
@@ -222,4 +295,4 @@ declare function buildThemeElement(ctx: ThemeMountContext, mountEl: HTMLElement
|
|
|
222
295
|
*/
|
|
223
296
|
declare function mountTheme(el: HTMLElement, ctx: ThemeMountContext, renderApp: (args: ThemeRenderArgs) => ReactNode): MountResult;
|
|
224
297
|
|
|
225
|
-
export {
|
|
298
|
+
export { type CartContextValue as C, type LocalizationState as L, type MenuItemData as M, NavigationContext as N, PageContext as P, ShopContext as S, type ThemeMountContext as T, type CurrencyState as a, type ThemeRenderArgs as b, CartContext as c, type CartMutationResult as d, CollectionContext as e, type CurrencyConfig as f, CurrencyContext as g, CustomerContext as h, LocalizationContext as i, ProductContext as j, type ThemeMountPage as k, ThemeSettingsContext as l, buildThemeElement as m, mountTheme as n };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, ReactElement } from 'react';
|
|
3
|
-
import { C as Cart, b as Collection, c as Customer, P as Page, e as Product, i as Store } from './entities-
|
|
4
|
-
import { T as ThemeSettingsV3, M as MountResult } from './theme-
|
|
3
|
+
import { C as Cart, b as Collection, c as Customer, P as Page, e as Product, i as Store } from './entities-B8378GKp.mjs';
|
|
4
|
+
import { T as ThemeSettingsV3, M as MountResult } from './theme-CNTB4KnU.mjs';
|
|
5
5
|
|
|
6
6
|
interface LocalizationState {
|
|
7
7
|
locale: string;
|
|
@@ -33,20 +33,40 @@ interface LocalizationState {
|
|
|
33
33
|
*/
|
|
34
34
|
availableLocales: string[];
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Result of a cart mutation (add / remove / update / discount / note).
|
|
38
|
+
*
|
|
39
|
+
* `ok` mirrors the HTTP result: `false` for any non-2xx response — an
|
|
40
|
+
* out-of-stock or validation rejection, a 403 CSRF failure, etc. — so a
|
|
41
|
+
* theme can surface the failure (toast, inline error) instead of assuming
|
|
42
|
+
* the write landed. `status` is the HTTP status (0 for a network throw that
|
|
43
|
+
* the caller catches); `message` carries the backend's error text when the
|
|
44
|
+
* error body parses.
|
|
45
|
+
*
|
|
46
|
+
* Back-compat: the cart methods previously resolved `Promise<void>`; callers
|
|
47
|
+
* that `await` them and ignore the return keep working unchanged — the
|
|
48
|
+
* resolved value is purely additive.
|
|
49
|
+
*/
|
|
50
|
+
interface CartMutationResult {
|
|
51
|
+
ok: boolean;
|
|
52
|
+
status: number;
|
|
53
|
+
message?: string;
|
|
54
|
+
}
|
|
55
|
+
interface CartContextValue {
|
|
40
56
|
cart: Cart;
|
|
41
|
-
addItem: (productId: string, variantId?: string, quantity?: number) => Promise<
|
|
42
|
-
removeItem: (itemId: string) => Promise<
|
|
43
|
-
updateQuantity: (itemId: string, quantity: number) => Promise<
|
|
44
|
-
applyDiscount: (code: string) => Promise<
|
|
45
|
-
removeDiscount: () => Promise<
|
|
46
|
-
updateNote: (note: string) => Promise<
|
|
57
|
+
addItem: (productId: string, variantId?: string, quantity?: number) => Promise<CartMutationResult>;
|
|
58
|
+
removeItem: (itemId: string) => Promise<CartMutationResult>;
|
|
59
|
+
updateQuantity: (itemId: string, quantity: number) => Promise<CartMutationResult>;
|
|
60
|
+
applyDiscount: (code: string) => Promise<CartMutationResult>;
|
|
61
|
+
removeDiscount: () => Promise<CartMutationResult>;
|
|
62
|
+
updateNote: (note: string) => Promise<CartMutationResult>;
|
|
47
63
|
clearCart: () => Promise<void>;
|
|
48
64
|
loading: boolean;
|
|
49
|
-
}
|
|
65
|
+
}
|
|
66
|
+
declare const ShopContext: react.Context<Store | null>;
|
|
67
|
+
declare const ProductContext: react.Context<Product | null>;
|
|
68
|
+
declare const CollectionContext: react.Context<Collection | null>;
|
|
69
|
+
declare const CartContext: react.Context<CartContextValue | null>;
|
|
50
70
|
declare const CustomerContext: react.Context<Customer | null>;
|
|
51
71
|
declare const ThemeSettingsContext: react.Context<ThemeSettingsV3 | null>;
|
|
52
72
|
declare const LocalizationContext: react.Context<LocalizationState | null>;
|
|
@@ -86,6 +106,52 @@ interface MenuItemData {
|
|
|
86
106
|
* doesn't exist (render nothing / fallback), no fetch attempted.
|
|
87
107
|
*/
|
|
88
108
|
declare const NavigationContext: react.Context<Record<string, MenuItemData[]>>;
|
|
109
|
+
/**
|
|
110
|
+
* Multi-currency presentment config, as returned by
|
|
111
|
+
* `GET /api/storefront/currencies`. Display-only — the store's *capture*
|
|
112
|
+
* currency never changes mid-session; this just lets visitors browse prices
|
|
113
|
+
* in a currency they recognize.
|
|
114
|
+
*/
|
|
115
|
+
interface CurrencyConfig {
|
|
116
|
+
base: string;
|
|
117
|
+
default_presentment: string;
|
|
118
|
+
presentment: string[];
|
|
119
|
+
rates: Record<string, string>;
|
|
120
|
+
auto_convert: boolean;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The value `useCurrency()` returns and `CurrencyContext` carries.
|
|
124
|
+
*
|
|
125
|
+
* `convert(cents, target?)` returns the converted **cents** in `target`
|
|
126
|
+
* (defaults to `selected`), using the API rates; returns the input unchanged
|
|
127
|
+
* when no rate exists (theme renders base — better than a wrong number).
|
|
128
|
+
*/
|
|
129
|
+
interface CurrencyState {
|
|
130
|
+
base: string;
|
|
131
|
+
selected: string;
|
|
132
|
+
presentment: string[];
|
|
133
|
+
rates: Record<string, number>;
|
|
134
|
+
autoConvert: boolean;
|
|
135
|
+
loading: boolean;
|
|
136
|
+
setSelected: (currency: string) => void;
|
|
137
|
+
convert: (cents: number, target?: string) => number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Phase 2 (correctness) — multi-currency lifted into a provider context.
|
|
141
|
+
*
|
|
142
|
+
* Previously `useCurrency()` fetched `/api/storefront/currencies` and held
|
|
143
|
+
* the selected currency in per-instance `useState`, so each `<Money>`,
|
|
144
|
+
* `useMoney()` and `<CurrencySwitcher>` owned an INDEPENDENT copy: switching
|
|
145
|
+
* currency in the switcher never reached the price tags, and every consumer
|
|
146
|
+
* re-fetched. `NuMuProvider` now fetches ONCE and publishes a single
|
|
147
|
+
* `CurrencyState` here, so a `<CurrencySwitcher>` change re-renders every
|
|
148
|
+
* `<Money>` on the page without a reload.
|
|
149
|
+
*
|
|
150
|
+
* Null when no provider is present (SSR before hydrate, or a theme mounted
|
|
151
|
+
* outside `NuMuProvider`); `useCurrency()` then falls back to a base-only,
|
|
152
|
+
* no-convert state derived from the store currency so `<Money>` still renders.
|
|
153
|
+
*/
|
|
154
|
+
declare const CurrencyContext: react.Context<CurrencyState | null>;
|
|
89
155
|
|
|
90
156
|
/**
|
|
91
157
|
* `mountTheme(el, ctx, renderApp)` — the canonical V3 bundle entry helper.
|
|
@@ -148,6 +214,13 @@ interface ThemeMountPage {
|
|
|
148
214
|
handle?: string;
|
|
149
215
|
title?: string;
|
|
150
216
|
data?: Record<string, unknown>;
|
|
217
|
+
/**
|
|
218
|
+
* Resolved alternate template key for this page (e.g. `"product.wholesale"`)
|
|
219
|
+
* when the storefront routed it to a template suffix. `mountTheme` forwards
|
|
220
|
+
* it to `NuMuProvider` so a theme reads it via `usePage()?.template`. Absent
|
|
221
|
+
* for pages on their default template. Additive/optional.
|
|
222
|
+
*/
|
|
223
|
+
template?: string;
|
|
151
224
|
}
|
|
152
225
|
/**
|
|
153
226
|
* The mount context a host (or dev harness) passes to a bundle's `mount`.
|
|
@@ -222,4 +295,4 @@ declare function buildThemeElement(ctx: ThemeMountContext, mountEl: HTMLElement
|
|
|
222
295
|
*/
|
|
223
296
|
declare function mountTheme(el: HTMLElement, ctx: ThemeMountContext, renderApp: (args: ThemeRenderArgs) => ReactNode): MountResult;
|
|
224
297
|
|
|
225
|
-
export {
|
|
298
|
+
export { type CartContextValue as C, type LocalizationState as L, type MenuItemData as M, NavigationContext as N, PageContext as P, ShopContext as S, type ThemeMountContext as T, type CurrencyState as a, type ThemeRenderArgs as b, CartContext as c, type CartMutationResult as d, CollectionContext as e, type CurrencyConfig as f, CurrencyContext as g, CustomerContext as h, LocalizationContext as i, ProductContext as j, type ThemeMountPage as k, ThemeSettingsContext as l, buildThemeElement as m, mountTheme as n };
|
package/dist/normalize.cjs
CHANGED
|
@@ -1,96 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var DEFAULT_THEME_ID = typeof process !== "undefined" && process.env?.NUMU_DEFAULT_THEME_ID || "modern";
|
|
5
|
-
function resolveThemeSettings(raw) {
|
|
6
|
-
const safeRaw = raw ?? {};
|
|
7
|
-
if (safeRaw.schema_version === 3) {
|
|
8
|
-
return safeRaw;
|
|
9
|
-
}
|
|
10
|
-
const themeBlock = safeRaw.theme || {};
|
|
11
|
-
const themeId = typeof themeBlock.base_theme === "string" && themeBlock.base_theme || DEFAULT_THEME_ID;
|
|
12
|
-
const globalSettings = {};
|
|
13
|
-
for (const key of [
|
|
14
|
-
"primary_color",
|
|
15
|
-
"secondary_color",
|
|
16
|
-
"font_family",
|
|
17
|
-
"logo_url"
|
|
18
|
-
]) {
|
|
19
|
-
if (themeBlock[key] !== void 0) globalSettings[key] = themeBlock[key];
|
|
20
|
-
}
|
|
21
|
-
if (safeRaw.identity) globalSettings.identity = safeRaw.identity;
|
|
22
|
-
const sections = {};
|
|
23
|
-
const order = [];
|
|
24
|
-
const hero = safeRaw.hero;
|
|
25
|
-
if (hero) {
|
|
26
|
-
sections["hero_1"] = {
|
|
27
|
-
type: "hero",
|
|
28
|
-
settings: {
|
|
29
|
-
// Mirrors backend `normalize_legacy_to_v3` exactly — includes
|
|
30
|
-
// headline_ar so Arabic content survives the round-trip.
|
|
31
|
-
headline: hero.headline ?? "",
|
|
32
|
-
headline_ar: hero.headline_ar ?? "",
|
|
33
|
-
subtitle: hero.subtitle ?? "",
|
|
34
|
-
background_image: hero.hero_image_url ?? "",
|
|
35
|
-
cta_text: hero.cta_text ?? "",
|
|
36
|
-
cta_link: hero.cta_link ?? ""
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
order.push("hero_1");
|
|
40
|
-
}
|
|
41
|
-
const products = safeRaw.products;
|
|
42
|
-
if (products) {
|
|
43
|
-
sections["featured_1"] = {
|
|
44
|
-
type: "featured-products",
|
|
45
|
-
settings: products
|
|
46
|
-
};
|
|
47
|
-
order.push("featured_1");
|
|
48
|
-
}
|
|
49
|
-
const templates = {};
|
|
50
|
-
if (Object.keys(sections).length > 0) {
|
|
51
|
-
templates["home"] = { name: "Home", sections, order };
|
|
52
|
-
}
|
|
53
|
-
const sectionGroups = {
|
|
54
|
-
header: {
|
|
55
|
-
name: "Header Group",
|
|
56
|
-
sections: {
|
|
57
|
-
header_1: {
|
|
58
|
-
type: "header",
|
|
59
|
-
settings: safeRaw.header || {}
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
order: ["header_1"]
|
|
63
|
-
},
|
|
64
|
-
footer: {
|
|
65
|
-
name: "Footer Group",
|
|
66
|
-
sections: {
|
|
67
|
-
footer_1: {
|
|
68
|
-
type: "footer",
|
|
69
|
-
settings: safeRaw.footer || {}
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
order: ["footer_1"]
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
let externalTheme = null;
|
|
76
|
-
const ext = safeRaw.external_theme;
|
|
77
|
-
if (ext && typeof ext === "object" && typeof ext.bundle_url === "string" && ext.bundle_url) {
|
|
78
|
-
externalTheme = {
|
|
79
|
-
bundle_url: ext.bundle_url,
|
|
80
|
-
css_url: typeof ext.css_url === "string" ? ext.css_url : null,
|
|
81
|
-
mode: typeof ext.mode === "string" ? ext.mode : "production"
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
schema_version: 3,
|
|
86
|
-
theme_id: themeId,
|
|
87
|
-
global_settings: globalSettings,
|
|
88
|
-
templates,
|
|
89
|
-
section_groups: sectionGroups,
|
|
90
|
-
external_theme: externalTheme
|
|
91
|
-
};
|
|
92
|
-
}
|
|
3
|
+
var chunkTBSNHHFH_cjs = require('./chunk-TBSNHHFH.cjs');
|
|
93
4
|
|
|
94
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "resolveThemeSettings", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkTBSNHHFH_cjs.resolveThemeSettings; }
|
|
10
|
+
});
|
|
95
11
|
//# sourceMappingURL=normalize.cjs.map
|
|
96
12
|
//# sourceMappingURL=normalize.cjs.map
|
package/dist/normalize.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"normalize.cjs"}
|
package/dist/normalize.d.mts
CHANGED
package/dist/normalize.d.ts
CHANGED
package/dist/normalize.mjs
CHANGED
|
@@ -1,94 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
var DEFAULT_THEME_ID = typeof process !== "undefined" && process.env?.NUMU_DEFAULT_THEME_ID || "modern";
|
|
3
|
-
function resolveThemeSettings(raw) {
|
|
4
|
-
const safeRaw = raw ?? {};
|
|
5
|
-
if (safeRaw.schema_version === 3) {
|
|
6
|
-
return safeRaw;
|
|
7
|
-
}
|
|
8
|
-
const themeBlock = safeRaw.theme || {};
|
|
9
|
-
const themeId = typeof themeBlock.base_theme === "string" && themeBlock.base_theme || DEFAULT_THEME_ID;
|
|
10
|
-
const globalSettings = {};
|
|
11
|
-
for (const key of [
|
|
12
|
-
"primary_color",
|
|
13
|
-
"secondary_color",
|
|
14
|
-
"font_family",
|
|
15
|
-
"logo_url"
|
|
16
|
-
]) {
|
|
17
|
-
if (themeBlock[key] !== void 0) globalSettings[key] = themeBlock[key];
|
|
18
|
-
}
|
|
19
|
-
if (safeRaw.identity) globalSettings.identity = safeRaw.identity;
|
|
20
|
-
const sections = {};
|
|
21
|
-
const order = [];
|
|
22
|
-
const hero = safeRaw.hero;
|
|
23
|
-
if (hero) {
|
|
24
|
-
sections["hero_1"] = {
|
|
25
|
-
type: "hero",
|
|
26
|
-
settings: {
|
|
27
|
-
// Mirrors backend `normalize_legacy_to_v3` exactly — includes
|
|
28
|
-
// headline_ar so Arabic content survives the round-trip.
|
|
29
|
-
headline: hero.headline ?? "",
|
|
30
|
-
headline_ar: hero.headline_ar ?? "",
|
|
31
|
-
subtitle: hero.subtitle ?? "",
|
|
32
|
-
background_image: hero.hero_image_url ?? "",
|
|
33
|
-
cta_text: hero.cta_text ?? "",
|
|
34
|
-
cta_link: hero.cta_link ?? ""
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
order.push("hero_1");
|
|
38
|
-
}
|
|
39
|
-
const products = safeRaw.products;
|
|
40
|
-
if (products) {
|
|
41
|
-
sections["featured_1"] = {
|
|
42
|
-
type: "featured-products",
|
|
43
|
-
settings: products
|
|
44
|
-
};
|
|
45
|
-
order.push("featured_1");
|
|
46
|
-
}
|
|
47
|
-
const templates = {};
|
|
48
|
-
if (Object.keys(sections).length > 0) {
|
|
49
|
-
templates["home"] = { name: "Home", sections, order };
|
|
50
|
-
}
|
|
51
|
-
const sectionGroups = {
|
|
52
|
-
header: {
|
|
53
|
-
name: "Header Group",
|
|
54
|
-
sections: {
|
|
55
|
-
header_1: {
|
|
56
|
-
type: "header",
|
|
57
|
-
settings: safeRaw.header || {}
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
order: ["header_1"]
|
|
61
|
-
},
|
|
62
|
-
footer: {
|
|
63
|
-
name: "Footer Group",
|
|
64
|
-
sections: {
|
|
65
|
-
footer_1: {
|
|
66
|
-
type: "footer",
|
|
67
|
-
settings: safeRaw.footer || {}
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
order: ["footer_1"]
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
let externalTheme = null;
|
|
74
|
-
const ext = safeRaw.external_theme;
|
|
75
|
-
if (ext && typeof ext === "object" && typeof ext.bundle_url === "string" && ext.bundle_url) {
|
|
76
|
-
externalTheme = {
|
|
77
|
-
bundle_url: ext.bundle_url,
|
|
78
|
-
css_url: typeof ext.css_url === "string" ? ext.css_url : null,
|
|
79
|
-
mode: typeof ext.mode === "string" ? ext.mode : "production"
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
schema_version: 3,
|
|
84
|
-
theme_id: themeId,
|
|
85
|
-
global_settings: globalSettings,
|
|
86
|
-
templates,
|
|
87
|
-
section_groups: sectionGroups,
|
|
88
|
-
external_theme: externalTheme
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export { resolveThemeSettings };
|
|
1
|
+
export { resolveThemeSettings } from './chunk-XF2FGIVS.mjs';
|
|
93
2
|
//# sourceMappingURL=normalize.mjs.map
|
|
94
3
|
//# sourceMappingURL=normalize.mjs.map
|
package/dist/normalize.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"normalize.mjs"}
|
|
@@ -179,9 +179,35 @@ interface SectionPreset {
|
|
|
179
179
|
settings?: Record<string, any>;
|
|
180
180
|
blocks?: PresetBlock[];
|
|
181
181
|
}
|
|
182
|
-
/**
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Section component props.
|
|
184
|
+
*
|
|
185
|
+
* Generic over the settings shape so a theme can type its own settings
|
|
186
|
+
* without hand-rolling a parallel props interface (the `EmpSectionProps`
|
|
187
|
+
* pattern every theme was duplicating). `id`/`type` mirror the section
|
|
188
|
+
* instance's key + `SectionInstance.type` so a component can key React
|
|
189
|
+
* lists, dispatch on type, or emit editor anchors without threading them
|
|
190
|
+
* separately; `groupId` names the owning `SectionGroup` for header/footer
|
|
191
|
+
* group sections (absent for template sections).
|
|
192
|
+
*
|
|
193
|
+
* // Loosely typed (default) — settings is Record<string, unknown>:
|
|
194
|
+
* function Hero(props: SectionProps) { … }
|
|
195
|
+
*
|
|
196
|
+
* // Strongly typed:
|
|
197
|
+
* interface HeroSettings { headline: string; show_cta: boolean }
|
|
198
|
+
* function Hero({ settings }: SectionProps<HeroSettings>) {
|
|
199
|
+
* return <h1>{settings.headline}</h1>;
|
|
200
|
+
* }
|
|
201
|
+
*/
|
|
202
|
+
interface SectionProps<S = Record<string, unknown>> {
|
|
203
|
+
/** The section instance's key within its template/group. */
|
|
204
|
+
id: string;
|
|
205
|
+
/** The section's `type` (its schema type / component name). */
|
|
206
|
+
type: string;
|
|
207
|
+
/** Owning section-group id for header/footer group sections; absent for
|
|
208
|
+
* template-level sections. */
|
|
209
|
+
groupId?: string;
|
|
210
|
+
settings: S;
|
|
185
211
|
blocks?: Record<string, BlockInstance>;
|
|
186
212
|
blockOrder?: string[];
|
|
187
213
|
storeData?: any;
|
|
@@ -179,9 +179,35 @@ interface SectionPreset {
|
|
|
179
179
|
settings?: Record<string, any>;
|
|
180
180
|
blocks?: PresetBlock[];
|
|
181
181
|
}
|
|
182
|
-
/**
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Section component props.
|
|
184
|
+
*
|
|
185
|
+
* Generic over the settings shape so a theme can type its own settings
|
|
186
|
+
* without hand-rolling a parallel props interface (the `EmpSectionProps`
|
|
187
|
+
* pattern every theme was duplicating). `id`/`type` mirror the section
|
|
188
|
+
* instance's key + `SectionInstance.type` so a component can key React
|
|
189
|
+
* lists, dispatch on type, or emit editor anchors without threading them
|
|
190
|
+
* separately; `groupId` names the owning `SectionGroup` for header/footer
|
|
191
|
+
* group sections (absent for template sections).
|
|
192
|
+
*
|
|
193
|
+
* // Loosely typed (default) — settings is Record<string, unknown>:
|
|
194
|
+
* function Hero(props: SectionProps) { … }
|
|
195
|
+
*
|
|
196
|
+
* // Strongly typed:
|
|
197
|
+
* interface HeroSettings { headline: string; show_cta: boolean }
|
|
198
|
+
* function Hero({ settings }: SectionProps<HeroSettings>) {
|
|
199
|
+
* return <h1>{settings.headline}</h1>;
|
|
200
|
+
* }
|
|
201
|
+
*/
|
|
202
|
+
interface SectionProps<S = Record<string, unknown>> {
|
|
203
|
+
/** The section instance's key within its template/group. */
|
|
204
|
+
id: string;
|
|
205
|
+
/** The section's `type` (its schema type / component name). */
|
|
206
|
+
type: string;
|
|
207
|
+
/** Owning section-group id for header/footer group sections; absent for
|
|
208
|
+
* template-level sections. */
|
|
209
|
+
groupId?: string;
|
|
210
|
+
settings: S;
|
|
185
211
|
blocks?: Record<string, BlockInstance>;
|
|
186
212
|
blockOrder?: string[];
|
|
187
213
|
storeData?: any;
|
package/dist/types.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { A as Address, C as Cart, a as CartItem, b as Collection, c as Customer, O as Order, d as OrderItem, P as Page, e as Product, f as ProductImage, g as ProductVariant, S as SizeChart, h as SizeChartMode, i as Store } from './entities-
|
|
2
|
-
export { B as BlockInstance, a as BlockProps, b as BlockSchema, E as ExternalThemeMetadata, P as PageTemplate, S as SectionGroup, c as SectionInstance, d as SectionPreset, e as SectionProps, f as SectionSchema, g as SettingDefinition, T as ThemeSettingsV3 } from './theme-
|
|
1
|
+
export { A as Address, C as Cart, a as CartItem, b as Collection, c as Customer, O as Order, d as OrderItem, P as Page, e as Product, f as ProductImage, g as ProductVariant, S as SizeChart, h as SizeChartMode, i as Store } from './entities-B8378GKp.mjs';
|
|
2
|
+
export { B as BlockInstance, a as BlockProps, b as BlockSchema, E as ExternalThemeMetadata, P as PageTemplate, S as SectionGroup, c as SectionInstance, d as SectionPreset, e as SectionProps, f as SectionSchema, g as SettingDefinition, T as ThemeSettingsV3 } from './theme-CNTB4KnU.mjs';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { A as Address, C as Cart, a as CartItem, b as Collection, c as Customer, O as Order, d as OrderItem, P as Page, e as Product, f as ProductImage, g as ProductVariant, S as SizeChart, h as SizeChartMode, i as Store } from './entities-
|
|
2
|
-
export { B as BlockInstance, a as BlockProps, b as BlockSchema, E as ExternalThemeMetadata, P as PageTemplate, S as SectionGroup, c as SectionInstance, d as SectionPreset, e as SectionProps, f as SectionSchema, g as SettingDefinition, T as ThemeSettingsV3 } from './theme-
|
|
1
|
+
export { A as Address, C as Cart, a as CartItem, b as Collection, c as Customer, O as Order, d as OrderItem, P as Page, e as Product, f as ProductImage, g as ProductVariant, S as SizeChart, h as SizeChartMode, i as Store } from './entities-B8378GKp.js';
|
|
2
|
+
export { B as BlockInstance, a as BlockProps, b as BlockSchema, E as ExternalThemeMetadata, P as PageTemplate, S as SectionGroup, c as SectionInstance, d as SectionPreset, e as SectionProps, f as SectionSchema, g as SettingDefinition, T as ThemeSettingsV3 } from './theme-CNTB4KnU.js';
|