@wocart/theme 1.4.0 → 1.5.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 +57 -0
- package/README.md +286 -17
- package/dist/astro/InstanceView.astro +21 -5
- package/dist/astro/index.d.ts +15 -14
- package/dist/astro/index.js +44 -0
- package/dist/composition.d.ts +17 -0
- package/dist/composition.js +60 -0
- package/dist/definitions.js +305 -6
- package/dist/index.d.ts +18 -5
- package/dist/index.js +12 -4
- package/dist/instances.d.ts +7 -1
- package/dist/instances.js +251 -13
- package/dist/manifest-diff.d.ts +14 -0
- package/dist/manifest-diff.js +160 -0
- package/dist/manifest.d.ts +192 -19
- package/dist/manifest.js +77 -16
- package/dist/operations.d.ts +71 -0
- package/dist/operations.js +377 -0
- package/dist/page-data.js +29 -2
- package/dist/preview-bridge.d.ts +28 -0
- package/dist/preview-bridge.js +317 -0
- package/dist/preview-protocol.d.ts +100 -0
- package/dist/preview-protocol.js +51 -0
- package/dist/rich-text.d.ts +31 -0
- package/dist/rich-text.js +233 -0
- package/dist/schemas.d.ts +21 -0
- package/dist/schemas.js +35 -2
- package/dist/types.d.ts +259 -15
- package/dist/version.d.ts +7 -0
- package/dist/version.js +7 -0
- package/package.json +7 -2
package/dist/manifest.d.ts
CHANGED
|
@@ -9,9 +9,15 @@
|
|
|
9
9
|
* so the manifest and assembly validators cannot disagree.
|
|
10
10
|
*/
|
|
11
11
|
import { z } from "zod";
|
|
12
|
-
import type { ThemeDefinition, ThemeManifest, ThemeManifestResult } from "./types.js";
|
|
12
|
+
import type { PageData, PresetInstance, SurfacePageType, RichTextFormat, RichTextValue, ThemeDefinition, ThemeManifest, ThemeManifestResult } from "./types.js";
|
|
13
13
|
/** Version of the manifest schema and its interpretation (not the theme's). */
|
|
14
14
|
export declare const THEME_MANIFEST_CONTRACT_VERSION: 1;
|
|
15
|
+
/**
|
|
16
|
+
* Where a built theme serves its manifest: a prerendered page at this path
|
|
17
|
+
* (`src/pages/wocart-theme.json.ts`), so the file is part of every build and
|
|
18
|
+
* a release can read it without running the theme.
|
|
19
|
+
*/
|
|
20
|
+
export declare const THEME_MANIFEST_PATH = "/wocart-theme.json";
|
|
15
21
|
/** Derive the data-only manifest from a theme. `component` and `load` are dropped. */
|
|
16
22
|
export declare function themeManifest(theme: ThemeDefinition): ThemeManifest;
|
|
17
23
|
/**
|
|
@@ -23,9 +29,12 @@ export declare const ThemeManifestSchema: z.ZodObject<{
|
|
|
23
29
|
contractVersion: z.ZodLiteral<1>;
|
|
24
30
|
key: z.ZodString;
|
|
25
31
|
version: z.ZodString;
|
|
32
|
+
sdkVersion: z.ZodExactOptional<z.ZodString>;
|
|
26
33
|
surfaces: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
27
34
|
key: z.ZodString;
|
|
28
35
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
36
|
+
pageType: z.ZodExactOptional<z.ZodCustom<SurfacePageType, SurfacePageType>>;
|
|
37
|
+
document: z.ZodExactOptional<z.ZodCustom<PageData, PageData>>;
|
|
29
38
|
}, z.core.$strip>>>;
|
|
30
39
|
locales: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
31
40
|
settings: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -56,6 +65,7 @@ export declare const ThemeManifestSchema: z.ZodObject<{
|
|
|
56
65
|
default: z.ZodExactOptional<z.ZodNumber>;
|
|
57
66
|
min: z.ZodExactOptional<z.ZodNumber>;
|
|
58
67
|
max: z.ZodExactOptional<z.ZodNumber>;
|
|
68
|
+
step: z.ZodExactOptional<z.ZodNumber>;
|
|
59
69
|
}, z.core.$strip>, z.ZodObject<{
|
|
60
70
|
key: z.ZodString;
|
|
61
71
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
@@ -70,37 +80,110 @@ export declare const ThemeManifestSchema: z.ZodObject<{
|
|
|
70
80
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
71
81
|
kind: z.ZodLiteral<"select">;
|
|
72
82
|
options: z.ZodArray<z.ZodString>;
|
|
83
|
+
optionLabels: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
|
|
73
84
|
default: z.ZodExactOptional<z.ZodString>;
|
|
74
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
85
|
+
}, z.core.$strip>, ...z.ZodObject<{
|
|
75
86
|
key: z.ZodString;
|
|
76
87
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
77
88
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
78
89
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
79
|
-
kind: z.ZodLiteral<"url">;
|
|
90
|
+
kind: z.ZodLiteral<"category" | "collection" | "color" | "menu" | "product" | "url">;
|
|
80
91
|
default: z.ZodExactOptional<z.ZodString>;
|
|
81
|
-
}, z.core.$strip
|
|
92
|
+
}, z.core.$strip>[], z.ZodObject<{
|
|
82
93
|
key: z.ZodString;
|
|
83
94
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
84
95
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
85
96
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
86
|
-
kind: z.ZodLiteral<"
|
|
87
|
-
default: z.ZodExactOptional<z.ZodString>;
|
|
97
|
+
kind: z.ZodLiteral<"image">;
|
|
88
98
|
}, z.core.$strip>, z.ZodObject<{
|
|
89
99
|
key: z.ZodString;
|
|
90
100
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
91
101
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
92
102
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
93
|
-
kind: z.ZodLiteral<"
|
|
94
|
-
|
|
103
|
+
kind: z.ZodLiteral<"richtext">;
|
|
104
|
+
formats: z.ZodExactOptional<z.ZodArray<z.ZodCustom<RichTextFormat, RichTextFormat>>>;
|
|
105
|
+
default: z.ZodExactOptional<z.ZodCustom<RichTextValue, RichTextValue>>;
|
|
95
106
|
}, z.core.$strip>, z.ZodObject<{
|
|
96
107
|
key: z.ZodString;
|
|
97
108
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
98
109
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
99
110
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
100
|
-
kind: z.ZodLiteral<"
|
|
101
|
-
|
|
111
|
+
kind: z.ZodLiteral<"list">;
|
|
112
|
+
fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
113
|
+
key: z.ZodString;
|
|
114
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
115
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
116
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
117
|
+
contentKey: z.ZodExactOptional<z.ZodString>;
|
|
118
|
+
default: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
119
|
+
kind: z.ZodLiteral<"text">;
|
|
120
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
121
|
+
key: z.ZodString;
|
|
122
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
123
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
124
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
125
|
+
contentKey: z.ZodExactOptional<z.ZodString>;
|
|
126
|
+
default: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
127
|
+
kind: z.ZodLiteral<"textarea">;
|
|
128
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
129
|
+
key: z.ZodString;
|
|
130
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
131
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
132
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
133
|
+
kind: z.ZodLiteral<"number">;
|
|
134
|
+
default: z.ZodExactOptional<z.ZodNumber>;
|
|
135
|
+
min: z.ZodExactOptional<z.ZodNumber>;
|
|
136
|
+
max: z.ZodExactOptional<z.ZodNumber>;
|
|
137
|
+
step: z.ZodExactOptional<z.ZodNumber>;
|
|
138
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
139
|
+
key: z.ZodString;
|
|
140
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
141
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
142
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
143
|
+
kind: z.ZodLiteral<"boolean">;
|
|
144
|
+
default: z.ZodExactOptional<z.ZodBoolean>;
|
|
145
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
146
|
+
key: z.ZodString;
|
|
147
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
148
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
149
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
150
|
+
kind: z.ZodLiteral<"select">;
|
|
151
|
+
options: z.ZodArray<z.ZodString>;
|
|
152
|
+
optionLabels: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
|
|
153
|
+
default: z.ZodExactOptional<z.ZodString>;
|
|
154
|
+
}, z.core.$strip>, ...z.ZodObject<{
|
|
155
|
+
key: z.ZodString;
|
|
156
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
157
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
158
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
159
|
+
kind: z.ZodLiteral<"category" | "collection" | "color" | "menu" | "product" | "url">;
|
|
160
|
+
default: z.ZodExactOptional<z.ZodString>;
|
|
161
|
+
}, z.core.$strip>[], z.ZodObject<{
|
|
162
|
+
key: z.ZodString;
|
|
163
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
164
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
165
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
166
|
+
kind: z.ZodLiteral<"image">;
|
|
167
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
168
|
+
key: z.ZodString;
|
|
169
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
170
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
171
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
172
|
+
kind: z.ZodLiteral<"richtext">;
|
|
173
|
+
formats: z.ZodExactOptional<z.ZodArray<z.ZodCustom<RichTextFormat, RichTextFormat>>>;
|
|
174
|
+
default: z.ZodExactOptional<z.ZodCustom<RichTextValue, RichTextValue>>;
|
|
175
|
+
}, z.core.$strip>], "kind">>;
|
|
176
|
+
min: z.ZodExactOptional<z.ZodNumber>;
|
|
177
|
+
max: z.ZodExactOptional<z.ZodNumber>;
|
|
178
|
+
default: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
|
|
179
|
+
id: z.ZodString;
|
|
180
|
+
props: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodType<import("./types.js").JsonValue, unknown, z.core.$ZodTypeInternals<import("./types.js").JsonValue, unknown>>>>;
|
|
181
|
+
}, z.core.$strip>>>;
|
|
182
|
+
itemLabel: z.ZodExactOptional<z.ZodString>;
|
|
102
183
|
}, z.core.$strip>], "kind">>;
|
|
103
184
|
}, z.core.$strip>>>;
|
|
185
|
+
content: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
186
|
+
preview: z.ZodDefault<z.ZodBoolean>;
|
|
104
187
|
components: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
105
188
|
type: z.ZodString;
|
|
106
189
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
@@ -130,6 +213,7 @@ export declare const ThemeManifestSchema: z.ZodObject<{
|
|
|
130
213
|
default: z.ZodExactOptional<z.ZodNumber>;
|
|
131
214
|
min: z.ZodExactOptional<z.ZodNumber>;
|
|
132
215
|
max: z.ZodExactOptional<z.ZodNumber>;
|
|
216
|
+
step: z.ZodExactOptional<z.ZodNumber>;
|
|
133
217
|
}, z.core.$strip>, z.ZodObject<{
|
|
134
218
|
key: z.ZodString;
|
|
135
219
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
@@ -144,35 +228,106 @@ export declare const ThemeManifestSchema: z.ZodObject<{
|
|
|
144
228
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
145
229
|
kind: z.ZodLiteral<"select">;
|
|
146
230
|
options: z.ZodArray<z.ZodString>;
|
|
231
|
+
optionLabels: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
|
|
147
232
|
default: z.ZodExactOptional<z.ZodString>;
|
|
148
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
233
|
+
}, z.core.$strip>, ...z.ZodObject<{
|
|
149
234
|
key: z.ZodString;
|
|
150
235
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
151
236
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
152
237
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
153
|
-
kind: z.ZodLiteral<"url">;
|
|
238
|
+
kind: z.ZodLiteral<"category" | "collection" | "color" | "menu" | "product" | "url">;
|
|
154
239
|
default: z.ZodExactOptional<z.ZodString>;
|
|
155
|
-
}, z.core.$strip
|
|
240
|
+
}, z.core.$strip>[], z.ZodObject<{
|
|
156
241
|
key: z.ZodString;
|
|
157
242
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
158
243
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
159
244
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
160
|
-
kind: z.ZodLiteral<"
|
|
161
|
-
default: z.ZodExactOptional<z.ZodString>;
|
|
245
|
+
kind: z.ZodLiteral<"image">;
|
|
162
246
|
}, z.core.$strip>, z.ZodObject<{
|
|
163
247
|
key: z.ZodString;
|
|
164
248
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
165
249
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
166
250
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
167
|
-
kind: z.ZodLiteral<"
|
|
168
|
-
|
|
251
|
+
kind: z.ZodLiteral<"richtext">;
|
|
252
|
+
formats: z.ZodExactOptional<z.ZodArray<z.ZodCustom<RichTextFormat, RichTextFormat>>>;
|
|
253
|
+
default: z.ZodExactOptional<z.ZodCustom<RichTextValue, RichTextValue>>;
|
|
169
254
|
}, z.core.$strip>, z.ZodObject<{
|
|
170
255
|
key: z.ZodString;
|
|
171
256
|
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
172
257
|
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
173
258
|
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
174
|
-
kind: z.ZodLiteral<"
|
|
175
|
-
|
|
259
|
+
kind: z.ZodLiteral<"list">;
|
|
260
|
+
fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
261
|
+
key: z.ZodString;
|
|
262
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
263
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
264
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
265
|
+
contentKey: z.ZodExactOptional<z.ZodString>;
|
|
266
|
+
default: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
267
|
+
kind: z.ZodLiteral<"text">;
|
|
268
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
269
|
+
key: z.ZodString;
|
|
270
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
271
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
272
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
273
|
+
contentKey: z.ZodExactOptional<z.ZodString>;
|
|
274
|
+
default: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
275
|
+
kind: z.ZodLiteral<"textarea">;
|
|
276
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
277
|
+
key: z.ZodString;
|
|
278
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
279
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
280
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
281
|
+
kind: z.ZodLiteral<"number">;
|
|
282
|
+
default: z.ZodExactOptional<z.ZodNumber>;
|
|
283
|
+
min: z.ZodExactOptional<z.ZodNumber>;
|
|
284
|
+
max: z.ZodExactOptional<z.ZodNumber>;
|
|
285
|
+
step: z.ZodExactOptional<z.ZodNumber>;
|
|
286
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
287
|
+
key: z.ZodString;
|
|
288
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
289
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
290
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
291
|
+
kind: z.ZodLiteral<"boolean">;
|
|
292
|
+
default: z.ZodExactOptional<z.ZodBoolean>;
|
|
293
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
294
|
+
key: z.ZodString;
|
|
295
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
296
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
297
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
298
|
+
kind: z.ZodLiteral<"select">;
|
|
299
|
+
options: z.ZodArray<z.ZodString>;
|
|
300
|
+
optionLabels: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
|
|
301
|
+
default: z.ZodExactOptional<z.ZodString>;
|
|
302
|
+
}, z.core.$strip>, ...z.ZodObject<{
|
|
303
|
+
key: z.ZodString;
|
|
304
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
305
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
306
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
307
|
+
kind: z.ZodLiteral<"category" | "collection" | "color" | "menu" | "product" | "url">;
|
|
308
|
+
default: z.ZodExactOptional<z.ZodString>;
|
|
309
|
+
}, z.core.$strip>[], z.ZodObject<{
|
|
310
|
+
key: z.ZodString;
|
|
311
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
312
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
313
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
314
|
+
kind: z.ZodLiteral<"image">;
|
|
315
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
316
|
+
key: z.ZodString;
|
|
317
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
318
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
319
|
+
required: z.ZodExactOptional<z.ZodBoolean>;
|
|
320
|
+
kind: z.ZodLiteral<"richtext">;
|
|
321
|
+
formats: z.ZodExactOptional<z.ZodArray<z.ZodCustom<RichTextFormat, RichTextFormat>>>;
|
|
322
|
+
default: z.ZodExactOptional<z.ZodCustom<RichTextValue, RichTextValue>>;
|
|
323
|
+
}, z.core.$strip>], "kind">>;
|
|
324
|
+
min: z.ZodExactOptional<z.ZodNumber>;
|
|
325
|
+
max: z.ZodExactOptional<z.ZodNumber>;
|
|
326
|
+
default: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
|
|
327
|
+
id: z.ZodString;
|
|
328
|
+
props: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodType<import("./types.js").JsonValue, unknown, z.core.$ZodTypeInternals<import("./types.js").JsonValue, unknown>>>>;
|
|
329
|
+
}, z.core.$strip>>>;
|
|
330
|
+
itemLabel: z.ZodExactOptional<z.ZodString>;
|
|
176
331
|
}, z.core.$strip>], "kind">>>;
|
|
177
332
|
slots: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
178
333
|
name: z.ZodString;
|
|
@@ -181,7 +336,16 @@ export declare const ThemeManifestSchema: z.ZodObject<{
|
|
|
181
336
|
}, z.core.$strip>>>;
|
|
182
337
|
capabilities: z.ZodExactOptional<z.ZodObject<{
|
|
183
338
|
insertable: z.ZodExactOptional<z.ZodBoolean>;
|
|
339
|
+
surfaces: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
|
|
184
340
|
}, z.core.$strip>>;
|
|
341
|
+
presets: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
342
|
+
key: z.ZodString;
|
|
343
|
+
label: z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>;
|
|
344
|
+
description: z.ZodExactOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
345
|
+
props: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodType<import("./types.js").JsonValue, unknown, z.core.$ZodTypeInternals<import("./types.js").JsonValue, unknown>>>>;
|
|
346
|
+
children: z.ZodExactOptional<z.ZodArray<z.ZodType<PresetInstance, unknown, z.core.$ZodTypeInternals<PresetInstance, unknown>>>>;
|
|
347
|
+
slots: z.ZodExactOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodType<PresetInstance, unknown, z.core.$ZodTypeInternals<PresetInstance, unknown>>>>>;
|
|
348
|
+
}, z.core.$strip>>>;
|
|
185
349
|
}, z.core.$strip>>;
|
|
186
350
|
}, z.core.$strip>;
|
|
187
351
|
/**
|
|
@@ -190,3 +354,12 @@ export declare const ThemeManifestSchema: z.ZodObject<{
|
|
|
190
354
|
* returns the manifest with an `invalid-version` issue.
|
|
191
355
|
*/
|
|
192
356
|
export declare function validateThemeManifest(input: unknown): ThemeManifestResult;
|
|
357
|
+
/**
|
|
358
|
+
* A manifest as a catalog every data function takes — `createInstance`,
|
|
359
|
+
* `instantiatePreset`, the document operations, `checkPageData`,
|
|
360
|
+
* `validatePageData`, `resolveThemeSettings`, `checkThemeSettings` — so an
|
|
361
|
+
* editor or a tool works from a theme's manifest alone, never its code.
|
|
362
|
+
* Components carry no implementation (`component: null`): the catalog
|
|
363
|
+
* describes and checks; it does not render.
|
|
364
|
+
*/
|
|
365
|
+
export declare function manifestCatalog(manifest: ThemeManifest): ThemeDefinition;
|
package/dist/manifest.js
CHANGED
|
@@ -10,8 +10,16 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { validateThemeDefinition } from "./definitions.js";
|
|
13
|
+
import { JsonValueSchema } from "./schemas.js";
|
|
14
|
+
import { THEME_SDK_VERSION } from "./version.js";
|
|
13
15
|
/** Version of the manifest schema and its interpretation (not the theme's). */
|
|
14
16
|
export const THEME_MANIFEST_CONTRACT_VERSION = 1;
|
|
17
|
+
/**
|
|
18
|
+
* Where a built theme serves its manifest: a prerendered page at this path
|
|
19
|
+
* (`src/pages/wocart-theme.json.ts`), so the file is part of every build and
|
|
20
|
+
* a release can read it without running the theme.
|
|
21
|
+
*/
|
|
22
|
+
export const THEME_MANIFEST_PATH = "/wocart-theme.json";
|
|
15
23
|
const SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
16
24
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17
25
|
// ── Derivation ───────────────────────────────────────────────────────────────
|
|
@@ -21,12 +29,17 @@ export function themeManifest(theme) {
|
|
|
21
29
|
contractVersion: THEME_MANIFEST_CONTRACT_VERSION,
|
|
22
30
|
key: theme.key,
|
|
23
31
|
version: theme.version,
|
|
32
|
+
sdkVersion: THEME_SDK_VERSION,
|
|
24
33
|
surfaces: (theme.surfaces ?? []).map((surface) => ({
|
|
25
34
|
key: surface.key,
|
|
26
35
|
label: copyData(surface.label),
|
|
36
|
+
...(surface.pageType === undefined ? {} : { pageType: surface.pageType }),
|
|
37
|
+
...(surface.document === undefined ? {} : { document: copyData(surface.document) }),
|
|
27
38
|
})),
|
|
28
39
|
locales: [...(theme.locales ?? [])],
|
|
29
40
|
settings: (theme.settings ?? []).map((group) => copyData(group)),
|
|
41
|
+
content: copyData(theme.content ?? {}),
|
|
42
|
+
preview: theme.preview === true,
|
|
30
43
|
components: Object.fromEntries(Object.entries(theme.components).map(([key, definition]) => [
|
|
31
44
|
key,
|
|
32
45
|
componentSpec(definition),
|
|
@@ -43,6 +56,7 @@ function componentSpec(definition) {
|
|
|
43
56
|
...(definition.capabilities === undefined
|
|
44
57
|
? {}
|
|
45
58
|
: { capabilities: copyData(definition.capabilities) }),
|
|
59
|
+
presets: (definition.presets ?? []).map((preset) => copyData(preset)),
|
|
46
60
|
};
|
|
47
61
|
}
|
|
48
62
|
/**
|
|
@@ -67,7 +81,7 @@ const TextFieldSchema = z.object({
|
|
|
67
81
|
contentKey: z.exactOptional(z.string()),
|
|
68
82
|
default: z.exactOptional(LocalizedTextSchema),
|
|
69
83
|
});
|
|
70
|
-
const
|
|
84
|
+
const ScalarFieldSchemas = [
|
|
71
85
|
TextFieldSchema.extend({ kind: z.literal("text") }),
|
|
72
86
|
TextFieldSchema.extend({ kind: z.literal("textarea") }),
|
|
73
87
|
z.object({
|
|
@@ -76,6 +90,7 @@ const FieldSchema = z.discriminatedUnion("kind", [
|
|
|
76
90
|
default: z.exactOptional(z.number()),
|
|
77
91
|
min: z.exactOptional(z.number()),
|
|
78
92
|
max: z.exactOptional(z.number()),
|
|
93
|
+
step: z.exactOptional(z.number()),
|
|
79
94
|
}),
|
|
80
95
|
z.object({
|
|
81
96
|
...FieldCommonSchema,
|
|
@@ -86,29 +101,45 @@ const FieldSchema = z.discriminatedUnion("kind", [
|
|
|
86
101
|
...FieldCommonSchema,
|
|
87
102
|
kind: z.literal("select"),
|
|
88
103
|
options: z.array(z.string()),
|
|
104
|
+
optionLabels: z.exactOptional(z.record(z.string(), LocalizedTextSchema)),
|
|
89
105
|
default: z.exactOptional(z.string()),
|
|
90
106
|
}),
|
|
91
|
-
z.object({
|
|
107
|
+
...["url", "color", "menu", "collection", "product", "category"].map((kind) => z.object({
|
|
92
108
|
...FieldCommonSchema,
|
|
93
|
-
kind: z.literal(
|
|
109
|
+
kind: z.literal(kind),
|
|
94
110
|
default: z.exactOptional(z.string()),
|
|
95
|
-
}),
|
|
111
|
+
})),
|
|
96
112
|
z.object({
|
|
97
113
|
...FieldCommonSchema,
|
|
98
|
-
kind: z.literal("
|
|
99
|
-
default: z.exactOptional(z.string()),
|
|
114
|
+
kind: z.literal("image"),
|
|
100
115
|
}),
|
|
101
116
|
z.object({
|
|
102
117
|
...FieldCommonSchema,
|
|
103
|
-
kind: z.literal("
|
|
104
|
-
|
|
118
|
+
kind: z.literal("richtext"),
|
|
119
|
+
formats: z.exactOptional(z.array(z.custom((value) => typeof value === "string"))),
|
|
120
|
+
// The document's own rules are relational; `validateThemeDefinition` checks them.
|
|
121
|
+
default: z.exactOptional(z.custom((value) => typeof value === "object" && value !== null)),
|
|
105
122
|
}),
|
|
123
|
+
];
|
|
124
|
+
const ItemFieldSchema = z.discriminatedUnion("kind", [...ScalarFieldSchemas]);
|
|
125
|
+
const FieldSchema = z.discriminatedUnion("kind", [
|
|
126
|
+
...ScalarFieldSchemas,
|
|
106
127
|
z.object({
|
|
107
128
|
...FieldCommonSchema,
|
|
108
|
-
kind: z.literal("
|
|
109
|
-
|
|
129
|
+
kind: z.literal("list"),
|
|
130
|
+
fields: z.array(ItemFieldSchema),
|
|
131
|
+
min: z.exactOptional(z.number()),
|
|
132
|
+
max: z.exactOptional(z.number()),
|
|
133
|
+
default: z.exactOptional(z.array(z.object({ id: z.string(), props: z.exactOptional(z.record(z.string(), JsonValueSchema)) }))),
|
|
134
|
+
itemLabel: z.exactOptional(z.string()),
|
|
110
135
|
}),
|
|
111
136
|
]);
|
|
137
|
+
const PresetInstanceSchema = z.lazy(() => z.object({
|
|
138
|
+
type: z.string(),
|
|
139
|
+
props: z.exactOptional(z.record(z.string(), JsonValueSchema)),
|
|
140
|
+
children: z.exactOptional(z.array(PresetInstanceSchema)),
|
|
141
|
+
slots: z.exactOptional(z.record(z.string(), z.array(PresetInstanceSchema))),
|
|
142
|
+
}));
|
|
112
143
|
const ComponentSpecSchema = z.object({
|
|
113
144
|
type: z.string(),
|
|
114
145
|
label: LocalizedTextSchema,
|
|
@@ -121,7 +152,20 @@ const ComponentSpecSchema = z.object({
|
|
|
121
152
|
allow: z.exactOptional(z.array(z.string())),
|
|
122
153
|
}))
|
|
123
154
|
.default([]),
|
|
124
|
-
capabilities: z.exactOptional(z.object({
|
|
155
|
+
capabilities: z.exactOptional(z.object({
|
|
156
|
+
insertable: z.exactOptional(z.boolean()),
|
|
157
|
+
surfaces: z.exactOptional(z.array(z.string())),
|
|
158
|
+
})),
|
|
159
|
+
presets: z
|
|
160
|
+
.array(z.object({
|
|
161
|
+
key: z.string(),
|
|
162
|
+
label: LocalizedTextSchema,
|
|
163
|
+
description: z.exactOptional(LocalizedTextSchema),
|
|
164
|
+
props: z.exactOptional(z.record(z.string(), JsonValueSchema)),
|
|
165
|
+
children: z.exactOptional(z.array(PresetInstanceSchema)),
|
|
166
|
+
slots: z.exactOptional(z.record(z.string(), z.array(PresetInstanceSchema))),
|
|
167
|
+
}))
|
|
168
|
+
.default([]),
|
|
125
169
|
});
|
|
126
170
|
/**
|
|
127
171
|
* The manifest's structural shape. Unknown keys are stripped (the forward-compat
|
|
@@ -132,13 +176,22 @@ export const ThemeManifestSchema = z.object({
|
|
|
132
176
|
contractVersion: z.literal(THEME_MANIFEST_CONTRACT_VERSION),
|
|
133
177
|
key: z.string(),
|
|
134
178
|
version: z.string(),
|
|
179
|
+
sdkVersion: z.exactOptional(z.string()),
|
|
135
180
|
surfaces: z
|
|
136
|
-
.array(z.object({
|
|
181
|
+
.array(z.object({
|
|
182
|
+
key: z.string(),
|
|
183
|
+
label: LocalizedTextSchema,
|
|
184
|
+
pageType: z.exactOptional(z.custom((value) => typeof value === "string")),
|
|
185
|
+
// A page document's own rules are checked by `validateThemeDefinition` on the probe.
|
|
186
|
+
document: z.exactOptional(z.custom((value) => isRecord(value))),
|
|
187
|
+
}))
|
|
137
188
|
.default([]),
|
|
138
189
|
locales: z.array(z.string()).default([]),
|
|
139
190
|
settings: z
|
|
140
191
|
.array(z.object({ key: z.string(), label: LocalizedTextSchema, fields: z.array(FieldSchema) }))
|
|
141
192
|
.default([]),
|
|
193
|
+
content: z.record(z.string(), z.record(z.string(), z.string())).default({}),
|
|
194
|
+
preview: z.boolean().default(false),
|
|
142
195
|
components: z.record(z.string(), ComponentSpecSchema),
|
|
143
196
|
});
|
|
144
197
|
// ── Validation ───────────────────────────────────────────────────────────────
|
|
@@ -168,7 +221,7 @@ export function validateThemeManifest(input) {
|
|
|
168
221
|
return { manifest: null, issues };
|
|
169
222
|
}
|
|
170
223
|
const manifest = parsed.data;
|
|
171
|
-
const issues = validateThemeDefinition(
|
|
224
|
+
const issues = validateThemeDefinition(manifestCatalog(manifest)).map((issue) => ({
|
|
172
225
|
path: issue.path,
|
|
173
226
|
code: issue.code === "type-mismatch" ? "type-mismatch" : codeAt(issue.path),
|
|
174
227
|
message: issue.message,
|
|
@@ -198,6 +251,8 @@ function codeAt(path) {
|
|
|
198
251
|
return "invalid-surface";
|
|
199
252
|
if (path === "settings" || path.startsWith("settings["))
|
|
200
253
|
return "invalid-settings";
|
|
254
|
+
if (path === "content" || path.startsWith("content."))
|
|
255
|
+
return "invalid-content";
|
|
201
256
|
if (path.startsWith("components."))
|
|
202
257
|
return "invalid-component";
|
|
203
258
|
return "invalid-manifest";
|
|
@@ -211,16 +266,22 @@ function toPath(segments) {
|
|
|
211
266
|
}, "");
|
|
212
267
|
}
|
|
213
268
|
/**
|
|
214
|
-
*
|
|
215
|
-
*
|
|
269
|
+
* A manifest as a catalog every data function takes — `createInstance`,
|
|
270
|
+
* `instantiatePreset`, the document operations, `checkPageData`,
|
|
271
|
+
* `validatePageData`, `resolveThemeSettings`, `checkThemeSettings` — so an
|
|
272
|
+
* editor or a tool works from a theme's manifest alone, never its code.
|
|
273
|
+
* Components carry no implementation (`component: null`): the catalog
|
|
274
|
+
* describes and checks; it does not render.
|
|
216
275
|
*/
|
|
217
|
-
function
|
|
276
|
+
export function manifestCatalog(manifest) {
|
|
218
277
|
return {
|
|
219
278
|
key: manifest.key,
|
|
220
279
|
version: manifest.version,
|
|
221
280
|
surfaces: manifest.surfaces,
|
|
222
281
|
locales: manifest.locales,
|
|
223
282
|
settings: manifest.settings,
|
|
283
|
+
content: manifest.content,
|
|
284
|
+
preview: manifest.preview,
|
|
224
285
|
components: Object.fromEntries(Object.entries(manifest.components).map(([key, spec]) => [
|
|
225
286
|
key,
|
|
226
287
|
{ ...spec, component: null },
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ComponentInstance, JsonValue, PageData, ThemeDefinition } from "./types.js";
|
|
2
|
+
export type DocumentIssueCode = "invalid-document" | "invalid-instance" | "invalid-index" | "invalid-props" | "unknown-instance" | "unknown-type" | "unknown-slot" | "duplicate-id" | "not-insertable" | "not-available" | "not-allowed" | "slot-full" | "cycle";
|
|
3
|
+
/** Why a document or a change is refused; `path` points into the document. */
|
|
4
|
+
export interface DocumentIssue {
|
|
5
|
+
path: string;
|
|
6
|
+
code: DocumentIssueCode;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
export type DocumentEdit = {
|
|
10
|
+
ok: true;
|
|
11
|
+
page: PageData;
|
|
12
|
+
} | {
|
|
13
|
+
ok: false;
|
|
14
|
+
issue: DocumentIssue;
|
|
15
|
+
};
|
|
16
|
+
/** Where an instance goes: a parent's slot (absent: the top-level sections) at an index (absent: the end). */
|
|
17
|
+
export interface InstancePlacement {
|
|
18
|
+
parent?: string;
|
|
19
|
+
/** Absent or `"default"`: the parent's children. */
|
|
20
|
+
slot?: string;
|
|
21
|
+
index?: number;
|
|
22
|
+
}
|
|
23
|
+
/** Where an instance is: its parent (`null` at the top level), its slot and its index there. */
|
|
24
|
+
export interface InstanceLocation {
|
|
25
|
+
instance: ComponentInstance;
|
|
26
|
+
parent: string | null;
|
|
27
|
+
slot: string | null;
|
|
28
|
+
index: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A new instance id: `cmp_` and 16 random hex digits. Operations refuse an id
|
|
32
|
+
* the document already holds, so a collision is reported, never written.
|
|
33
|
+
*/
|
|
34
|
+
export declare function newInstanceId(): string;
|
|
35
|
+
/** Where `id` is in the document, or `null`. */
|
|
36
|
+
export declare function findInstance(page: PageData, id: string): InstanceLocation | null;
|
|
37
|
+
/**
|
|
38
|
+
* Insert a new instance — from `createInstance` or `instantiatePreset` — at a
|
|
39
|
+
* placement. Refused when the component is not insertable or not available on
|
|
40
|
+
* the document's surface, when the slot does not take it, or when any id is
|
|
41
|
+
* already in the document.
|
|
42
|
+
*/
|
|
43
|
+
export declare function insertInstance(theme: ThemeDefinition, page: PageData, instance: ComponentInstance, placement?: InstancePlacement): DocumentEdit;
|
|
44
|
+
/** Remove an instance and everything inside it. */
|
|
45
|
+
export declare function removeInstance(page: PageData, id: string): DocumentEdit;
|
|
46
|
+
/**
|
|
47
|
+
* Move an instance (with everything inside it) to a placement. `index` counts
|
|
48
|
+
* positions in the destination after the instance has left its old place.
|
|
49
|
+
*/
|
|
50
|
+
export declare function moveInstance(theme: ThemeDefinition, page: PageData, id: string, placement?: InstancePlacement): DocumentEdit;
|
|
51
|
+
/**
|
|
52
|
+
* Copy an instance and everything inside it right after the original, every
|
|
53
|
+
* copied instance with an id from `newId`. List items keep their ids: they
|
|
54
|
+
* are unique within their list, not the document.
|
|
55
|
+
*/
|
|
56
|
+
export declare function duplicateInstance(theme: ThemeDefinition, page: PageData, id: string, newId: () => string): DocumentEdit;
|
|
57
|
+
/**
|
|
58
|
+
* Change an instance's props: each value is checked by its field;
|
|
59
|
+
* `undefined` removes the stored value, so the field falls back to its
|
|
60
|
+
* content-pack text or default.
|
|
61
|
+
*/
|
|
62
|
+
export declare function setInstanceProps(theme: ThemeDefinition, page: PageData, id: string, changes: Readonly<Record<string, JsonValue | undefined>>): DocumentEdit;
|
|
63
|
+
/** Switch an instance off (kept, not rendered) or back on. */
|
|
64
|
+
export declare function setInstanceHidden(page: PageData, id: string, hidden: boolean): DocumentEdit;
|
|
65
|
+
/**
|
|
66
|
+
* Everything a writer must fix before saving a document for this theme —
|
|
67
|
+
* the strict counterpart of `validatePageData`: an envelope for one of the
|
|
68
|
+
* theme's surfaces when it declares any, and every section a tree the
|
|
69
|
+
* operations would have built. An empty list means the document may be saved.
|
|
70
|
+
*/
|
|
71
|
+
export declare function checkPageData(theme: ThemeDefinition, input: unknown): DocumentIssue[];
|