design-constraint-validator 1.1.0 → 2.1.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/README.md +90 -21
- package/adapters/decisionthemes.d.ts +44 -0
- package/adapters/decisionthemes.d.ts.map +1 -0
- package/adapters/decisionthemes.js +35 -0
- package/adapters/decisionthemes.ts +59 -0
- package/cli/commands/build.js +1 -1
- package/cli/commands/build.ts +1 -1
- package/cli/commands/graph.js +4 -4
- package/cli/commands/graph.ts +4 -4
- package/cli/commands/validate.d.ts.map +1 -1
- package/cli/commands/validate.js +43 -6
- package/cli/commands/validate.ts +41 -8
- package/cli/config-schema.d.ts +39 -0
- package/cli/config-schema.d.ts.map +1 -1
- package/cli/config-schema.js +4 -2
- package/cli/config-schema.ts +4 -2
- package/cli/config.d.ts.map +1 -1
- package/cli/config.js +8 -2
- package/cli/config.ts +8 -2
- package/cli/constraint-registry.d.ts +16 -0
- package/cli/constraint-registry.d.ts.map +1 -1
- package/cli/constraint-registry.js +64 -31
- package/cli/constraint-registry.ts +67 -31
- package/cli/dcv.js +8 -24
- package/cli/dcv.ts +8 -20
- package/cli/json-output.d.ts +8 -1
- package/cli/json-output.d.ts.map +1 -1
- package/cli/json-output.js +13 -4
- package/cli/json-output.ts +20 -4
- package/cli/types.d.ts +2 -0
- package/cli/types.d.ts.map +1 -1
- package/cli/types.ts +2 -0
- package/cli/validate-api.d.ts +40 -0
- package/cli/validate-api.d.ts.map +1 -0
- package/cli/validate-api.js +85 -0
- package/cli/validate-api.ts +126 -0
- package/cli/version-banner.d.ts +20 -0
- package/cli/version-banner.d.ts.map +1 -0
- package/cli/version-banner.js +49 -0
- package/cli/version-banner.ts +61 -0
- package/core/breakpoints.d.ts +8 -2
- package/core/breakpoints.d.ts.map +1 -1
- package/core/breakpoints.js +24 -3
- package/core/breakpoints.ts +22 -3
- package/core/color.js +4 -4
- package/core/color.ts +4 -4
- package/core/constraints/monotonic-lightness.d.ts.map +1 -1
- package/core/constraints/monotonic-lightness.js +9 -5
- package/core/constraints/monotonic-lightness.ts +9 -4
- package/core/constraints/wcag.d.ts.map +1 -1
- package/core/constraints/wcag.js +6 -0
- package/core/constraints/wcag.ts +6 -0
- package/core/dtcg.d.ts +38 -0
- package/core/dtcg.d.ts.map +1 -0
- package/core/dtcg.js +88 -0
- package/core/dtcg.ts +102 -0
- package/core/engine.d.ts +6 -0
- package/core/engine.d.ts.map +1 -1
- package/core/engine.ts +7 -0
- package/core/flatten.d.ts +5 -3
- package/core/flatten.d.ts.map +1 -1
- package/core/flatten.js +24 -10
- package/core/flatten.ts +39 -16
- package/core/image-export.d.ts.map +1 -1
- package/core/image-export.js +10 -7
- package/core/image-export.ts +9 -6
- package/core/index.d.ts +2 -0
- package/core/index.d.ts.map +1 -1
- package/core/index.js +4 -0
- package/core/index.ts +6 -0
- package/core/why.d.ts +1 -1
- package/core/why.d.ts.map +1 -1
- package/core/why.ts +1 -1
- package/mcp/contracts.d.ts +118 -0
- package/mcp/contracts.d.ts.map +1 -0
- package/mcp/contracts.js +30 -0
- package/mcp/contracts.ts +51 -0
- package/mcp/index.d.ts +9 -0
- package/mcp/index.d.ts.map +1 -0
- package/mcp/index.js +32 -0
- package/mcp/index.ts +70 -0
- package/mcp/tools.d.ts +52 -0
- package/mcp/tools.d.ts.map +1 -0
- package/mcp/tools.js +172 -0
- package/mcp/tools.ts +254 -0
- package/package.json +41 -26
- package/server.json +21 -0
- package/cli/constraints-loader.d.ts +0 -30
- package/cli/constraints-loader.d.ts.map +0 -1
- package/cli/constraints-loader.js +0 -58
- package/cli/constraints-loader.ts +0 -83
- package/cli/engine-helpers.d.ts +0 -41
- package/cli/engine-helpers.d.ts.map +0 -1
- package/cli/engine-helpers.js +0 -135
- package/cli/engine-helpers.ts +0 -133
- package/core/cross-axis-config.d.ts +0 -34
- package/core/cross-axis-config.d.ts.map +0 -1
- package/core/cross-axis-config.js +0 -173
- package/core/cross-axis-config.ts +0 -182
package/cli/config-schema.d.ts
CHANGED
|
@@ -4,16 +4,19 @@ export declare const WcagRuleSchema: z.ZodObject<{
|
|
|
4
4
|
background: z.ZodString;
|
|
5
5
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
6
6
|
description: z.ZodOptional<z.ZodString>;
|
|
7
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
7
8
|
}, "strip", z.ZodTypeAny, {
|
|
8
9
|
foreground: string;
|
|
9
10
|
background: string;
|
|
10
11
|
description?: string | undefined;
|
|
11
12
|
ratio?: number | undefined;
|
|
13
|
+
backdrop?: string | undefined;
|
|
12
14
|
}, {
|
|
13
15
|
foreground: string;
|
|
14
16
|
background: string;
|
|
15
17
|
description?: string | undefined;
|
|
16
18
|
ratio?: number | undefined;
|
|
19
|
+
backdrop?: string | undefined;
|
|
17
20
|
}>;
|
|
18
21
|
export declare const ConstraintsSchema: z.ZodObject<{
|
|
19
22
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -21,16 +24,19 @@ export declare const ConstraintsSchema: z.ZodObject<{
|
|
|
21
24
|
background: z.ZodString;
|
|
22
25
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
23
26
|
description: z.ZodOptional<z.ZodString>;
|
|
27
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
24
28
|
}, "strip", z.ZodTypeAny, {
|
|
25
29
|
foreground: string;
|
|
26
30
|
background: string;
|
|
27
31
|
description?: string | undefined;
|
|
28
32
|
ratio?: number | undefined;
|
|
33
|
+
backdrop?: string | undefined;
|
|
29
34
|
}, {
|
|
30
35
|
foreground: string;
|
|
31
36
|
background: string;
|
|
32
37
|
description?: string | undefined;
|
|
33
38
|
ratio?: number | undefined;
|
|
39
|
+
backdrop?: string | undefined;
|
|
34
40
|
}>, "many">>;
|
|
35
41
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
36
42
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -38,16 +44,19 @@ export declare const ConstraintsSchema: z.ZodObject<{
|
|
|
38
44
|
background: z.ZodString;
|
|
39
45
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
40
46
|
description: z.ZodOptional<z.ZodString>;
|
|
47
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
41
48
|
}, "strip", z.ZodTypeAny, {
|
|
42
49
|
foreground: string;
|
|
43
50
|
background: string;
|
|
44
51
|
description?: string | undefined;
|
|
45
52
|
ratio?: number | undefined;
|
|
53
|
+
backdrop?: string | undefined;
|
|
46
54
|
}, {
|
|
47
55
|
foreground: string;
|
|
48
56
|
background: string;
|
|
49
57
|
description?: string | undefined;
|
|
50
58
|
ratio?: number | undefined;
|
|
59
|
+
backdrop?: string | undefined;
|
|
51
60
|
}>, "many">>;
|
|
52
61
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
53
62
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -55,16 +64,19 @@ export declare const ConstraintsSchema: z.ZodObject<{
|
|
|
55
64
|
background: z.ZodString;
|
|
56
65
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
57
66
|
description: z.ZodOptional<z.ZodString>;
|
|
67
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
58
68
|
}, "strip", z.ZodTypeAny, {
|
|
59
69
|
foreground: string;
|
|
60
70
|
background: string;
|
|
61
71
|
description?: string | undefined;
|
|
62
72
|
ratio?: number | undefined;
|
|
73
|
+
backdrop?: string | undefined;
|
|
63
74
|
}, {
|
|
64
75
|
foreground: string;
|
|
65
76
|
background: string;
|
|
66
77
|
description?: string | undefined;
|
|
67
78
|
ratio?: number | undefined;
|
|
79
|
+
backdrop?: string | undefined;
|
|
68
80
|
}>, "many">>;
|
|
69
81
|
}, z.ZodTypeAny, "passthrough">>;
|
|
70
82
|
export declare const DcvConfigSchema: z.ZodObject<{
|
|
@@ -75,16 +87,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
75
87
|
background: z.ZodString;
|
|
76
88
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
77
89
|
description: z.ZodOptional<z.ZodString>;
|
|
90
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
78
91
|
}, "strip", z.ZodTypeAny, {
|
|
79
92
|
foreground: string;
|
|
80
93
|
background: string;
|
|
81
94
|
description?: string | undefined;
|
|
82
95
|
ratio?: number | undefined;
|
|
96
|
+
backdrop?: string | undefined;
|
|
83
97
|
}, {
|
|
84
98
|
foreground: string;
|
|
85
99
|
background: string;
|
|
86
100
|
description?: string | undefined;
|
|
87
101
|
ratio?: number | undefined;
|
|
102
|
+
backdrop?: string | undefined;
|
|
88
103
|
}>, "many">>;
|
|
89
104
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
90
105
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -92,16 +107,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
92
107
|
background: z.ZodString;
|
|
93
108
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
94
109
|
description: z.ZodOptional<z.ZodString>;
|
|
110
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
95
111
|
}, "strip", z.ZodTypeAny, {
|
|
96
112
|
foreground: string;
|
|
97
113
|
background: string;
|
|
98
114
|
description?: string | undefined;
|
|
99
115
|
ratio?: number | undefined;
|
|
116
|
+
backdrop?: string | undefined;
|
|
100
117
|
}, {
|
|
101
118
|
foreground: string;
|
|
102
119
|
background: string;
|
|
103
120
|
description?: string | undefined;
|
|
104
121
|
ratio?: number | undefined;
|
|
122
|
+
backdrop?: string | undefined;
|
|
105
123
|
}>, "many">>;
|
|
106
124
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
107
125
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -109,16 +127,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
109
127
|
background: z.ZodString;
|
|
110
128
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
111
129
|
description: z.ZodOptional<z.ZodString>;
|
|
130
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
112
131
|
}, "strip", z.ZodTypeAny, {
|
|
113
132
|
foreground: string;
|
|
114
133
|
background: string;
|
|
115
134
|
description?: string | undefined;
|
|
116
135
|
ratio?: number | undefined;
|
|
136
|
+
backdrop?: string | undefined;
|
|
117
137
|
}, {
|
|
118
138
|
foreground: string;
|
|
119
139
|
background: string;
|
|
120
140
|
description?: string | undefined;
|
|
121
141
|
ratio?: number | undefined;
|
|
142
|
+
backdrop?: string | undefined;
|
|
122
143
|
}>, "many">>;
|
|
123
144
|
}, z.ZodTypeAny, "passthrough">>>;
|
|
124
145
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
@@ -129,16 +150,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
129
150
|
background: z.ZodString;
|
|
130
151
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
131
152
|
description: z.ZodOptional<z.ZodString>;
|
|
153
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
132
154
|
}, "strip", z.ZodTypeAny, {
|
|
133
155
|
foreground: string;
|
|
134
156
|
background: string;
|
|
135
157
|
description?: string | undefined;
|
|
136
158
|
ratio?: number | undefined;
|
|
159
|
+
backdrop?: string | undefined;
|
|
137
160
|
}, {
|
|
138
161
|
foreground: string;
|
|
139
162
|
background: string;
|
|
140
163
|
description?: string | undefined;
|
|
141
164
|
ratio?: number | undefined;
|
|
165
|
+
backdrop?: string | undefined;
|
|
142
166
|
}>, "many">>;
|
|
143
167
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
144
168
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -146,16 +170,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
146
170
|
background: z.ZodString;
|
|
147
171
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
148
172
|
description: z.ZodOptional<z.ZodString>;
|
|
173
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
149
174
|
}, "strip", z.ZodTypeAny, {
|
|
150
175
|
foreground: string;
|
|
151
176
|
background: string;
|
|
152
177
|
description?: string | undefined;
|
|
153
178
|
ratio?: number | undefined;
|
|
179
|
+
backdrop?: string | undefined;
|
|
154
180
|
}, {
|
|
155
181
|
foreground: string;
|
|
156
182
|
background: string;
|
|
157
183
|
description?: string | undefined;
|
|
158
184
|
ratio?: number | undefined;
|
|
185
|
+
backdrop?: string | undefined;
|
|
159
186
|
}>, "many">>;
|
|
160
187
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
161
188
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -163,16 +190,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
163
190
|
background: z.ZodString;
|
|
164
191
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
165
192
|
description: z.ZodOptional<z.ZodString>;
|
|
193
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
166
194
|
}, "strip", z.ZodTypeAny, {
|
|
167
195
|
foreground: string;
|
|
168
196
|
background: string;
|
|
169
197
|
description?: string | undefined;
|
|
170
198
|
ratio?: number | undefined;
|
|
199
|
+
backdrop?: string | undefined;
|
|
171
200
|
}, {
|
|
172
201
|
foreground: string;
|
|
173
202
|
background: string;
|
|
174
203
|
description?: string | undefined;
|
|
175
204
|
ratio?: number | undefined;
|
|
205
|
+
backdrop?: string | undefined;
|
|
176
206
|
}>, "many">>;
|
|
177
207
|
}, z.ZodTypeAny, "passthrough">>>;
|
|
178
208
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
@@ -183,16 +213,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
183
213
|
background: z.ZodString;
|
|
184
214
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
185
215
|
description: z.ZodOptional<z.ZodString>;
|
|
216
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
186
217
|
}, "strip", z.ZodTypeAny, {
|
|
187
218
|
foreground: string;
|
|
188
219
|
background: string;
|
|
189
220
|
description?: string | undefined;
|
|
190
221
|
ratio?: number | undefined;
|
|
222
|
+
backdrop?: string | undefined;
|
|
191
223
|
}, {
|
|
192
224
|
foreground: string;
|
|
193
225
|
background: string;
|
|
194
226
|
description?: string | undefined;
|
|
195
227
|
ratio?: number | undefined;
|
|
228
|
+
backdrop?: string | undefined;
|
|
196
229
|
}>, "many">>;
|
|
197
230
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
198
231
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -200,16 +233,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
200
233
|
background: z.ZodString;
|
|
201
234
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
202
235
|
description: z.ZodOptional<z.ZodString>;
|
|
236
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
203
237
|
}, "strip", z.ZodTypeAny, {
|
|
204
238
|
foreground: string;
|
|
205
239
|
background: string;
|
|
206
240
|
description?: string | undefined;
|
|
207
241
|
ratio?: number | undefined;
|
|
242
|
+
backdrop?: string | undefined;
|
|
208
243
|
}, {
|
|
209
244
|
foreground: string;
|
|
210
245
|
background: string;
|
|
211
246
|
description?: string | undefined;
|
|
212
247
|
ratio?: number | undefined;
|
|
248
|
+
backdrop?: string | undefined;
|
|
213
249
|
}>, "many">>;
|
|
214
250
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
215
251
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -217,16 +253,19 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
217
253
|
background: z.ZodString;
|
|
218
254
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
219
255
|
description: z.ZodOptional<z.ZodString>;
|
|
256
|
+
backdrop: z.ZodOptional<z.ZodString>;
|
|
220
257
|
}, "strip", z.ZodTypeAny, {
|
|
221
258
|
foreground: string;
|
|
222
259
|
background: string;
|
|
223
260
|
description?: string | undefined;
|
|
224
261
|
ratio?: number | undefined;
|
|
262
|
+
backdrop?: string | undefined;
|
|
225
263
|
}, {
|
|
226
264
|
foreground: string;
|
|
227
265
|
background: string;
|
|
228
266
|
description?: string | undefined;
|
|
229
267
|
ratio?: number | undefined;
|
|
268
|
+
backdrop?: string | undefined;
|
|
230
269
|
}>, "many">>;
|
|
231
270
|
}, z.ZodTypeAny, "passthrough">>>;
|
|
232
271
|
}, z.ZodTypeAny, "passthrough">>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAMzB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAEd,CAAC;AAEjB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAGZ,CAAC;AAEjB,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,KAAK,CAAC,EAAE,eAAe,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAO3F"}
|
package/cli/config-schema.js
CHANGED
|
@@ -3,7 +3,8 @@ export const WcagRuleSchema = z.object({
|
|
|
3
3
|
foreground: z.string(),
|
|
4
4
|
background: z.string(),
|
|
5
5
|
ratio: z.number().positive().optional(),
|
|
6
|
-
description: z.string().optional()
|
|
6
|
+
description: z.string().optional(),
|
|
7
|
+
backdrop: z.string().optional()
|
|
7
8
|
});
|
|
8
9
|
export const ConstraintsSchema = z.object({
|
|
9
10
|
wcag: z.array(WcagRuleSchema).optional()
|
|
@@ -15,7 +16,8 @@ export const DcvConfigSchema = z.object({
|
|
|
15
16
|
export function validateConfig(raw) {
|
|
16
17
|
const res = DcvConfigSchema.safeParse(raw);
|
|
17
18
|
if (!res.success) {
|
|
18
|
-
|
|
19
|
+
// zod v4 renamed ZodError.errors -> .issues (the .errors getter was removed).
|
|
20
|
+
return { errors: res.error.issues.map((e) => `${e.path.join('.') || '<root>'}: ${e.message}`) };
|
|
19
21
|
}
|
|
20
22
|
return { value: res.data };
|
|
21
23
|
}
|
package/cli/config-schema.ts
CHANGED
|
@@ -4,7 +4,8 @@ export const WcagRuleSchema = z.object({
|
|
|
4
4
|
foreground: z.string(),
|
|
5
5
|
background: z.string(),
|
|
6
6
|
ratio: z.number().positive().optional(),
|
|
7
|
-
description: z.string().optional()
|
|
7
|
+
description: z.string().optional(),
|
|
8
|
+
backdrop: z.string().optional()
|
|
8
9
|
});
|
|
9
10
|
|
|
10
11
|
export const ConstraintsSchema = z.object({
|
|
@@ -21,7 +22,8 @@ export type DcvConfigParsed = z.infer<typeof DcvConfigSchema>;
|
|
|
21
22
|
export function validateConfig(raw: unknown): { value?: DcvConfigParsed; errors?: string[] } {
|
|
22
23
|
const res = DcvConfigSchema.safeParse(raw);
|
|
23
24
|
if (!res.success) {
|
|
24
|
-
|
|
25
|
+
// zod v4 renamed ZodError.errors -> .issues (the .errors getter was removed).
|
|
26
|
+
return { errors: res.error.issues.map((e) => `${e.path.join('.') || '<root>'}: ${e.message}`) };
|
|
25
27
|
}
|
|
26
28
|
return { value: res.data };
|
|
27
29
|
}
|
package/cli/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAkCzE"}
|
package/cli/config.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { basename, extname } from 'node:path';
|
|
2
3
|
import { validateConfig } from './config-schema.js';
|
|
3
4
|
import { ok, err } from './result.js';
|
|
4
5
|
export function loadConfig(configPath) {
|
|
6
|
+
if (configPath && !existsSync(configPath)) {
|
|
7
|
+
return err(`Config file not found: ${configPath}`);
|
|
8
|
+
}
|
|
5
9
|
const candidates = configPath ? [configPath] : [
|
|
6
10
|
'dcv.config.json',
|
|
7
|
-
'dcv.config.js',
|
|
8
11
|
'.dcvrc.json',
|
|
9
12
|
'package.json'
|
|
10
13
|
];
|
|
11
14
|
for (const p of candidates) {
|
|
12
15
|
if (!existsSync(p))
|
|
13
16
|
continue;
|
|
17
|
+
if (extname(p) === '.js') {
|
|
18
|
+
return err(`Unsupported config file ${p}: use JSON config (dcv.config.json, .dcvrc.json, or package.json "dcv").`);
|
|
19
|
+
}
|
|
14
20
|
try {
|
|
15
21
|
const rawTxt = readFileSync(p, 'utf8');
|
|
16
22
|
let raw = JSON.parse(rawTxt);
|
|
17
|
-
if (p === 'package.json' && raw && typeof raw === 'object') {
|
|
23
|
+
if (basename(p) === 'package.json' && raw && typeof raw === 'object') {
|
|
18
24
|
const pkg = raw;
|
|
19
25
|
if ('dcv' in pkg) {
|
|
20
26
|
raw = pkg.dcv;
|
package/cli/config.ts
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { basename, extname } from 'node:path';
|
|
2
3
|
import { validateConfig } from './config-schema.js';
|
|
3
4
|
import { ok, err, type Result } from './result.js';
|
|
4
5
|
import type { DcvConfig } from './types.js';
|
|
5
6
|
|
|
6
7
|
export function loadConfig(configPath?: string): Result<DcvConfig, string> {
|
|
8
|
+
if (configPath && !existsSync(configPath)) {
|
|
9
|
+
return err(`Config file not found: ${configPath}`);
|
|
10
|
+
}
|
|
7
11
|
const candidates = configPath ? [configPath] : [
|
|
8
12
|
'dcv.config.json',
|
|
9
|
-
'dcv.config.js',
|
|
10
13
|
'.dcvrc.json',
|
|
11
14
|
'package.json'
|
|
12
15
|
];
|
|
13
16
|
for (const p of candidates) {
|
|
14
17
|
if (!existsSync(p)) continue;
|
|
18
|
+
if (extname(p) === '.js') {
|
|
19
|
+
return err(`Unsupported config file ${p}: use JSON config (dcv.config.json, .dcvrc.json, or package.json "dcv").`);
|
|
20
|
+
}
|
|
15
21
|
try {
|
|
16
22
|
const rawTxt = readFileSync(p, 'utf8');
|
|
17
23
|
let raw: unknown = JSON.parse(rawTxt);
|
|
18
|
-
if (p === 'package.json' && raw && typeof raw === 'object') {
|
|
24
|
+
if (basename(p) === 'package.json' && raw && typeof raw === 'object') {
|
|
19
25
|
const pkg = raw as Record<string, unknown>;
|
|
20
26
|
if ('dcv' in pkg) {
|
|
21
27
|
raw = pkg.dcv;
|
|
@@ -67,6 +67,8 @@ export type AttachOptions = {
|
|
|
67
67
|
knownIds: Set<string>;
|
|
68
68
|
crossAxisDebug?: boolean;
|
|
69
69
|
};
|
|
70
|
+
export declare const DEFAULT_WCAG_PAIRS: WcagRule[];
|
|
71
|
+
export declare const DEFAULT_THRESHOLDS: ThresholdRule[];
|
|
70
72
|
/**
|
|
71
73
|
* Discover all constraint sources for a given configuration and breakpoint.
|
|
72
74
|
*
|
|
@@ -98,4 +100,18 @@ export declare function attachConstraints(engine: Engine, sources: ConstraintSou
|
|
|
98
100
|
* @param attachOpts Attachment options
|
|
99
101
|
*/
|
|
100
102
|
export declare function setupConstraints(engine: Engine, discoveryOpts: DiscoveryOptions, attachOpts: AttachOptions): ConstraintSource[];
|
|
103
|
+
/**
|
|
104
|
+
* Collect the token ids referenced by the active constraint sources, plus
|
|
105
|
+
* whether that coverage is fully enumerable.
|
|
106
|
+
*
|
|
107
|
+
* Used to detect the silent-pass case: a token file that validates with zero
|
|
108
|
+
* errors only because no active constraint references any of its tokens. Cross-
|
|
109
|
+
* axis rule ids are not enumerated here, so when any cross-axis source is present
|
|
110
|
+
* `coverageKnown` is false and callers must stay conservative (never claim
|
|
111
|
+
* "nothing was checked" when they cannot be sure).
|
|
112
|
+
*/
|
|
113
|
+
export declare function collectReferencedIds(sources: ConstraintSource[]): {
|
|
114
|
+
ids: Set<string>;
|
|
115
|
+
coverageKnown: boolean;
|
|
116
|
+
};
|
|
101
117
|
//# sourceMappingURL=constraint-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constraint-registry.d.ts","sourceRoot":"","sources":["constraint-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAY5C,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAEtD,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,IAAI,GAAG,IAAI,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,QAAQ,EAAE,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,UAAU,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAMF;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CA8F9E;AAMD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"constraint-registry.d.ts","sourceRoot":"","sources":["constraint-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,16 @@ import { WcagContrastPlugin } from '../core/constraints/wcag.js';
|
|
|
18
18
|
import { ThresholdPlugin } from '../core/constraints/threshold.js';
|
|
19
19
|
import { CrossAxisPlugin } from '../core/constraints/cross-axis.js';
|
|
20
20
|
import { loadCrossAxisRules } from './cross-axis-loader.js';
|
|
21
|
+
// Built-in default constraint rules. Shared by attachConstraints (to register
|
|
22
|
+
// plugins) and collectReferencedIds (to compute coverage) so the two never drift.
|
|
23
|
+
export const DEFAULT_WCAG_PAIRS = [
|
|
24
|
+
{ fg: 'color.role.text.default', bg: 'color.role.bg.surface', min: 4.5, where: 'Body text on surface' },
|
|
25
|
+
{ fg: 'color.role.accent.default', bg: 'color.role.bg.surface', min: 3.0, where: 'Accent on surface' },
|
|
26
|
+
{ fg: 'color.role.focus.ring', bg: 'color.role.bg.surface', min: 3.0, where: 'Focus ring on surface', backdrop: '#ffffff' },
|
|
27
|
+
];
|
|
28
|
+
export const DEFAULT_THRESHOLDS = [
|
|
29
|
+
{ id: 'control.size.min', op: '>=', valuePx: 44, where: 'Touch target (WCAG / Apple HIG)' },
|
|
30
|
+
];
|
|
21
31
|
// ============================================================================
|
|
22
32
|
// Discovery
|
|
23
33
|
// ============================================================================
|
|
@@ -132,42 +142,13 @@ export function attachConstraints(engine, sources, opts) {
|
|
|
132
142
|
switch (source.type) {
|
|
133
143
|
case 'builtin-wcag': {
|
|
134
144
|
if (source.enabled) {
|
|
135
|
-
|
|
136
|
-
{
|
|
137
|
-
fg: 'color.role.text.default',
|
|
138
|
-
bg: 'color.role.bg.surface',
|
|
139
|
-
min: 4.5,
|
|
140
|
-
where: 'Body text on surface',
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
fg: 'color.role.accent.default',
|
|
144
|
-
bg: 'color.role.bg.surface',
|
|
145
|
-
min: 3.0,
|
|
146
|
-
where: 'Accent on surface',
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
fg: 'color.role.focus.ring',
|
|
150
|
-
bg: 'color.role.bg.surface',
|
|
151
|
-
min: 3.0,
|
|
152
|
-
where: 'Focus ring on surface',
|
|
153
|
-
backdrop: '#ffffff',
|
|
154
|
-
},
|
|
155
|
-
];
|
|
156
|
-
engine.use(WcagContrastPlugin(defaultWcagPairs));
|
|
145
|
+
engine.use(WcagContrastPlugin(DEFAULT_WCAG_PAIRS));
|
|
157
146
|
}
|
|
158
147
|
break;
|
|
159
148
|
}
|
|
160
149
|
case 'builtin-threshold': {
|
|
161
150
|
if (source.enabled) {
|
|
162
|
-
|
|
163
|
-
{
|
|
164
|
-
id: 'control.size.min',
|
|
165
|
-
op: '>=',
|
|
166
|
-
valuePx: 44,
|
|
167
|
-
where: 'Touch target (WCAG / Apple HIG)',
|
|
168
|
-
},
|
|
169
|
-
];
|
|
170
|
-
engine.use(ThresholdPlugin(defaultThresholds, 'threshold'));
|
|
151
|
+
engine.use(ThresholdPlugin(DEFAULT_THRESHOLDS, 'threshold'));
|
|
171
152
|
}
|
|
172
153
|
break;
|
|
173
154
|
}
|
|
@@ -223,3 +204,55 @@ export function setupConstraints(engine, discoveryOpts, attachOpts) {
|
|
|
223
204
|
attachConstraints(engine, sources, attachOpts);
|
|
224
205
|
return sources;
|
|
225
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Collect the token ids referenced by the active constraint sources, plus
|
|
209
|
+
* whether that coverage is fully enumerable.
|
|
210
|
+
*
|
|
211
|
+
* Used to detect the silent-pass case: a token file that validates with zero
|
|
212
|
+
* errors only because no active constraint references any of its tokens. Cross-
|
|
213
|
+
* axis rule ids are not enumerated here, so when any cross-axis source is present
|
|
214
|
+
* `coverageKnown` is false and callers must stay conservative (never claim
|
|
215
|
+
* "nothing was checked" when they cannot be sure).
|
|
216
|
+
*/
|
|
217
|
+
export function collectReferencedIds(sources) {
|
|
218
|
+
const ids = new Set();
|
|
219
|
+
let coverageKnown = true;
|
|
220
|
+
const addOrders = (orders) => {
|
|
221
|
+
for (const [a, , b] of orders) {
|
|
222
|
+
ids.add(a);
|
|
223
|
+
ids.add(b);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
for (const source of sources) {
|
|
227
|
+
switch (source.type) {
|
|
228
|
+
case 'builtin-wcag':
|
|
229
|
+
for (const p of DEFAULT_WCAG_PAIRS) {
|
|
230
|
+
ids.add(p.fg);
|
|
231
|
+
ids.add(p.bg);
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
case 'builtin-threshold':
|
|
235
|
+
for (const t of DEFAULT_THRESHOLDS)
|
|
236
|
+
ids.add(t.id);
|
|
237
|
+
break;
|
|
238
|
+
case 'config-wcag':
|
|
239
|
+
for (const r of source.rules) {
|
|
240
|
+
ids.add(r.fg);
|
|
241
|
+
ids.add(r.bg);
|
|
242
|
+
}
|
|
243
|
+
break;
|
|
244
|
+
case 'custom-threshold':
|
|
245
|
+
for (const r of source.rules)
|
|
246
|
+
ids.add(r.id);
|
|
247
|
+
break;
|
|
248
|
+
case 'order-file':
|
|
249
|
+
case 'lightness-file':
|
|
250
|
+
addOrders(source.orders);
|
|
251
|
+
break;
|
|
252
|
+
case 'cross-axis-file':
|
|
253
|
+
coverageKnown = false;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return { ids, coverageKnown };
|
|
258
|
+
}
|
|
@@ -69,6 +69,18 @@ export type AttachOptions = {
|
|
|
69
69
|
crossAxisDebug?: boolean;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
+
// Built-in default constraint rules. Shared by attachConstraints (to register
|
|
73
|
+
// plugins) and collectReferencedIds (to compute coverage) so the two never drift.
|
|
74
|
+
export const DEFAULT_WCAG_PAIRS: WcagRule[] = [
|
|
75
|
+
{ fg: 'color.role.text.default', bg: 'color.role.bg.surface', min: 4.5, where: 'Body text on surface' },
|
|
76
|
+
{ fg: 'color.role.accent.default', bg: 'color.role.bg.surface', min: 3.0, where: 'Accent on surface' },
|
|
77
|
+
{ fg: 'color.role.focus.ring', bg: 'color.role.bg.surface', min: 3.0, where: 'Focus ring on surface', backdrop: '#ffffff' },
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
export const DEFAULT_THRESHOLDS: ThresholdRule[] = [
|
|
81
|
+
{ id: 'control.size.min', op: '>=', valuePx: 44, where: 'Touch target (WCAG / Apple HIG)' },
|
|
82
|
+
];
|
|
83
|
+
|
|
72
84
|
// ============================================================================
|
|
73
85
|
// Discovery
|
|
74
86
|
// ============================================================================
|
|
@@ -200,43 +212,14 @@ export function attachConstraints(engine: Engine, sources: ConstraintSource[], o
|
|
|
200
212
|
switch (source.type) {
|
|
201
213
|
case 'builtin-wcag': {
|
|
202
214
|
if (source.enabled) {
|
|
203
|
-
|
|
204
|
-
{
|
|
205
|
-
fg: 'color.role.text.default',
|
|
206
|
-
bg: 'color.role.bg.surface',
|
|
207
|
-
min: 4.5,
|
|
208
|
-
where: 'Body text on surface',
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
fg: 'color.role.accent.default',
|
|
212
|
-
bg: 'color.role.bg.surface',
|
|
213
|
-
min: 3.0,
|
|
214
|
-
where: 'Accent on surface',
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
fg: 'color.role.focus.ring',
|
|
218
|
-
bg: 'color.role.bg.surface',
|
|
219
|
-
min: 3.0,
|
|
220
|
-
where: 'Focus ring on surface',
|
|
221
|
-
backdrop: '#ffffff',
|
|
222
|
-
},
|
|
223
|
-
];
|
|
224
|
-
engine.use(WcagContrastPlugin(defaultWcagPairs));
|
|
215
|
+
engine.use(WcagContrastPlugin(DEFAULT_WCAG_PAIRS));
|
|
225
216
|
}
|
|
226
217
|
break;
|
|
227
218
|
}
|
|
228
219
|
|
|
229
220
|
case 'builtin-threshold': {
|
|
230
221
|
if (source.enabled) {
|
|
231
|
-
|
|
232
|
-
{
|
|
233
|
-
id: 'control.size.min',
|
|
234
|
-
op: '>=',
|
|
235
|
-
valuePx: 44,
|
|
236
|
-
where: 'Touch target (WCAG / Apple HIG)',
|
|
237
|
-
},
|
|
238
|
-
];
|
|
239
|
-
engine.use(ThresholdPlugin(defaultThresholds, 'threshold'));
|
|
222
|
+
engine.use(ThresholdPlugin(DEFAULT_THRESHOLDS, 'threshold'));
|
|
240
223
|
}
|
|
241
224
|
break;
|
|
242
225
|
}
|
|
@@ -302,3 +285,56 @@ export function setupConstraints(
|
|
|
302
285
|
attachConstraints(engine, sources, attachOpts);
|
|
303
286
|
return sources;
|
|
304
287
|
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Collect the token ids referenced by the active constraint sources, plus
|
|
291
|
+
* whether that coverage is fully enumerable.
|
|
292
|
+
*
|
|
293
|
+
* Used to detect the silent-pass case: a token file that validates with zero
|
|
294
|
+
* errors only because no active constraint references any of its tokens. Cross-
|
|
295
|
+
* axis rule ids are not enumerated here, so when any cross-axis source is present
|
|
296
|
+
* `coverageKnown` is false and callers must stay conservative (never claim
|
|
297
|
+
* "nothing was checked" when they cannot be sure).
|
|
298
|
+
*/
|
|
299
|
+
export function collectReferencedIds(sources: ConstraintSource[]): { ids: Set<string>; coverageKnown: boolean } {
|
|
300
|
+
const ids = new Set<string>();
|
|
301
|
+
let coverageKnown = true;
|
|
302
|
+
const addOrders = (orders: OrderRule[]) => {
|
|
303
|
+
for (const [a, , b] of orders) {
|
|
304
|
+
ids.add(a);
|
|
305
|
+
ids.add(b);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
for (const source of sources) {
|
|
310
|
+
switch (source.type) {
|
|
311
|
+
case 'builtin-wcag':
|
|
312
|
+
for (const p of DEFAULT_WCAG_PAIRS) {
|
|
313
|
+
ids.add(p.fg);
|
|
314
|
+
ids.add(p.bg);
|
|
315
|
+
}
|
|
316
|
+
break;
|
|
317
|
+
case 'builtin-threshold':
|
|
318
|
+
for (const t of DEFAULT_THRESHOLDS) ids.add(t.id);
|
|
319
|
+
break;
|
|
320
|
+
case 'config-wcag':
|
|
321
|
+
for (const r of source.rules) {
|
|
322
|
+
ids.add(r.fg);
|
|
323
|
+
ids.add(r.bg);
|
|
324
|
+
}
|
|
325
|
+
break;
|
|
326
|
+
case 'custom-threshold':
|
|
327
|
+
for (const r of source.rules) ids.add(r.id);
|
|
328
|
+
break;
|
|
329
|
+
case 'order-file':
|
|
330
|
+
case 'lightness-file':
|
|
331
|
+
addOrders(source.orders);
|
|
332
|
+
break;
|
|
333
|
+
case 'cross-axis-file':
|
|
334
|
+
coverageKnown = false;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return { ids, coverageKnown };
|
|
340
|
+
}
|