desen-core 1.0.0-draft
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/.turbo/turbo-build.log +5 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +40 -0
- package/dist/schemas/action.d.ts +3 -0
- package/dist/schemas/action.js +14 -0
- package/dist/schemas/binding.d.ts +91 -0
- package/dist/schemas/binding.js +31 -0
- package/dist/schemas/composition.d.ts +51 -0
- package/dist/schemas/composition.js +99 -0
- package/dist/schemas/element.d.ts +759 -0
- package/dist/schemas/element.js +29 -0
- package/dist/schemas/style.d.ts +192 -0
- package/dist/schemas/style.js +69 -0
- package/dist/schemas/surface.d.ts +39 -0
- package/dist/schemas/surface.js +19 -0
- package/dist/schemas/telemetry.d.ts +32 -0
- package/dist/schemas/telemetry.js +20 -0
- package/dist/schemas/token.d.ts +24 -0
- package/dist/schemas/token.js +36 -0
- package/package.json +17 -0
- package/src/index.ts +63 -0
- package/src/schemas/action.ts +17 -0
- package/src/schemas/binding.ts +38 -0
- package/src/schemas/composition.ts +131 -0
- package/src/schemas/element.ts +36 -0
- package/src/schemas/style.ts +77 -0
- package/src/schemas/surface.ts +20 -0
- package/src/schemas/telemetry.ts +23 -0
- package/src/schemas/token.ts +48 -0
- package/test-schemas.js +62 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.elementSpec = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const binding_1 = require("./binding");
|
|
6
|
+
const telemetry_1 = require("./telemetry");
|
|
7
|
+
// ─── ElementSpec ─────────────────────────────────────────────────
|
|
8
|
+
// SPEC.md §2.2: type, id, props REQUIRED.
|
|
9
|
+
//
|
|
10
|
+
// CRITICAL RULE: ElementSpec MUST NOT contain `children` or `layout`.
|
|
11
|
+
// These belong exclusively to CompositionSpec (§2.3).
|
|
12
|
+
// Enforced via .refine() to reject any payload with these fields.
|
|
13
|
+
exports.elementSpec = zod_1.z.object({
|
|
14
|
+
type: zod_1.z.string().min(1),
|
|
15
|
+
id: zod_1.z.string().min(1),
|
|
16
|
+
props: zod_1.z.record(zod_1.z.any()),
|
|
17
|
+
constraints: zod_1.z.object({
|
|
18
|
+
a11y: zod_1.z.object({
|
|
19
|
+
aria_label: zod_1.z.string().optional(),
|
|
20
|
+
aria_role: zod_1.z.string().optional(),
|
|
21
|
+
min_contrast_ratio: zod_1.z.number().min(1).optional(),
|
|
22
|
+
focusable: zod_1.z.boolean().optional(),
|
|
23
|
+
}).optional(),
|
|
24
|
+
}).passthrough().optional(),
|
|
25
|
+
modifiers: binding_1.modifiersSpec.optional(),
|
|
26
|
+
telemetry: telemetry_1.telemetrySpec.optional(),
|
|
27
|
+
}).passthrough()
|
|
28
|
+
.refine((data) => !("children" in data), { message: "ElementSpec MUST NOT contain 'children'. Use CompositionSpec for containers." })
|
|
29
|
+
.refine((data) => !("layout" in data), { message: "ElementSpec MUST NOT contain 'layout'. Use CompositionSpec for layout." });
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const styleSpec: z.ZodObject<{
|
|
3
|
+
bg_color: z.ZodOptional<z.ZodString>;
|
|
4
|
+
bg_color_token: z.ZodOptional<z.ZodString>;
|
|
5
|
+
text_color: z.ZodOptional<z.ZodString>;
|
|
6
|
+
text_color_token: z.ZodOptional<z.ZodString>;
|
|
7
|
+
border_color: z.ZodOptional<z.ZodString>;
|
|
8
|
+
border_color_token: z.ZodOptional<z.ZodString>;
|
|
9
|
+
font_family: z.ZodOptional<z.ZodString>;
|
|
10
|
+
font_family_token: z.ZodOptional<z.ZodString>;
|
|
11
|
+
font_size: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
font_size_token: z.ZodOptional<z.ZodString>;
|
|
13
|
+
font_weight: z.ZodOptional<z.ZodNumber>;
|
|
14
|
+
font_weight_token: z.ZodOptional<z.ZodString>;
|
|
15
|
+
line_height: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
line_height_token: z.ZodOptional<z.ZodString>;
|
|
17
|
+
padding: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
|
18
|
+
top: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
right: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
bottom: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
left: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
}, "strip", z.ZodTypeAny, {
|
|
23
|
+
top?: number | undefined;
|
|
24
|
+
right?: number | undefined;
|
|
25
|
+
bottom?: number | undefined;
|
|
26
|
+
left?: number | undefined;
|
|
27
|
+
}, {
|
|
28
|
+
top?: number | undefined;
|
|
29
|
+
right?: number | undefined;
|
|
30
|
+
bottom?: number | undefined;
|
|
31
|
+
left?: number | undefined;
|
|
32
|
+
}>]>>;
|
|
33
|
+
padding_token: z.ZodOptional<z.ZodString>;
|
|
34
|
+
margin: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
|
35
|
+
top: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
right: z.ZodOptional<z.ZodNumber>;
|
|
37
|
+
bottom: z.ZodOptional<z.ZodNumber>;
|
|
38
|
+
left: z.ZodOptional<z.ZodNumber>;
|
|
39
|
+
}, "strip", z.ZodTypeAny, {
|
|
40
|
+
top?: number | undefined;
|
|
41
|
+
right?: number | undefined;
|
|
42
|
+
bottom?: number | undefined;
|
|
43
|
+
left?: number | undefined;
|
|
44
|
+
}, {
|
|
45
|
+
top?: number | undefined;
|
|
46
|
+
right?: number | undefined;
|
|
47
|
+
bottom?: number | undefined;
|
|
48
|
+
left?: number | undefined;
|
|
49
|
+
}>]>>;
|
|
50
|
+
margin_token: z.ZodOptional<z.ZodString>;
|
|
51
|
+
border_radius: z.ZodOptional<z.ZodNumber>;
|
|
52
|
+
border_radius_token: z.ZodOptional<z.ZodString>;
|
|
53
|
+
border_width: z.ZodOptional<z.ZodNumber>;
|
|
54
|
+
border_width_token: z.ZodOptional<z.ZodString>;
|
|
55
|
+
min_height: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
min_height_token: z.ZodOptional<z.ZodString>;
|
|
57
|
+
min_width: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
min_width_token: z.ZodOptional<z.ZodString>;
|
|
59
|
+
width: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
60
|
+
width_token: z.ZodOptional<z.ZodString>;
|
|
61
|
+
height: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
62
|
+
height_token: z.ZodOptional<z.ZodString>;
|
|
63
|
+
opacity: z.ZodOptional<z.ZodNumber>;
|
|
64
|
+
opacity_token: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
66
|
+
bg_color: z.ZodOptional<z.ZodString>;
|
|
67
|
+
bg_color_token: z.ZodOptional<z.ZodString>;
|
|
68
|
+
text_color: z.ZodOptional<z.ZodString>;
|
|
69
|
+
text_color_token: z.ZodOptional<z.ZodString>;
|
|
70
|
+
border_color: z.ZodOptional<z.ZodString>;
|
|
71
|
+
border_color_token: z.ZodOptional<z.ZodString>;
|
|
72
|
+
font_family: z.ZodOptional<z.ZodString>;
|
|
73
|
+
font_family_token: z.ZodOptional<z.ZodString>;
|
|
74
|
+
font_size: z.ZodOptional<z.ZodNumber>;
|
|
75
|
+
font_size_token: z.ZodOptional<z.ZodString>;
|
|
76
|
+
font_weight: z.ZodOptional<z.ZodNumber>;
|
|
77
|
+
font_weight_token: z.ZodOptional<z.ZodString>;
|
|
78
|
+
line_height: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
line_height_token: z.ZodOptional<z.ZodString>;
|
|
80
|
+
padding: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
|
81
|
+
top: z.ZodOptional<z.ZodNumber>;
|
|
82
|
+
right: z.ZodOptional<z.ZodNumber>;
|
|
83
|
+
bottom: z.ZodOptional<z.ZodNumber>;
|
|
84
|
+
left: z.ZodOptional<z.ZodNumber>;
|
|
85
|
+
}, "strip", z.ZodTypeAny, {
|
|
86
|
+
top?: number | undefined;
|
|
87
|
+
right?: number | undefined;
|
|
88
|
+
bottom?: number | undefined;
|
|
89
|
+
left?: number | undefined;
|
|
90
|
+
}, {
|
|
91
|
+
top?: number | undefined;
|
|
92
|
+
right?: number | undefined;
|
|
93
|
+
bottom?: number | undefined;
|
|
94
|
+
left?: number | undefined;
|
|
95
|
+
}>]>>;
|
|
96
|
+
padding_token: z.ZodOptional<z.ZodString>;
|
|
97
|
+
margin: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
|
98
|
+
top: z.ZodOptional<z.ZodNumber>;
|
|
99
|
+
right: z.ZodOptional<z.ZodNumber>;
|
|
100
|
+
bottom: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
left: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
}, "strip", z.ZodTypeAny, {
|
|
103
|
+
top?: number | undefined;
|
|
104
|
+
right?: number | undefined;
|
|
105
|
+
bottom?: number | undefined;
|
|
106
|
+
left?: number | undefined;
|
|
107
|
+
}, {
|
|
108
|
+
top?: number | undefined;
|
|
109
|
+
right?: number | undefined;
|
|
110
|
+
bottom?: number | undefined;
|
|
111
|
+
left?: number | undefined;
|
|
112
|
+
}>]>>;
|
|
113
|
+
margin_token: z.ZodOptional<z.ZodString>;
|
|
114
|
+
border_radius: z.ZodOptional<z.ZodNumber>;
|
|
115
|
+
border_radius_token: z.ZodOptional<z.ZodString>;
|
|
116
|
+
border_width: z.ZodOptional<z.ZodNumber>;
|
|
117
|
+
border_width_token: z.ZodOptional<z.ZodString>;
|
|
118
|
+
min_height: z.ZodOptional<z.ZodNumber>;
|
|
119
|
+
min_height_token: z.ZodOptional<z.ZodString>;
|
|
120
|
+
min_width: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
min_width_token: z.ZodOptional<z.ZodString>;
|
|
122
|
+
width: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
123
|
+
width_token: z.ZodOptional<z.ZodString>;
|
|
124
|
+
height: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
125
|
+
height_token: z.ZodOptional<z.ZodString>;
|
|
126
|
+
opacity: z.ZodOptional<z.ZodNumber>;
|
|
127
|
+
opacity_token: z.ZodOptional<z.ZodString>;
|
|
128
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
129
|
+
bg_color: z.ZodOptional<z.ZodString>;
|
|
130
|
+
bg_color_token: z.ZodOptional<z.ZodString>;
|
|
131
|
+
text_color: z.ZodOptional<z.ZodString>;
|
|
132
|
+
text_color_token: z.ZodOptional<z.ZodString>;
|
|
133
|
+
border_color: z.ZodOptional<z.ZodString>;
|
|
134
|
+
border_color_token: z.ZodOptional<z.ZodString>;
|
|
135
|
+
font_family: z.ZodOptional<z.ZodString>;
|
|
136
|
+
font_family_token: z.ZodOptional<z.ZodString>;
|
|
137
|
+
font_size: z.ZodOptional<z.ZodNumber>;
|
|
138
|
+
font_size_token: z.ZodOptional<z.ZodString>;
|
|
139
|
+
font_weight: z.ZodOptional<z.ZodNumber>;
|
|
140
|
+
font_weight_token: z.ZodOptional<z.ZodString>;
|
|
141
|
+
line_height: z.ZodOptional<z.ZodNumber>;
|
|
142
|
+
line_height_token: z.ZodOptional<z.ZodString>;
|
|
143
|
+
padding: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
|
144
|
+
top: z.ZodOptional<z.ZodNumber>;
|
|
145
|
+
right: z.ZodOptional<z.ZodNumber>;
|
|
146
|
+
bottom: z.ZodOptional<z.ZodNumber>;
|
|
147
|
+
left: z.ZodOptional<z.ZodNumber>;
|
|
148
|
+
}, "strip", z.ZodTypeAny, {
|
|
149
|
+
top?: number | undefined;
|
|
150
|
+
right?: number | undefined;
|
|
151
|
+
bottom?: number | undefined;
|
|
152
|
+
left?: number | undefined;
|
|
153
|
+
}, {
|
|
154
|
+
top?: number | undefined;
|
|
155
|
+
right?: number | undefined;
|
|
156
|
+
bottom?: number | undefined;
|
|
157
|
+
left?: number | undefined;
|
|
158
|
+
}>]>>;
|
|
159
|
+
padding_token: z.ZodOptional<z.ZodString>;
|
|
160
|
+
margin: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
|
161
|
+
top: z.ZodOptional<z.ZodNumber>;
|
|
162
|
+
right: z.ZodOptional<z.ZodNumber>;
|
|
163
|
+
bottom: z.ZodOptional<z.ZodNumber>;
|
|
164
|
+
left: z.ZodOptional<z.ZodNumber>;
|
|
165
|
+
}, "strip", z.ZodTypeAny, {
|
|
166
|
+
top?: number | undefined;
|
|
167
|
+
right?: number | undefined;
|
|
168
|
+
bottom?: number | undefined;
|
|
169
|
+
left?: number | undefined;
|
|
170
|
+
}, {
|
|
171
|
+
top?: number | undefined;
|
|
172
|
+
right?: number | undefined;
|
|
173
|
+
bottom?: number | undefined;
|
|
174
|
+
left?: number | undefined;
|
|
175
|
+
}>]>>;
|
|
176
|
+
margin_token: z.ZodOptional<z.ZodString>;
|
|
177
|
+
border_radius: z.ZodOptional<z.ZodNumber>;
|
|
178
|
+
border_radius_token: z.ZodOptional<z.ZodString>;
|
|
179
|
+
border_width: z.ZodOptional<z.ZodNumber>;
|
|
180
|
+
border_width_token: z.ZodOptional<z.ZodString>;
|
|
181
|
+
min_height: z.ZodOptional<z.ZodNumber>;
|
|
182
|
+
min_height_token: z.ZodOptional<z.ZodString>;
|
|
183
|
+
min_width: z.ZodOptional<z.ZodNumber>;
|
|
184
|
+
min_width_token: z.ZodOptional<z.ZodString>;
|
|
185
|
+
width: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
186
|
+
width_token: z.ZodOptional<z.ZodString>;
|
|
187
|
+
height: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
|
|
188
|
+
height_token: z.ZodOptional<z.ZodString>;
|
|
189
|
+
opacity: z.ZodOptional<z.ZodNumber>;
|
|
190
|
+
opacity_token: z.ZodOptional<z.ZodString>;
|
|
191
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
192
|
+
export type StyleSpec = z.infer<typeof styleSpec>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.styleSpec = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
// ─── Token-Aware Style Schema ────────────────────────────────────
|
|
6
|
+
// SPEC.md §2.6: Properties support both literal and token-based config.
|
|
7
|
+
// Convention: literal `bg_color` + parallel `bg_color_token` (DTCG path).
|
|
8
|
+
//
|
|
9
|
+
// When both are present, runtimes MUST attempt token resolution first.
|
|
10
|
+
// If token resolution fails and literal is type-compatible, runtimes
|
|
11
|
+
// MAY use literal as graceful degradation.
|
|
12
|
+
// DTCG token path: e.g. "color.bg.primary"
|
|
13
|
+
const dtcgTokenPath = zod_1.z.string().min(1);
|
|
14
|
+
exports.styleSpec = zod_1.z.object({
|
|
15
|
+
// ── Color Properties ──
|
|
16
|
+
bg_color: zod_1.z.string().optional(),
|
|
17
|
+
bg_color_token: dtcgTokenPath.optional(),
|
|
18
|
+
text_color: zod_1.z.string().optional(),
|
|
19
|
+
text_color_token: dtcgTokenPath.optional(),
|
|
20
|
+
border_color: zod_1.z.string().optional(),
|
|
21
|
+
border_color_token: dtcgTokenPath.optional(),
|
|
22
|
+
// ── Typography Properties ──
|
|
23
|
+
font_family: zod_1.z.string().optional(),
|
|
24
|
+
font_family_token: dtcgTokenPath.optional(),
|
|
25
|
+
font_size: zod_1.z.number().optional(),
|
|
26
|
+
font_size_token: dtcgTokenPath.optional(),
|
|
27
|
+
font_weight: zod_1.z.number().optional(),
|
|
28
|
+
font_weight_token: dtcgTokenPath.optional(),
|
|
29
|
+
line_height: zod_1.z.number().optional(),
|
|
30
|
+
line_height_token: dtcgTokenPath.optional(),
|
|
31
|
+
// ── Spacing Properties ──
|
|
32
|
+
padding: zod_1.z.union([
|
|
33
|
+
zod_1.z.number(),
|
|
34
|
+
zod_1.z.object({
|
|
35
|
+
top: zod_1.z.number().optional(),
|
|
36
|
+
right: zod_1.z.number().optional(),
|
|
37
|
+
bottom: zod_1.z.number().optional(),
|
|
38
|
+
left: zod_1.z.number().optional(),
|
|
39
|
+
}),
|
|
40
|
+
]).optional(),
|
|
41
|
+
padding_token: dtcgTokenPath.optional(),
|
|
42
|
+
margin: zod_1.z.union([
|
|
43
|
+
zod_1.z.number(),
|
|
44
|
+
zod_1.z.object({
|
|
45
|
+
top: zod_1.z.number().optional(),
|
|
46
|
+
right: zod_1.z.number().optional(),
|
|
47
|
+
bottom: zod_1.z.number().optional(),
|
|
48
|
+
left: zod_1.z.number().optional(),
|
|
49
|
+
}),
|
|
50
|
+
]).optional(),
|
|
51
|
+
margin_token: dtcgTokenPath.optional(),
|
|
52
|
+
// ── Border Properties ──
|
|
53
|
+
border_radius: zod_1.z.number().optional(),
|
|
54
|
+
border_radius_token: dtcgTokenPath.optional(),
|
|
55
|
+
border_width: zod_1.z.number().optional(),
|
|
56
|
+
border_width_token: dtcgTokenPath.optional(),
|
|
57
|
+
// ── Dimension Properties ──
|
|
58
|
+
min_height: zod_1.z.number().optional(),
|
|
59
|
+
min_height_token: dtcgTokenPath.optional(),
|
|
60
|
+
min_width: zod_1.z.number().optional(),
|
|
61
|
+
min_width_token: dtcgTokenPath.optional(),
|
|
62
|
+
width: zod_1.z.union([zod_1.z.number(), zod_1.z.string()]).optional(),
|
|
63
|
+
width_token: dtcgTokenPath.optional(),
|
|
64
|
+
height: zod_1.z.union([zod_1.z.number(), zod_1.z.string()]).optional(),
|
|
65
|
+
height_token: dtcgTokenPath.optional(),
|
|
66
|
+
// ── Opacity ──
|
|
67
|
+
opacity: zod_1.z.number().min(0).max(1).optional(),
|
|
68
|
+
opacity_token: dtcgTokenPath.optional(),
|
|
69
|
+
}).passthrough(); // Allow vendor extensions (§2.9)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const surfaceSpec: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
root: z.ZodType<any, z.ZodTypeDef, any>;
|
|
5
|
+
telemetry: z.ZodObject<{
|
|
6
|
+
emit: z.ZodArray<z.ZodString, "many">;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
emit: string[];
|
|
9
|
+
}, {
|
|
10
|
+
emit: string[];
|
|
11
|
+
}>;
|
|
12
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
13
|
+
environment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
14
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
15
|
+
id: z.ZodString;
|
|
16
|
+
root: z.ZodType<any, z.ZodTypeDef, any>;
|
|
17
|
+
telemetry: z.ZodObject<{
|
|
18
|
+
emit: z.ZodArray<z.ZodString, "many">;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
emit: string[];
|
|
21
|
+
}, {
|
|
22
|
+
emit: string[];
|
|
23
|
+
}>;
|
|
24
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
25
|
+
environment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
26
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
27
|
+
id: z.ZodString;
|
|
28
|
+
root: z.ZodType<any, z.ZodTypeDef, any>;
|
|
29
|
+
telemetry: z.ZodObject<{
|
|
30
|
+
emit: z.ZodArray<z.ZodString, "many">;
|
|
31
|
+
}, "strip", z.ZodTypeAny, {
|
|
32
|
+
emit: string[];
|
|
33
|
+
}, {
|
|
34
|
+
emit: string[];
|
|
35
|
+
}>;
|
|
36
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
37
|
+
environment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
38
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
39
|
+
export type SurfaceSpec = z.infer<typeof surfaceSpec>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.surfaceSpec = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const composition_1 = require("./composition");
|
|
6
|
+
const telemetry_1 = require("./telemetry");
|
|
7
|
+
// ─── SurfaceSpec ─────────────────────────────────────────────────
|
|
8
|
+
// SPEC.md §2.8: id, root, telemetry REQUIRED.
|
|
9
|
+
//
|
|
10
|
+
// CRITICAL RULE: root MUST be a CompositionSpec.
|
|
11
|
+
// It MUST NOT be an ElementSpec. An Element cannot exist at the
|
|
12
|
+
// root level; it must be contained within a Composition.
|
|
13
|
+
exports.surfaceSpec = zod_1.z.object({
|
|
14
|
+
id: zod_1.z.string().min(1).regex(/^[A-Za-z][A-Za-z0-9_.:-]{0,127}$/),
|
|
15
|
+
root: composition_1.compositionSpec,
|
|
16
|
+
telemetry: telemetry_1.telemetrySpec,
|
|
17
|
+
metadata: zod_1.z.record(zod_1.z.any()).optional(),
|
|
18
|
+
environment: zod_1.z.record(zod_1.z.any()).optional(),
|
|
19
|
+
}).passthrough();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const telemetrySpec: z.ZodObject<{
|
|
3
|
+
emit: z.ZodArray<z.ZodString, "many">;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
emit: string[];
|
|
6
|
+
}, {
|
|
7
|
+
emit: string[];
|
|
8
|
+
}>;
|
|
9
|
+
export declare const telemetryEnvelopeSpec: z.ZodObject<{
|
|
10
|
+
session_id: z.ZodString;
|
|
11
|
+
element_id: z.ZodString;
|
|
12
|
+
timestamp: z.ZodString;
|
|
13
|
+
revision_id: z.ZodString;
|
|
14
|
+
event_type: z.ZodString;
|
|
15
|
+
payload: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
16
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
17
|
+
session_id: z.ZodString;
|
|
18
|
+
element_id: z.ZodString;
|
|
19
|
+
timestamp: z.ZodString;
|
|
20
|
+
revision_id: z.ZodString;
|
|
21
|
+
event_type: z.ZodString;
|
|
22
|
+
payload: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
23
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
24
|
+
session_id: z.ZodString;
|
|
25
|
+
element_id: z.ZodString;
|
|
26
|
+
timestamp: z.ZodString;
|
|
27
|
+
revision_id: z.ZodString;
|
|
28
|
+
event_type: z.ZodString;
|
|
29
|
+
payload: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
30
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
31
|
+
export type TelemetrySpec = z.infer<typeof telemetrySpec>;
|
|
32
|
+
export type TelemetryEnvelope = z.infer<typeof telemetryEnvelopeSpec>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.telemetryEnvelopeSpec = exports.telemetrySpec = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
// ─── telemetrySpec ───────────────────────────────────────────────
|
|
6
|
+
// SPEC.md §2.3/$defs/telemetrySpec: object with emit string array
|
|
7
|
+
exports.telemetrySpec = zod_1.z.object({
|
|
8
|
+
emit: zod_1.z.array(zod_1.z.string()),
|
|
9
|
+
});
|
|
10
|
+
// ─── TelemetryEnvelope ───────────────────────────────────────────
|
|
11
|
+
// SPEC.md §4.5: All telemetry events MUST share this common envelope.
|
|
12
|
+
// All fields are REQUIRED per the normative schema.
|
|
13
|
+
exports.telemetryEnvelopeSpec = zod_1.z.object({
|
|
14
|
+
session_id: zod_1.z.string().min(1),
|
|
15
|
+
element_id: zod_1.z.string().min(1),
|
|
16
|
+
timestamp: zod_1.z.string(), // ISO 8601 UTC
|
|
17
|
+
revision_id: zod_1.z.string().min(1),
|
|
18
|
+
event_type: zod_1.z.string().min(1),
|
|
19
|
+
payload: zod_1.z.record(zod_1.z.any()),
|
|
20
|
+
}).passthrough(); // additionalProperties: true per §4.5
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const dtcgTokenLeaf: z.ZodObject<{
|
|
3
|
+
$type: z.ZodString;
|
|
4
|
+
$value: z.ZodAny;
|
|
5
|
+
$description: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
7
|
+
$type: z.ZodString;
|
|
8
|
+
$value: z.ZodAny;
|
|
9
|
+
$description: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
11
|
+
$type: z.ZodString;
|
|
12
|
+
$value: z.ZodAny;
|
|
13
|
+
$description: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
15
|
+
export type DTCGTokenGroup = {
|
|
16
|
+
[key: string]: DTCGTokenGroup | {
|
|
17
|
+
$type: string;
|
|
18
|
+
$value: any;
|
|
19
|
+
$description?: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export declare const tokenThemeSchema: z.ZodRecord<z.ZodString, z.ZodType<any, z.ZodTypeDef, any>>;
|
|
23
|
+
export type DTCGTokenLeaf = z.infer<typeof dtcgTokenLeaf>;
|
|
24
|
+
export type TokenTheme = z.infer<typeof tokenThemeSchema>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tokenThemeSchema = exports.dtcgTokenLeaf = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
// ─── DTCG Token Format Schema ────────────────────────────────────
|
|
6
|
+
// SPEC.md §2.6: DESEN MUST reuse the Design Tokens Community Group
|
|
7
|
+
// (DTCG) Design Tokens Format Module.
|
|
8
|
+
//
|
|
9
|
+
// A token leaf node has { $type, $value } (required) and
|
|
10
|
+
// optional $description. Non-leaf nodes are groups that contain
|
|
11
|
+
// other token nodes or groups (recursive).
|
|
12
|
+
//
|
|
13
|
+
// Example:
|
|
14
|
+
// {
|
|
15
|
+
// "color": {
|
|
16
|
+
// "bg": {
|
|
17
|
+
// "primary": { "$type": "color", "$value": "#0B5FFF" }
|
|
18
|
+
// }
|
|
19
|
+
// }
|
|
20
|
+
// }
|
|
21
|
+
// Leaf token node — the actual design token
|
|
22
|
+
exports.dtcgTokenLeaf = zod_1.z.object({
|
|
23
|
+
$type: zod_1.z.string().min(1),
|
|
24
|
+
$value: zod_1.z.any(),
|
|
25
|
+
$description: zod_1.z.string().optional(),
|
|
26
|
+
}).passthrough();
|
|
27
|
+
// The full token theme is a recursive structure.
|
|
28
|
+
// We use z.record + z.lazy for recursive validation.
|
|
29
|
+
const dtcgTokenNode = zod_1.z.lazy(() => zod_1.z.union([
|
|
30
|
+
exports.dtcgTokenLeaf,
|
|
31
|
+
zod_1.z.record(dtcgTokenNode),
|
|
32
|
+
]));
|
|
33
|
+
// ─── TokenThemeSchema ────────────────────────────────────────────
|
|
34
|
+
// Top-level theme file: a record of token groups
|
|
35
|
+
// e.g. { "color": { "bg": { "primary": { "$type": "color", "$value": "#0B5FFF" } } } }
|
|
36
|
+
exports.tokenThemeSchema = zod_1.z.record(dtcgTokenNode);
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "desen-core",
|
|
3
|
+
"version": "1.0.0-draft",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"zod": "^3.22.4"
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"typescript": "^5.0.0"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"dev": "tsc -w",
|
|
15
|
+
"clean": "rm -rf dist"
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ─── desen-core ─────────────────────────────────────────────────
|
|
2
|
+
// DESEN Protocol Validation Engine
|
|
3
|
+
// Pure TypeScript + Zod — Zero UI dependencies
|
|
4
|
+
//
|
|
5
|
+
// All schemas and types adhere to SPEC.md v1.0.0-RC
|
|
6
|
+
|
|
7
|
+
// ── Binding & Modifiers (§2.7, §2.11) ──
|
|
8
|
+
export {
|
|
9
|
+
bindingSourceEnum,
|
|
10
|
+
bindingSpec,
|
|
11
|
+
bindWrapper,
|
|
12
|
+
modifiersSpec,
|
|
13
|
+
} from "./schemas/binding";
|
|
14
|
+
export type {
|
|
15
|
+
BindingSource,
|
|
16
|
+
BindingSpec,
|
|
17
|
+
BindWrapper,
|
|
18
|
+
ModifiersSpec,
|
|
19
|
+
} from "./schemas/binding";
|
|
20
|
+
|
|
21
|
+
// ── Telemetry (§2.3, §4.5) ──
|
|
22
|
+
export {
|
|
23
|
+
telemetrySpec,
|
|
24
|
+
telemetryEnvelopeSpec,
|
|
25
|
+
} from "./schemas/telemetry";
|
|
26
|
+
export type {
|
|
27
|
+
TelemetrySpec,
|
|
28
|
+
TelemetryEnvelope,
|
|
29
|
+
} from "./schemas/telemetry";
|
|
30
|
+
|
|
31
|
+
// ── Actions (§2.4) ──
|
|
32
|
+
export { actionSpec } from "./schemas/action";
|
|
33
|
+
export type { ActionSpec } from "./schemas/action";
|
|
34
|
+
|
|
35
|
+
// ── Style & Tokens (§2.6) ──
|
|
36
|
+
export { styleSpec } from "./schemas/style";
|
|
37
|
+
export type { StyleSpec } from "./schemas/style";
|
|
38
|
+
export { dtcgTokenLeaf, tokenThemeSchema } from "./schemas/token";
|
|
39
|
+
export type { DTCGTokenLeaf, DTCGTokenGroup, TokenTheme } from "./schemas/token";
|
|
40
|
+
|
|
41
|
+
// ── Element (§2.2) ──
|
|
42
|
+
export { elementSpec } from "./schemas/element";
|
|
43
|
+
export type { ElementSpec } from "./schemas/element";
|
|
44
|
+
|
|
45
|
+
// ── Composition, Layout, Repeater, Node (§2.3, §2.5, §3.5) ──
|
|
46
|
+
export {
|
|
47
|
+
positioningSpec,
|
|
48
|
+
layoutSpec,
|
|
49
|
+
nodeSpec,
|
|
50
|
+
compositionSpec,
|
|
51
|
+
repeaterSpec,
|
|
52
|
+
} from "./schemas/composition";
|
|
53
|
+
export type {
|
|
54
|
+
PositioningSpec,
|
|
55
|
+
LayoutSpec,
|
|
56
|
+
NodeSpec,
|
|
57
|
+
CompositionSpec,
|
|
58
|
+
RepeaterSpec,
|
|
59
|
+
} from "./schemas/composition";
|
|
60
|
+
|
|
61
|
+
// ── Surface (§2.8) ──
|
|
62
|
+
export { surfaceSpec } from "./schemas/surface";
|
|
63
|
+
export type { SurfaceSpec } from "./schemas/surface";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// ─── ActionSpec ──────────────────────────────────────────────────
|
|
4
|
+
// SPEC.md §2.4: Standardized behavior primitives.
|
|
5
|
+
// kind is REQUIRED; target, params, actions are optional.
|
|
6
|
+
// "sequence" kind uses recursive `actions` array.
|
|
7
|
+
export const actionSpec: z.ZodType<any> = z.lazy(() =>
|
|
8
|
+
z.object({
|
|
9
|
+
kind: z.enum(["navigate", "mutate", "trigger_event", "sequence"]),
|
|
10
|
+
target: z.string().optional(),
|
|
11
|
+
params: z.record(z.any()).optional(),
|
|
12
|
+
actions: z.array(actionSpec).optional(),
|
|
13
|
+
}).passthrough()
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
// ─── Types ───────────────────────────────────────────────────────
|
|
17
|
+
export type ActionSpec = z.infer<typeof actionSpec>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// ─── Binding Sources ─────────────────────────────────────────────
|
|
4
|
+
// SPEC.md §2.7: source MUST be an implementation-defined identifier
|
|
5
|
+
// for a trusted data source. Runtimes MUST maintain a fixed allowlist.
|
|
6
|
+
export const bindingSourceEnum = z.enum([
|
|
7
|
+
"session",
|
|
8
|
+
"backend",
|
|
9
|
+
"local",
|
|
10
|
+
"feature_flag",
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
// ─── bindingSpec ─────────────────────────────────────────────────
|
|
14
|
+
// SPEC.md §2.7: { source, path } required; fallback optional
|
|
15
|
+
export const bindingSpec = z.object({
|
|
16
|
+
source: bindingSourceEnum,
|
|
17
|
+
path: z.string().min(1),
|
|
18
|
+
fallback: z.any().optional(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// ─── Bind Wrapper ────────────────────────────────────────────────
|
|
22
|
+
// Standard wrapper: { bind: bindingSpec }
|
|
23
|
+
export const bindWrapper = z.object({
|
|
24
|
+
bind: bindingSpec,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// ─── modifiersSpec ───────────────────────────────────────────────
|
|
28
|
+
// SPEC.md §2.11: visible can be a boolean or a bind reference.
|
|
29
|
+
// If binding fails and no fallback is present, default is false (fail-closed).
|
|
30
|
+
export const modifiersSpec = z.object({
|
|
31
|
+
visible: z.union([z.boolean(), bindWrapper]).optional(),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// ─── Types ───────────────────────────────────────────────────────
|
|
35
|
+
export type BindingSource = z.infer<typeof bindingSourceEnum>;
|
|
36
|
+
export type BindingSpec = z.infer<typeof bindingSpec>;
|
|
37
|
+
export type BindWrapper = z.infer<typeof bindWrapper>;
|
|
38
|
+
export type ModifiersSpec = z.infer<typeof modifiersSpec>;
|