@jxsuite/schema 1.2.0 → 1.4.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/LICENSE +21 -0
- package/class-schema.json +104 -1
- package/defs/children-value.schema.ts +10 -1
- package/defs/class-def.schema.ts +108 -1
- package/defs/element-def.schema.ts +15 -2
- package/defs/external-class-def.schema.ts +14 -1
- package/defs/function-def.schema.ts +8 -0
- package/defs/index.ts +4 -0
- package/defs/project-config.schema.ts +3 -2
- package/defs/style-object.schema.ts +4 -10
- package/package.json +1 -1
- package/project-schema.json +20 -2
- package/schema.json +1053 -19
- package/schemas/project.core.schema.json +20 -2
- package/src/asset-paths.ts +137 -2
- package/src/extension-registry.ts +5 -0
- package/src/format-registry.ts +4 -2
- package/src/guards.ts +10 -0
- package/src/schema.ts +41 -3
- package/src/validate-project.ts +13 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kevin Shenk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/class-schema.json
CHANGED
|
@@ -176,7 +176,17 @@
|
|
|
176
176
|
"parse",
|
|
177
177
|
"serialize",
|
|
178
178
|
"discover",
|
|
179
|
-
"load"
|
|
179
|
+
"load",
|
|
180
|
+
"projectData",
|
|
181
|
+
"resolvePaths",
|
|
182
|
+
"lower",
|
|
183
|
+
"emit",
|
|
184
|
+
"assets",
|
|
185
|
+
"mount",
|
|
186
|
+
"dialect",
|
|
187
|
+
"deploySchema",
|
|
188
|
+
"bindings",
|
|
189
|
+
"testConnection"
|
|
180
190
|
],
|
|
181
191
|
"type": "string"
|
|
182
192
|
},
|
|
@@ -237,6 +247,40 @@
|
|
|
237
247
|
],
|
|
238
248
|
"type": "object"
|
|
239
249
|
},
|
|
250
|
+
"ConnectorBlockDef": {
|
|
251
|
+
"description": "Connection-provider admission block (specs/extensions.md §12). A class carrying this block provides database connections of the given provider/kind.",
|
|
252
|
+
"properties": {
|
|
253
|
+
"kind": {
|
|
254
|
+
"description": "SQL dialect family the provider speaks.",
|
|
255
|
+
"enum": [
|
|
256
|
+
"sqlite",
|
|
257
|
+
"postgres"
|
|
258
|
+
],
|
|
259
|
+
"type": "string"
|
|
260
|
+
},
|
|
261
|
+
"local": {
|
|
262
|
+
"description": "Local-development substitute provider (e.g. sqlite for D1).",
|
|
263
|
+
"type": "string"
|
|
264
|
+
},
|
|
265
|
+
"module": {
|
|
266
|
+
"description": "Module specifier exporting the provider implementation.",
|
|
267
|
+
"type": "string"
|
|
268
|
+
},
|
|
269
|
+
"provider": {
|
|
270
|
+
"description": "Provider identifier (e.g. d1, supabase, sqlite).",
|
|
271
|
+
"type": "string"
|
|
272
|
+
},
|
|
273
|
+
"serve": {
|
|
274
|
+
"description": "Module specifier exporting the serve-time worker binding.",
|
|
275
|
+
"type": "string"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"required": [
|
|
279
|
+
"provider",
|
|
280
|
+
"kind"
|
|
281
|
+
],
|
|
282
|
+
"type": "object"
|
|
283
|
+
},
|
|
240
284
|
"FormatDef": {
|
|
241
285
|
"description": "Format participation marker. A class carrying this block is auto-discovered from the project imports map and used for file-extension dispatch by the compiler, server, and studio.",
|
|
242
286
|
"properties": {
|
|
@@ -279,6 +323,56 @@
|
|
|
279
323
|
],
|
|
280
324
|
"type": "object"
|
|
281
325
|
},
|
|
326
|
+
"ProjectBlockDef": {
|
|
327
|
+
"additionalProperties": false,
|
|
328
|
+
"description": "Project-section admission block (specs/extensions.md §9). A class carrying this block owns the project.json section named by `key`; hosts dispatch that section's data through the class's projectData/resolvePaths capabilities.",
|
|
329
|
+
"properties": {
|
|
330
|
+
"description": {
|
|
331
|
+
"type": "string"
|
|
332
|
+
},
|
|
333
|
+
"key": {
|
|
334
|
+
"description": "The project.json top-level section this class owns (exclusive per project).",
|
|
335
|
+
"type": "string"
|
|
336
|
+
},
|
|
337
|
+
"referenceable": {
|
|
338
|
+
"description": "Whether section entries can be referenced from documents (e.g. content types).",
|
|
339
|
+
"type": "boolean"
|
|
340
|
+
},
|
|
341
|
+
"title": {
|
|
342
|
+
"type": "string"
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
"required": [
|
|
346
|
+
"key"
|
|
347
|
+
],
|
|
348
|
+
"type": "object"
|
|
349
|
+
},
|
|
350
|
+
"ServerBlockDef": {
|
|
351
|
+
"additionalProperties": false,
|
|
352
|
+
"description": "Server-mount admission block (specs/extensions.md §11). A class carrying this block mounts routes under its /_jx/ basePath in the site worker and dev server.",
|
|
353
|
+
"properties": {
|
|
354
|
+
"basePath": {
|
|
355
|
+
"description": "Route subtree this class mounts — must be under /_jx/ (exclusive per project).",
|
|
356
|
+
"examples": [
|
|
357
|
+
"/_jx/data",
|
|
358
|
+
"/_jx/auth"
|
|
359
|
+
],
|
|
360
|
+
"type": "string"
|
|
361
|
+
},
|
|
362
|
+
"module": {
|
|
363
|
+
"description": "Module specifier exporting the mount handler.",
|
|
364
|
+
"type": "string"
|
|
365
|
+
},
|
|
366
|
+
"order": {
|
|
367
|
+
"description": "Mount order (ascending; default 100).",
|
|
368
|
+
"type": "number"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"required": [
|
|
372
|
+
"basePath"
|
|
373
|
+
],
|
|
374
|
+
"type": "object"
|
|
375
|
+
},
|
|
282
376
|
"StudioHints": {
|
|
283
377
|
"description": "Studio control-surface hints for a format class: editor modes, document-mode rules, templates, and the element/nesting constraints that gate structural editing.",
|
|
284
378
|
"properties": {
|
|
@@ -442,6 +536,9 @@
|
|
|
442
536
|
"$studio": {
|
|
443
537
|
"$ref": "#/$defs/StudioHints"
|
|
444
538
|
},
|
|
539
|
+
"connector": {
|
|
540
|
+
"$ref": "#/$defs/ConnectorBlockDef"
|
|
541
|
+
},
|
|
445
542
|
"description": {
|
|
446
543
|
"type": "string"
|
|
447
544
|
},
|
|
@@ -468,6 +565,12 @@
|
|
|
468
565
|
"format": {
|
|
469
566
|
"$ref": "#/$defs/FormatDef"
|
|
470
567
|
},
|
|
568
|
+
"project": {
|
|
569
|
+
"$ref": "#/$defs/ProjectBlockDef"
|
|
570
|
+
},
|
|
571
|
+
"server": {
|
|
572
|
+
"$ref": "#/$defs/ServerBlockDef"
|
|
573
|
+
},
|
|
471
574
|
"title": {
|
|
472
575
|
"description": "PascalCase class name, used as the export name.",
|
|
473
576
|
"examples": [
|
|
@@ -18,7 +18,8 @@ export const childrenValueSchema = {
|
|
|
18
18
|
description:
|
|
19
19
|
"Array of child definitions — elements, text, or Array namespaces (dynamic lists) mixed " +
|
|
20
20
|
"freely. A bare Array namespace (the whole children slot is one dynamic list) is also " +
|
|
21
|
-
"accepted for backward compatibility
|
|
21
|
+
"accepted for backward compatibility, as is a ${…} template string that resolves at build " +
|
|
22
|
+
"time to an array of child definitions.",
|
|
22
23
|
oneOf: [
|
|
23
24
|
{
|
|
24
25
|
items: {
|
|
@@ -32,5 +33,13 @@ export const childrenValueSchema = {
|
|
|
32
33
|
type: "array",
|
|
33
34
|
},
|
|
34
35
|
{ $ref: "#/$defs/ArrayNamespace" },
|
|
36
|
+
{
|
|
37
|
+
description:
|
|
38
|
+
"Computed children — a ${…} template that resolves at build time to an array of child " +
|
|
39
|
+
'definitions (e.g. "${state.entry.$children}" for parsed content). A bare plain-text ' +
|
|
40
|
+
"string is NOT a valid children value; text children must be array items.",
|
|
41
|
+
pattern: "\\$\\{",
|
|
42
|
+
type: "string",
|
|
43
|
+
},
|
|
35
44
|
],
|
|
36
45
|
} as const;
|
package/defs/class-def.schema.ts
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Method capability roles: "method"/"accessor" plus every static capability role hosts dispatch on
|
|
3
|
+
* (format-registry EXTENSION_CAPABILITIES — specs/extensions.md §8). Kept as a literal tuple so
|
|
4
|
+
* FromSchema inference stays precise; the drift-guard test in tests/class-schema-drift.test.ts
|
|
5
|
+
* asserts parity with EXTENSION_CAPABILITIES.
|
|
6
|
+
*/
|
|
7
|
+
export const CLASS_METHOD_ROLES = [
|
|
8
|
+
"method",
|
|
9
|
+
"accessor",
|
|
10
|
+
"parse",
|
|
11
|
+
"serialize",
|
|
12
|
+
"discover",
|
|
13
|
+
"load",
|
|
14
|
+
"projectData",
|
|
15
|
+
"resolvePaths",
|
|
16
|
+
"lower",
|
|
17
|
+
"emit",
|
|
18
|
+
"assets",
|
|
19
|
+
"mount",
|
|
20
|
+
"dialect",
|
|
21
|
+
"deploySchema",
|
|
22
|
+
"bindings",
|
|
23
|
+
"testConnection",
|
|
24
|
+
] as const;
|
|
25
|
+
|
|
1
26
|
export const classParameterDefSchema = {
|
|
2
27
|
description: "A typed parameter definition for a class.",
|
|
3
28
|
properties: {
|
|
@@ -100,7 +125,7 @@ export const classMethodDefSchema = {
|
|
|
100
125
|
},
|
|
101
126
|
returnType: {},
|
|
102
127
|
role: {
|
|
103
|
-
enum:
|
|
128
|
+
enum: CLASS_METHOD_ROLES,
|
|
104
129
|
type: "string",
|
|
105
130
|
},
|
|
106
131
|
scope: { enum: ["instance", "static"], type: "string" },
|
|
@@ -157,6 +182,85 @@ export const formatDefSchema = {
|
|
|
157
182
|
type: "object",
|
|
158
183
|
} as const;
|
|
159
184
|
|
|
185
|
+
export const projectBlockDefSchema = {
|
|
186
|
+
additionalProperties: false,
|
|
187
|
+
description:
|
|
188
|
+
"Project-section admission block (specs/extensions.md §9). A class carrying this block owns " +
|
|
189
|
+
"the project.json section named by `key`; hosts dispatch that section's data through the " +
|
|
190
|
+
"class's projectData/resolvePaths capabilities.",
|
|
191
|
+
properties: {
|
|
192
|
+
description: { type: "string" },
|
|
193
|
+
key: {
|
|
194
|
+
description: "The project.json top-level section this class owns (exclusive per project).",
|
|
195
|
+
type: "string",
|
|
196
|
+
},
|
|
197
|
+
referenceable: {
|
|
198
|
+
description: "Whether section entries can be referenced from documents (e.g. content types).",
|
|
199
|
+
type: "boolean",
|
|
200
|
+
},
|
|
201
|
+
title: { type: "string" },
|
|
202
|
+
},
|
|
203
|
+
required: ["key"],
|
|
204
|
+
type: "object",
|
|
205
|
+
} as const;
|
|
206
|
+
|
|
207
|
+
export const serverBlockDefSchema = {
|
|
208
|
+
additionalProperties: false,
|
|
209
|
+
description:
|
|
210
|
+
"Server-mount admission block (specs/extensions.md §11). A class carrying this block mounts " +
|
|
211
|
+
"routes under its /_jx/ basePath in the site worker and dev server.",
|
|
212
|
+
properties: {
|
|
213
|
+
basePath: {
|
|
214
|
+
description: "Route subtree this class mounts — must be under /_jx/ (exclusive per project).",
|
|
215
|
+
examples: ["/_jx/data", "/_jx/auth"],
|
|
216
|
+
type: "string",
|
|
217
|
+
},
|
|
218
|
+
module: {
|
|
219
|
+
description: "Module specifier exporting the mount handler.",
|
|
220
|
+
type: "string",
|
|
221
|
+
},
|
|
222
|
+
order: {
|
|
223
|
+
description: "Mount order (ascending; default 100).",
|
|
224
|
+
type: "number",
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
required: ["basePath"],
|
|
228
|
+
type: "object",
|
|
229
|
+
} as const;
|
|
230
|
+
|
|
231
|
+
export const connectorBlockDefSchema = {
|
|
232
|
+
// Open by design: the block mirrors format-registry's ConnectorBlock ([key: string]: unknown) —
|
|
233
|
+
// Providers carry extra keys (e.g. D1's `module`), so additionalProperties stays true.
|
|
234
|
+
description:
|
|
235
|
+
"Connection-provider admission block (specs/extensions.md §12). A class carrying this block " +
|
|
236
|
+
"provides database connections of the given provider/kind.",
|
|
237
|
+
properties: {
|
|
238
|
+
kind: {
|
|
239
|
+
description: "SQL dialect family the provider speaks.",
|
|
240
|
+
enum: ["sqlite", "postgres"],
|
|
241
|
+
type: "string",
|
|
242
|
+
},
|
|
243
|
+
local: {
|
|
244
|
+
description: "Local-development substitute provider (e.g. sqlite for D1).",
|
|
245
|
+
type: "string",
|
|
246
|
+
},
|
|
247
|
+
module: {
|
|
248
|
+
description: "Module specifier exporting the provider implementation.",
|
|
249
|
+
type: "string",
|
|
250
|
+
},
|
|
251
|
+
provider: {
|
|
252
|
+
description: "Provider identifier (e.g. d1, supabase, sqlite).",
|
|
253
|
+
type: "string",
|
|
254
|
+
},
|
|
255
|
+
serve: {
|
|
256
|
+
description: "Module specifier exporting the serve-time worker binding.",
|
|
257
|
+
type: "string",
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
required: ["provider", "kind"],
|
|
261
|
+
type: "object",
|
|
262
|
+
} as const;
|
|
263
|
+
|
|
160
264
|
export const studioHintsSchema = {
|
|
161
265
|
description:
|
|
162
266
|
"Studio control-surface hints for a format class: editor modes, document-mode rules, " +
|
|
@@ -258,6 +362,7 @@ export const classDefSchema = {
|
|
|
258
362
|
$prototype: { const: "Class", type: "string" },
|
|
259
363
|
$schema: { type: "string" },
|
|
260
364
|
$studio: { $ref: "#/$defs/StudioHints" },
|
|
365
|
+
connector: { $ref: "#/$defs/ConnectorBlockDef" },
|
|
261
366
|
description: { type: "string" },
|
|
262
367
|
extends: {
|
|
263
368
|
description: "Base class — string name or $ref to another .class.json.",
|
|
@@ -267,6 +372,8 @@ export const classDefSchema = {
|
|
|
267
372
|
],
|
|
268
373
|
},
|
|
269
374
|
format: { $ref: "#/$defs/FormatDef" },
|
|
375
|
+
project: { $ref: "#/$defs/ProjectBlockDef" },
|
|
376
|
+
server: { $ref: "#/$defs/ServerBlockDef" },
|
|
270
377
|
title: {
|
|
271
378
|
description: "PascalCase class name, used as the export name.",
|
|
272
379
|
type: "string",
|
|
@@ -12,8 +12,10 @@ export const attributesObjectSchema = {
|
|
|
12
12
|
} as const;
|
|
13
13
|
|
|
14
14
|
export const propsObjectSchema = {
|
|
15
|
+
// AnyOf, not oneOf: a RefObject value legitimately matches both the plain-object branch and
|
|
16
|
+
// The RefObject branch, and exclusive matching would reject every $ref-bound prop.
|
|
15
17
|
additionalProperties: {
|
|
16
|
-
|
|
18
|
+
anyOf: [
|
|
17
19
|
{ type: "string" },
|
|
18
20
|
{ type: "number" },
|
|
19
21
|
{ type: "boolean" },
|
|
@@ -39,7 +41,9 @@ export const elementPropertyValueSchema = {
|
|
|
39
41
|
export const switchDefSchema = {
|
|
40
42
|
additionalProperties: false,
|
|
41
43
|
description: "Reactive $ref that drives which case to render.",
|
|
42
|
-
|
|
44
|
+
// The discriminant is a reactive state path (e.g. "#/state/currentRoute") resolved by
|
|
45
|
+
// ResolveRef at render time — not a #/$defs/ type pointer.
|
|
46
|
+
properties: { $ref: { $ref: "#/$defs/StateRef" } },
|
|
43
47
|
required: ["$ref"],
|
|
44
48
|
type: "object",
|
|
45
49
|
} as const;
|
|
@@ -70,6 +74,15 @@ export const elementDefSchema = {
|
|
|
70
74
|
$switch: { $ref: "#/$defs/SwitchDef" },
|
|
71
75
|
alt: { $ref: "#/$defs/StringOrRef" },
|
|
72
76
|
attributes: { $ref: "#/$defs/AttributesObject" },
|
|
77
|
+
cases: {
|
|
78
|
+
additionalProperties: {
|
|
79
|
+
oneOf: [{ $ref: "#/$defs/ElementDef" }, { $ref: "#/$defs/ExternalComponentRef" }],
|
|
80
|
+
},
|
|
81
|
+
description:
|
|
82
|
+
"Switch cases for this element. Maps case values to element definitions or external " +
|
|
83
|
+
"component refs, rendered according to the reactive $switch discriminant.",
|
|
84
|
+
type: "object",
|
|
85
|
+
},
|
|
73
86
|
checked: { $ref: "#/$defs/BoolOrRef" },
|
|
74
87
|
children: { $ref: "#/$defs/ChildrenValue" },
|
|
75
88
|
className: { $ref: "#/$defs/StringOrRef" },
|
|
@@ -92,7 +92,20 @@ export const externalClassDefSchema = {
|
|
|
92
92
|
},
|
|
93
93
|
sameSite: { enum: ["strict", "lax", "none"], type: "string" },
|
|
94
94
|
secure: { type: "boolean" },
|
|
95
|
-
sort: {
|
|
95
|
+
sort: {
|
|
96
|
+
anyOf: [
|
|
97
|
+
{ $ref: "#/$defs/RefObject" },
|
|
98
|
+
{ description: "A single sort rule, e.g. { field, order }.", type: "object" },
|
|
99
|
+
{
|
|
100
|
+
description: 'Ordered sort rules, e.g. [{ field: "date", order: "desc" }].',
|
|
101
|
+
items: { type: "object" },
|
|
102
|
+
type: "array",
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
description:
|
|
106
|
+
"Sort configuration: a reactive $ref binding, a single { field, order } rule, or an " +
|
|
107
|
+
"ordered array of rules.",
|
|
108
|
+
},
|
|
96
109
|
src: {
|
|
97
110
|
description: "Configuration property passed to external class constructor.",
|
|
98
111
|
type: "string",
|
|
@@ -15,6 +15,14 @@ export const functionDefSchema = {
|
|
|
15
15
|
examples: ["./counter.js", "npm:@myorg/validators"],
|
|
16
16
|
type: "string",
|
|
17
17
|
},
|
|
18
|
+
arguments: {
|
|
19
|
+
description:
|
|
20
|
+
"Legacy alias for parameters: bare string parameter names (state may be listed " +
|
|
21
|
+
"explicitly as the first name). Superseded by parameters.",
|
|
22
|
+
examples: [["state", "event"]],
|
|
23
|
+
items: { type: "string" },
|
|
24
|
+
type: "array",
|
|
25
|
+
},
|
|
18
26
|
body: {
|
|
19
27
|
description:
|
|
20
28
|
"Inline function body: an opaque JS source string (first implicit parameter is state), or a structured statement array (spec §20) — explicit structured function declaration, analyzable by tooling and editable visually. The escalation ladder within the shape is structured statements → JS string.",
|
package/defs/index.ts
CHANGED
|
@@ -69,12 +69,16 @@ export {
|
|
|
69
69
|
|
|
70
70
|
// Class definitions
|
|
71
71
|
export {
|
|
72
|
+
CLASS_METHOD_ROLES,
|
|
72
73
|
classParameterDefSchema,
|
|
73
74
|
classFieldDefSchema,
|
|
74
75
|
classConstructorDefSchema,
|
|
75
76
|
classMethodDefSchema,
|
|
76
77
|
classDefSchema,
|
|
78
|
+
connectorBlockDefSchema,
|
|
77
79
|
formatDefSchema,
|
|
80
|
+
projectBlockDefSchema,
|
|
81
|
+
serverBlockDefSchema,
|
|
78
82
|
studioHintsSchema,
|
|
79
83
|
} from "./class-def.schema";
|
|
80
84
|
|
|
@@ -233,11 +233,12 @@ export const projectConfigSchema = {
|
|
|
233
233
|
},
|
|
234
234
|
style: {
|
|
235
235
|
additionalProperties: {
|
|
236
|
-
oneOf: [{ type: "string" }, { type: "number" }, {
|
|
236
|
+
oneOf: [{ type: "string" }, { type: "number" }, { $ref: "#/$defs/StyleObject" }],
|
|
237
237
|
},
|
|
238
238
|
description:
|
|
239
239
|
"Global CSS styles applied to the <body> element. " +
|
|
240
|
-
"Uses the same camelCase CSSOM convention
|
|
240
|
+
"Uses the same camelCase CSSOM convention and recursive selector/at-rule " +
|
|
241
|
+
"nesting as component styles.",
|
|
241
242
|
type: "object",
|
|
242
243
|
},
|
|
243
244
|
url: {
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
export const styleObjectSchema = {
|
|
2
2
|
additionalProperties: {
|
|
3
|
-
oneOf: [
|
|
4
|
-
{ type: "string" },
|
|
5
|
-
{ type: "number" },
|
|
6
|
-
{
|
|
7
|
-
additionalProperties: { oneOf: [{ type: "string" }, { type: "number" }] },
|
|
8
|
-
description: "Nested CSS selector or media breakpoint rules.",
|
|
9
|
-
type: "object",
|
|
10
|
-
},
|
|
11
|
-
],
|
|
3
|
+
oneOf: [{ type: "string" }, { type: "number" }, { $ref: "#/$defs/StyleObject" }],
|
|
12
4
|
},
|
|
13
5
|
description:
|
|
14
6
|
"CSS style definition. camelCase property names follow CSSOM convention. " +
|
|
15
7
|
"Keys starting with :, ., &, or [ are treated as nested CSS selectors. " +
|
|
16
|
-
"Keys matching $media breakpoint names
|
|
8
|
+
"Keys matching $media breakpoint names (or other @-prefixed at-rules) group nested rules. " +
|
|
9
|
+
"Nesting is recursive: selector and at-rule groups may nest to arbitrary depth " +
|
|
10
|
+
"(e.g. breakpoint → selector → pseudo-class), mirroring the compiler's recursive emission.",
|
|
17
11
|
properties: {},
|
|
18
12
|
type: "object",
|
|
19
13
|
} as const;
|
package/package.json
CHANGED
package/project-schema.json
CHANGED
|
@@ -58,6 +58,24 @@
|
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"type": "object"
|
|
61
|
+
},
|
|
62
|
+
"StyleObject": {
|
|
63
|
+
"additionalProperties": {
|
|
64
|
+
"oneOf": [
|
|
65
|
+
{
|
|
66
|
+
"type": "string"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"type": "number"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"$ref": "#/$defs/StyleObject"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
"description": "CSS style definition. camelCase property names follow CSSOM convention. Keys starting with :, ., &, or [ are treated as nested CSS selectors. Keys matching $media breakpoint names (or other @-prefixed at-rules) group nested rules. Nesting is recursive: selector and at-rule groups may nest to arbitrary depth (e.g. breakpoint → selector → pseudo-class), mirroring the compiler's recursive emission.",
|
|
77
|
+
"properties": {},
|
|
78
|
+
"type": "object"
|
|
61
79
|
}
|
|
62
80
|
},
|
|
63
81
|
"$id": "https://jxsuite.com/schema/project/v1",
|
|
@@ -360,11 +378,11 @@
|
|
|
360
378
|
"type": "number"
|
|
361
379
|
},
|
|
362
380
|
{
|
|
363
|
-
"
|
|
381
|
+
"$ref": "#/$defs/StyleObject"
|
|
364
382
|
}
|
|
365
383
|
]
|
|
366
384
|
},
|
|
367
|
-
"description": "Global CSS styles applied to the <body> element. Uses the same camelCase CSSOM convention as component styles.",
|
|
385
|
+
"description": "Global CSS styles applied to the <body> element. Uses the same camelCase CSSOM convention and recursive selector/at-rule nesting as component styles.",
|
|
368
386
|
"type": "object"
|
|
369
387
|
},
|
|
370
388
|
"url": {
|