design-constraint-validator 2.1.0 → 2.2.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 +17 -6
- package/cli/commands/build.d.ts.map +1 -1
- package/cli/commands/build.js +32 -24
- package/cli/commands/build.ts +26 -17
- package/cli/commands/graph.d.ts.map +1 -1
- package/cli/commands/graph.js +33 -16
- package/cli/commands/graph.ts +28 -15
- package/cli/commands/patch-apply.d.ts.map +1 -1
- package/cli/commands/patch-apply.js +4 -1
- package/cli/commands/patch-apply.ts +4 -1
- package/cli/commands/set.d.ts.map +1 -1
- package/cli/commands/set.js +18 -19
- package/cli/commands/set.ts +19 -19
- package/cli/commands/utils.d.ts +1 -0
- package/cli/commands/utils.d.ts.map +1 -1
- package/cli/commands/utils.js +20 -1
- package/cli/commands/utils.ts +23 -1
- package/cli/commands/validate.d.ts.map +1 -1
- package/cli/commands/validate.js +5 -17
- package/cli/commands/validate.ts +10 -18
- package/cli/commands/why.d.ts.map +1 -1
- package/cli/commands/why.js +22 -10
- package/cli/commands/why.ts +20 -9
- package/cli/config-schema.d.ts +144 -178
- package/cli/config-schema.d.ts.map +1 -1
- package/cli/config-schema.js +25 -5
- package/cli/config-schema.ts +27 -5
- package/cli/constraint-registry.d.ts.map +1 -1
- package/cli/constraint-registry.js +53 -15
- package/cli/constraint-registry.ts +53 -18
- package/cli/cross-axis-loader.d.ts +62 -0
- package/cli/cross-axis-loader.d.ts.map +1 -1
- package/cli/cross-axis-loader.js +186 -31
- package/cli/cross-axis-loader.ts +199 -24
- package/cli/dcv.js +23 -1
- package/cli/dcv.ts +23 -1
- package/cli/types.d.ts +19 -9
- package/cli/types.d.ts.map +1 -1
- package/cli/types.ts +23 -10
- package/cli/validate-api.d.ts.map +1 -1
- package/cli/validate-api.js +6 -1
- package/cli/validate-api.ts +6 -1
- package/core/constraints/cross-axis.d.ts.map +1 -1
- package/core/constraints/cross-axis.js +37 -9
- package/core/constraints/cross-axis.ts +37 -9
- package/core/constraints/monotonic.d.ts.map +1 -1
- package/core/constraints/monotonic.js +32 -8
- package/core/constraints/monotonic.ts +29 -8
- package/core/constraints/threshold.d.ts.map +1 -1
- package/core/constraints/threshold.js +24 -4
- package/core/constraints/threshold.ts +23 -4
- package/core/constraints/wcag.js +1 -1
- package/core/constraints/wcag.ts +1 -1
- package/core/flatten.d.ts.map +1 -1
- package/core/flatten.js +8 -0
- package/core/flatten.ts +9 -0
- package/core/poset.d.ts +6 -1
- package/core/poset.d.ts.map +1 -1
- package/core/poset.js +7 -2
- package/core/poset.ts +7 -2
- package/mcp/contracts.d.ts +1456 -13
- package/mcp/contracts.d.ts.map +1 -1
- package/mcp/contracts.js +45 -1
- package/mcp/contracts.ts +55 -1
- package/mcp/index.d.ts +6 -4
- package/mcp/index.d.ts.map +1 -1
- package/mcp/index.js +6 -3
- package/mcp/index.ts +28 -1
- package/mcp/insights.d.ts +94 -0
- package/mcp/insights.d.ts.map +1 -0
- package/mcp/insights.js +445 -0
- package/mcp/insights.ts +541 -0
- package/mcp/tools.d.ts +14 -3
- package/mcp/tools.d.ts.map +1 -1
- package/mcp/tools.js +133 -6
- package/mcp/tools.ts +188 -11
- package/package.json +1 -6
- package/server.json +2 -2
package/cli/config-schema.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const WcagRuleSchema: z.ZodObject<{
|
|
|
5
5
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
6
6
|
description: z.ZodOptional<z.ZodString>;
|
|
7
7
|
backdrop: z.ZodOptional<z.ZodString>;
|
|
8
|
-
}, "
|
|
8
|
+
}, "strict", z.ZodTypeAny, {
|
|
9
9
|
foreground: string;
|
|
10
10
|
background: string;
|
|
11
11
|
description?: string | undefined;
|
|
@@ -18,14 +18,35 @@ export declare const WcagRuleSchema: z.ZodObject<{
|
|
|
18
18
|
ratio?: number | undefined;
|
|
19
19
|
backdrop?: string | undefined;
|
|
20
20
|
}>;
|
|
21
|
+
export declare const ThresholdRuleSchema: z.ZodObject<{
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
op: z.ZodEnum<["<=", ">="]>;
|
|
24
|
+
valuePx: z.ZodNumber;
|
|
25
|
+
where: z.ZodOptional<z.ZodString>;
|
|
26
|
+
level: z.ZodOptional<z.ZodEnum<["error", "warn"]>>;
|
|
27
|
+
}, "strict", z.ZodTypeAny, {
|
|
28
|
+
id: string;
|
|
29
|
+
op: "<=" | ">=";
|
|
30
|
+
valuePx: number;
|
|
31
|
+
where?: string | undefined;
|
|
32
|
+
level?: "error" | "warn" | undefined;
|
|
33
|
+
}, {
|
|
34
|
+
id: string;
|
|
35
|
+
op: "<=" | ">=";
|
|
36
|
+
valuePx: number;
|
|
37
|
+
where?: string | undefined;
|
|
38
|
+
level?: "error" | "warn" | undefined;
|
|
39
|
+
}>;
|
|
21
40
|
export declare const ConstraintsSchema: z.ZodObject<{
|
|
41
|
+
enableBuiltInWcagDefaults: z.ZodOptional<z.ZodBoolean>;
|
|
42
|
+
enableBuiltInThreshold: z.ZodOptional<z.ZodBoolean>;
|
|
22
43
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
23
44
|
foreground: z.ZodString;
|
|
24
45
|
background: z.ZodString;
|
|
25
46
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
26
47
|
description: z.ZodOptional<z.ZodString>;
|
|
27
48
|
backdrop: z.ZodOptional<z.ZodString>;
|
|
28
|
-
}, "
|
|
49
|
+
}, "strict", z.ZodTypeAny, {
|
|
29
50
|
foreground: string;
|
|
30
51
|
background: string;
|
|
31
52
|
description?: string | undefined;
|
|
@@ -38,57 +59,73 @@ export declare const ConstraintsSchema: z.ZodObject<{
|
|
|
38
59
|
ratio?: number | undefined;
|
|
39
60
|
backdrop?: string | undefined;
|
|
40
61
|
}>, "many">>;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
backdrop?: string | undefined;
|
|
62
|
+
thresholds: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
63
|
+
id: z.ZodString;
|
|
64
|
+
op: z.ZodEnum<["<=", ">="]>;
|
|
65
|
+
valuePx: z.ZodNumber;
|
|
66
|
+
where: z.ZodOptional<z.ZodString>;
|
|
67
|
+
level: z.ZodOptional<z.ZodEnum<["error", "warn"]>>;
|
|
68
|
+
}, "strict", z.ZodTypeAny, {
|
|
69
|
+
id: string;
|
|
70
|
+
op: "<=" | ">=";
|
|
71
|
+
valuePx: number;
|
|
72
|
+
where?: string | undefined;
|
|
73
|
+
level?: "error" | "warn" | undefined;
|
|
54
74
|
}, {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
id: string;
|
|
76
|
+
op: "<=" | ">=";
|
|
77
|
+
valuePx: number;
|
|
78
|
+
where?: string | undefined;
|
|
79
|
+
level?: "error" | "warn" | undefined;
|
|
60
80
|
}>, "many">>;
|
|
61
|
-
}, z.ZodTypeAny,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
ratio: z.ZodOptional<z.ZodNumber>;
|
|
66
|
-
description: z.ZodOptional<z.ZodString>;
|
|
67
|
-
backdrop: z.ZodOptional<z.ZodString>;
|
|
68
|
-
}, "strip", z.ZodTypeAny, {
|
|
81
|
+
}, "strict", z.ZodTypeAny, {
|
|
82
|
+
enableBuiltInWcagDefaults?: boolean | undefined;
|
|
83
|
+
enableBuiltInThreshold?: boolean | undefined;
|
|
84
|
+
wcag?: {
|
|
69
85
|
foreground: string;
|
|
70
86
|
background: string;
|
|
71
87
|
description?: string | undefined;
|
|
72
88
|
ratio?: number | undefined;
|
|
73
89
|
backdrop?: string | undefined;
|
|
74
|
-
}
|
|
90
|
+
}[] | undefined;
|
|
91
|
+
thresholds?: {
|
|
92
|
+
id: string;
|
|
93
|
+
op: "<=" | ">=";
|
|
94
|
+
valuePx: number;
|
|
95
|
+
where?: string | undefined;
|
|
96
|
+
level?: "error" | "warn" | undefined;
|
|
97
|
+
}[] | undefined;
|
|
98
|
+
}, {
|
|
99
|
+
enableBuiltInWcagDefaults?: boolean | undefined;
|
|
100
|
+
enableBuiltInThreshold?: boolean | undefined;
|
|
101
|
+
wcag?: {
|
|
75
102
|
foreground: string;
|
|
76
103
|
background: string;
|
|
77
104
|
description?: string | undefined;
|
|
78
105
|
ratio?: number | undefined;
|
|
79
106
|
backdrop?: string | undefined;
|
|
80
|
-
}
|
|
81
|
-
|
|
107
|
+
}[] | undefined;
|
|
108
|
+
thresholds?: {
|
|
109
|
+
id: string;
|
|
110
|
+
op: "<=" | ">=";
|
|
111
|
+
valuePx: number;
|
|
112
|
+
where?: string | undefined;
|
|
113
|
+
level?: "error" | "warn" | undefined;
|
|
114
|
+
}[] | undefined;
|
|
115
|
+
}>;
|
|
82
116
|
export declare const DcvConfigSchema: z.ZodObject<{
|
|
117
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
83
118
|
version: z.ZodOptional<z.ZodString>;
|
|
84
119
|
constraints: z.ZodOptional<z.ZodObject<{
|
|
120
|
+
enableBuiltInWcagDefaults: z.ZodOptional<z.ZodBoolean>;
|
|
121
|
+
enableBuiltInThreshold: z.ZodOptional<z.ZodBoolean>;
|
|
85
122
|
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
86
123
|
foreground: z.ZodString;
|
|
87
124
|
background: z.ZodString;
|
|
88
125
|
ratio: z.ZodOptional<z.ZodNumber>;
|
|
89
126
|
description: z.ZodOptional<z.ZodString>;
|
|
90
127
|
backdrop: z.ZodOptional<z.ZodString>;
|
|
91
|
-
}, "
|
|
128
|
+
}, "strict", z.ZodTypeAny, {
|
|
92
129
|
foreground: string;
|
|
93
130
|
background: string;
|
|
94
131
|
description?: string | undefined;
|
|
@@ -101,174 +138,103 @@ export declare const DcvConfigSchema: z.ZodObject<{
|
|
|
101
138
|
ratio?: number | undefined;
|
|
102
139
|
backdrop?: string | undefined;
|
|
103
140
|
}>, "many">>;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
backdrop?: string | undefined;
|
|
141
|
+
thresholds: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
142
|
+
id: z.ZodString;
|
|
143
|
+
op: z.ZodEnum<["<=", ">="]>;
|
|
144
|
+
valuePx: z.ZodNumber;
|
|
145
|
+
where: z.ZodOptional<z.ZodString>;
|
|
146
|
+
level: z.ZodOptional<z.ZodEnum<["error", "warn"]>>;
|
|
147
|
+
}, "strict", z.ZodTypeAny, {
|
|
148
|
+
id: string;
|
|
149
|
+
op: "<=" | ">=";
|
|
150
|
+
valuePx: number;
|
|
151
|
+
where?: string | undefined;
|
|
152
|
+
level?: "error" | "warn" | undefined;
|
|
117
153
|
}, {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
154
|
+
id: string;
|
|
155
|
+
op: "<=" | ">=";
|
|
156
|
+
valuePx: number;
|
|
157
|
+
where?: string | undefined;
|
|
158
|
+
level?: "error" | "warn" | undefined;
|
|
123
159
|
}>, "many">>;
|
|
124
|
-
}, z.ZodTypeAny,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
ratio: z.ZodOptional<z.ZodNumber>;
|
|
129
|
-
description: z.ZodOptional<z.ZodString>;
|
|
130
|
-
backdrop: z.ZodOptional<z.ZodString>;
|
|
131
|
-
}, "strip", z.ZodTypeAny, {
|
|
160
|
+
}, "strict", z.ZodTypeAny, {
|
|
161
|
+
enableBuiltInWcagDefaults?: boolean | undefined;
|
|
162
|
+
enableBuiltInThreshold?: boolean | undefined;
|
|
163
|
+
wcag?: {
|
|
132
164
|
foreground: string;
|
|
133
165
|
background: string;
|
|
134
166
|
description?: string | undefined;
|
|
135
167
|
ratio?: number | undefined;
|
|
136
168
|
backdrop?: string | undefined;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
wcag
|
|
149
|
-
foreground: z.ZodString;
|
|
150
|
-
background: z.ZodString;
|
|
151
|
-
ratio: z.ZodOptional<z.ZodNumber>;
|
|
152
|
-
description: z.ZodOptional<z.ZodString>;
|
|
153
|
-
backdrop: z.ZodOptional<z.ZodString>;
|
|
154
|
-
}, "strip", z.ZodTypeAny, {
|
|
155
|
-
foreground: string;
|
|
156
|
-
background: string;
|
|
157
|
-
description?: string | undefined;
|
|
158
|
-
ratio?: number | undefined;
|
|
159
|
-
backdrop?: string | undefined;
|
|
160
|
-
}, {
|
|
161
|
-
foreground: string;
|
|
162
|
-
background: string;
|
|
163
|
-
description?: string | undefined;
|
|
164
|
-
ratio?: number | undefined;
|
|
165
|
-
backdrop?: string | undefined;
|
|
166
|
-
}>, "many">>;
|
|
167
|
-
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
168
|
-
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
169
|
-
foreground: z.ZodString;
|
|
170
|
-
background: z.ZodString;
|
|
171
|
-
ratio: z.ZodOptional<z.ZodNumber>;
|
|
172
|
-
description: z.ZodOptional<z.ZodString>;
|
|
173
|
-
backdrop: z.ZodOptional<z.ZodString>;
|
|
174
|
-
}, "strip", z.ZodTypeAny, {
|
|
175
|
-
foreground: string;
|
|
176
|
-
background: string;
|
|
177
|
-
description?: string | undefined;
|
|
178
|
-
ratio?: number | undefined;
|
|
179
|
-
backdrop?: string | undefined;
|
|
180
|
-
}, {
|
|
181
|
-
foreground: string;
|
|
182
|
-
background: string;
|
|
183
|
-
description?: string | undefined;
|
|
184
|
-
ratio?: number | undefined;
|
|
185
|
-
backdrop?: string | undefined;
|
|
186
|
-
}>, "many">>;
|
|
187
|
-
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
188
|
-
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
189
|
-
foreground: z.ZodString;
|
|
190
|
-
background: z.ZodString;
|
|
191
|
-
ratio: z.ZodOptional<z.ZodNumber>;
|
|
192
|
-
description: z.ZodOptional<z.ZodString>;
|
|
193
|
-
backdrop: z.ZodOptional<z.ZodString>;
|
|
194
|
-
}, "strip", z.ZodTypeAny, {
|
|
195
|
-
foreground: string;
|
|
196
|
-
background: string;
|
|
197
|
-
description?: string | undefined;
|
|
198
|
-
ratio?: number | undefined;
|
|
199
|
-
backdrop?: string | undefined;
|
|
200
|
-
}, {
|
|
201
|
-
foreground: string;
|
|
202
|
-
background: string;
|
|
203
|
-
description?: string | undefined;
|
|
204
|
-
ratio?: number | undefined;
|
|
205
|
-
backdrop?: string | undefined;
|
|
206
|
-
}>, "many">>;
|
|
207
|
-
}, z.ZodTypeAny, "passthrough">>>;
|
|
208
|
-
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
209
|
-
version: z.ZodOptional<z.ZodString>;
|
|
210
|
-
constraints: z.ZodOptional<z.ZodObject<{
|
|
211
|
-
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
212
|
-
foreground: z.ZodString;
|
|
213
|
-
background: z.ZodString;
|
|
214
|
-
ratio: z.ZodOptional<z.ZodNumber>;
|
|
215
|
-
description: z.ZodOptional<z.ZodString>;
|
|
216
|
-
backdrop: z.ZodOptional<z.ZodString>;
|
|
217
|
-
}, "strip", z.ZodTypeAny, {
|
|
218
|
-
foreground: string;
|
|
219
|
-
background: string;
|
|
220
|
-
description?: string | undefined;
|
|
221
|
-
ratio?: number | undefined;
|
|
222
|
-
backdrop?: string | undefined;
|
|
223
|
-
}, {
|
|
224
|
-
foreground: string;
|
|
225
|
-
background: string;
|
|
226
|
-
description?: string | undefined;
|
|
227
|
-
ratio?: number | undefined;
|
|
228
|
-
backdrop?: string | undefined;
|
|
229
|
-
}>, "many">>;
|
|
230
|
-
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
231
|
-
wcag: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
232
|
-
foreground: z.ZodString;
|
|
233
|
-
background: z.ZodString;
|
|
234
|
-
ratio: z.ZodOptional<z.ZodNumber>;
|
|
235
|
-
description: z.ZodOptional<z.ZodString>;
|
|
236
|
-
backdrop: z.ZodOptional<z.ZodString>;
|
|
237
|
-
}, "strip", z.ZodTypeAny, {
|
|
169
|
+
}[] | undefined;
|
|
170
|
+
thresholds?: {
|
|
171
|
+
id: string;
|
|
172
|
+
op: "<=" | ">=";
|
|
173
|
+
valuePx: number;
|
|
174
|
+
where?: string | undefined;
|
|
175
|
+
level?: "error" | "warn" | undefined;
|
|
176
|
+
}[] | undefined;
|
|
177
|
+
}, {
|
|
178
|
+
enableBuiltInWcagDefaults?: boolean | undefined;
|
|
179
|
+
enableBuiltInThreshold?: boolean | undefined;
|
|
180
|
+
wcag?: {
|
|
238
181
|
foreground: string;
|
|
239
182
|
background: string;
|
|
240
183
|
description?: string | undefined;
|
|
241
184
|
ratio?: number | undefined;
|
|
242
185
|
backdrop?: string | undefined;
|
|
243
|
-
}
|
|
186
|
+
}[] | undefined;
|
|
187
|
+
thresholds?: {
|
|
188
|
+
id: string;
|
|
189
|
+
op: "<=" | ">=";
|
|
190
|
+
valuePx: number;
|
|
191
|
+
where?: string | undefined;
|
|
192
|
+
level?: "error" | "warn" | undefined;
|
|
193
|
+
}[] | undefined;
|
|
194
|
+
}>>;
|
|
195
|
+
}, "strict", z.ZodTypeAny, {
|
|
196
|
+
$schema?: string | undefined;
|
|
197
|
+
version?: string | undefined;
|
|
198
|
+
constraints?: {
|
|
199
|
+
enableBuiltInWcagDefaults?: boolean | undefined;
|
|
200
|
+
enableBuiltInThreshold?: boolean | undefined;
|
|
201
|
+
wcag?: {
|
|
244
202
|
foreground: string;
|
|
245
203
|
background: string;
|
|
246
204
|
description?: string | undefined;
|
|
247
205
|
ratio?: number | undefined;
|
|
248
206
|
backdrop?: string | undefined;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
207
|
+
}[] | undefined;
|
|
208
|
+
thresholds?: {
|
|
209
|
+
id: string;
|
|
210
|
+
op: "<=" | ">=";
|
|
211
|
+
valuePx: number;
|
|
212
|
+
where?: string | undefined;
|
|
213
|
+
level?: "error" | "warn" | undefined;
|
|
214
|
+
}[] | undefined;
|
|
215
|
+
} | undefined;
|
|
216
|
+
}, {
|
|
217
|
+
$schema?: string | undefined;
|
|
218
|
+
version?: string | undefined;
|
|
219
|
+
constraints?: {
|
|
220
|
+
enableBuiltInWcagDefaults?: boolean | undefined;
|
|
221
|
+
enableBuiltInThreshold?: boolean | undefined;
|
|
222
|
+
wcag?: {
|
|
264
223
|
foreground: string;
|
|
265
224
|
background: string;
|
|
266
225
|
description?: string | undefined;
|
|
267
226
|
ratio?: number | undefined;
|
|
268
227
|
backdrop?: string | undefined;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
228
|
+
}[] | undefined;
|
|
229
|
+
thresholds?: {
|
|
230
|
+
id: string;
|
|
231
|
+
op: "<=" | ">=";
|
|
232
|
+
valuePx: number;
|
|
233
|
+
where?: string | undefined;
|
|
234
|
+
level?: "error" | "warn" | undefined;
|
|
235
|
+
}[] | undefined;
|
|
236
|
+
} | undefined;
|
|
237
|
+
}>;
|
|
272
238
|
export type DcvConfigParsed = z.infer<typeof DcvConfigSchema>;
|
|
273
239
|
export declare function validateConfig(raw: unknown): {
|
|
274
240
|
value?: DcvConfigParsed;
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAMhB,CAAC;AAEZ,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;EAMrB,CAAC;AAEZ,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKnB,CAAC;AAEZ,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMjB,CAAC;AAEZ,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
|
@@ -1,18 +1,38 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
// Schemas are `.strict()` on purpose (TASK-037): a validator must never silently
|
|
3
|
+
// accept a typo'd key, because "the rule never ran" is indistinguishable from
|
|
4
|
+
// "the rule passed" — a false green. A misspelled block (`wcagg`), a typo'd
|
|
5
|
+
// field (`levle`), or an out-of-range bound is rejected loudly, not dropped.
|
|
6
|
+
// WCAG contrast ratios are bounded by the spec to (1:1, 21:1]: 1 means "no
|
|
7
|
+
// contrast required" (a no-op rule) and 21 is the maximum achievable (#000 on
|
|
8
|
+
// #fff). Anything outside that is a config error, not a stricter policy.
|
|
2
9
|
export const WcagRuleSchema = z.object({
|
|
3
10
|
foreground: z.string(),
|
|
4
11
|
background: z.string(),
|
|
5
|
-
ratio: z.number().
|
|
12
|
+
ratio: z.number().finite().gt(1).max(21).optional(),
|
|
6
13
|
description: z.string().optional(),
|
|
7
14
|
backdrop: z.string().optional()
|
|
8
|
-
});
|
|
15
|
+
}).strict();
|
|
16
|
+
export const ThresholdRuleSchema = z.object({
|
|
17
|
+
id: z.string(),
|
|
18
|
+
op: z.enum(['<=', '>=']),
|
|
19
|
+
valuePx: z.number().finite().nonnegative(),
|
|
20
|
+
where: z.string().optional(),
|
|
21
|
+
level: z.enum(['error', 'warn']).optional()
|
|
22
|
+
}).strict();
|
|
9
23
|
export const ConstraintsSchema = z.object({
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
enableBuiltInWcagDefaults: z.boolean().optional(),
|
|
25
|
+
enableBuiltInThreshold: z.boolean().optional(),
|
|
26
|
+
wcag: z.array(WcagRuleSchema).optional(),
|
|
27
|
+
thresholds: z.array(ThresholdRuleSchema).optional()
|
|
28
|
+
}).strict();
|
|
12
29
|
export const DcvConfigSchema = z.object({
|
|
30
|
+
// `$schema` is the conventional editor-hint key; allow it so strictness does
|
|
31
|
+
// not punish a well-formed config, but still reject unknown top-level typos.
|
|
32
|
+
$schema: z.string().optional(),
|
|
13
33
|
version: z.string().optional(),
|
|
14
34
|
constraints: ConstraintsSchema.optional()
|
|
15
|
-
}).
|
|
35
|
+
}).strict();
|
|
16
36
|
export function validateConfig(raw) {
|
|
17
37
|
const res = DcvConfigSchema.safeParse(raw);
|
|
18
38
|
if (!res.success) {
|
package/cli/config-schema.ts
CHANGED
|
@@ -1,21 +1,43 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
// Schemas are `.strict()` on purpose (TASK-037): a validator must never silently
|
|
4
|
+
// accept a typo'd key, because "the rule never ran" is indistinguishable from
|
|
5
|
+
// "the rule passed" — a false green. A misspelled block (`wcagg`), a typo'd
|
|
6
|
+
// field (`levle`), or an out-of-range bound is rejected loudly, not dropped.
|
|
7
|
+
|
|
8
|
+
// WCAG contrast ratios are bounded by the spec to (1:1, 21:1]: 1 means "no
|
|
9
|
+
// contrast required" (a no-op rule) and 21 is the maximum achievable (#000 on
|
|
10
|
+
// #fff). Anything outside that is a config error, not a stricter policy.
|
|
3
11
|
export const WcagRuleSchema = z.object({
|
|
4
12
|
foreground: z.string(),
|
|
5
13
|
background: z.string(),
|
|
6
|
-
ratio: z.number().
|
|
14
|
+
ratio: z.number().finite().gt(1).max(21).optional(),
|
|
7
15
|
description: z.string().optional(),
|
|
8
16
|
backdrop: z.string().optional()
|
|
9
|
-
});
|
|
17
|
+
}).strict();
|
|
18
|
+
|
|
19
|
+
export const ThresholdRuleSchema = z.object({
|
|
20
|
+
id: z.string(),
|
|
21
|
+
op: z.enum(['<=', '>=']),
|
|
22
|
+
valuePx: z.number().finite().nonnegative(),
|
|
23
|
+
where: z.string().optional(),
|
|
24
|
+
level: z.enum(['error', 'warn']).optional()
|
|
25
|
+
}).strict();
|
|
10
26
|
|
|
11
27
|
export const ConstraintsSchema = z.object({
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
enableBuiltInWcagDefaults: z.boolean().optional(),
|
|
29
|
+
enableBuiltInThreshold: z.boolean().optional(),
|
|
30
|
+
wcag: z.array(WcagRuleSchema).optional(),
|
|
31
|
+
thresholds: z.array(ThresholdRuleSchema).optional()
|
|
32
|
+
}).strict();
|
|
14
33
|
|
|
15
34
|
export const DcvConfigSchema = z.object({
|
|
35
|
+
// `$schema` is the conventional editor-hint key; allow it so strictness does
|
|
36
|
+
// not punish a well-formed config, but still reject unknown top-level typos.
|
|
37
|
+
$schema: z.string().optional(),
|
|
16
38
|
version: z.string().optional(),
|
|
17
39
|
constraints: ConstraintsSchema.optional()
|
|
18
|
-
}).
|
|
40
|
+
}).strict();
|
|
19
41
|
|
|
20
42
|
export type DcvConfigParsed = z.infer<typeof DcvConfigSchema>;
|
|
21
43
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constraint-registry.d.ts","sourceRoot":"","sources":["constraint-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"constraint-registry.d.ts","sourceRoot":"","sources":["constraint-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,13 +11,22 @@
|
|
|
11
11
|
* - All entry points (validate, set, graph) use this registry for consistency
|
|
12
12
|
*/
|
|
13
13
|
import { existsSync, readFileSync } from 'node:fs';
|
|
14
|
-
import { join } from 'node:path';
|
|
14
|
+
import { isAbsolute, join } from 'node:path';
|
|
15
15
|
import { MonotonicPlugin, parseSize as parseSizePx } from '../core/constraints/monotonic.js';
|
|
16
16
|
import { MonotonicLightness } from '../core/constraints/monotonic-lightness.js';
|
|
17
17
|
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
|
-
import {
|
|
20
|
+
import { loadCrossAxisRulesDetailed, referencedIdsForFile } from './cross-axis-loader.js';
|
|
21
|
+
/**
|
|
22
|
+
* A plugin that emits a fixed set of pre-computed issues unconditionally (it
|
|
23
|
+
* ignores the candidate set). Used to surface cross-axis loader notices —
|
|
24
|
+
* present-but-unusable files and skipped invalid rules (TASK-037) — through the
|
|
25
|
+
* normal issue channel so they appear as warnings instead of vanishing.
|
|
26
|
+
*/
|
|
27
|
+
function noticePlugin(notices) {
|
|
28
|
+
return { id: 'cross-axis-notices', evaluate: () => notices };
|
|
29
|
+
}
|
|
21
30
|
// Built-in default constraint rules. Shared by attachConstraints (to register
|
|
22
31
|
// plugins) and collectReferencedIds (to compute coverage) so the two never drift.
|
|
23
32
|
export const DEFAULT_WCAG_PAIRS = [
|
|
@@ -44,6 +53,7 @@ export function discoverConstraints(opts) {
|
|
|
44
53
|
const { config, basePath = '.', bp, constraintsDir = 'themes' } = opts;
|
|
45
54
|
const sources = [];
|
|
46
55
|
const constraintsCfg = config.constraints ?? {};
|
|
56
|
+
const constraintsRoot = isAbsolute(constraintsDir) ? constraintsDir : join(basePath, constraintsDir);
|
|
47
57
|
// 1. Built-in WCAG defaults
|
|
48
58
|
const enableBuiltInWcag = constraintsCfg.enableBuiltInWcagDefaults === undefined ? true : !!constraintsCfg.enableBuiltInWcagDefaults;
|
|
49
59
|
if (enableBuiltInWcag) {
|
|
@@ -72,15 +82,28 @@ export function discoverConstraints(opts) {
|
|
|
72
82
|
op: r.op,
|
|
73
83
|
valuePx: r.valuePx,
|
|
74
84
|
where: r.where,
|
|
85
|
+
// Preserve configured severity (TASK-037): the core plugin honors `level`,
|
|
86
|
+
// but dropping it here silently promoted a `warn` threshold to an error.
|
|
87
|
+
level: r.level,
|
|
75
88
|
}));
|
|
76
89
|
sources.push({ type: 'custom-threshold', rules });
|
|
77
90
|
}
|
|
91
|
+
// A breakpoint uses its own `<axis>.<bp>.order.json` when present, but MUST fall
|
|
92
|
+
// back to the global `<axis>.order.json` otherwise — without this, any axis
|
|
93
|
+
// lacking a per-bp file (e.g. spacing) contributed ZERO constraints under
|
|
94
|
+
// --breakpoint/--all-breakpoints, a silent false-pass (TASK-034).
|
|
95
|
+
const orderPathFor = (base) => {
|
|
96
|
+
const bpPath = bp ? join(constraintsRoot, `${base}.${bp}.order.json`) : undefined;
|
|
97
|
+
if (bpPath && existsSync(bpPath))
|
|
98
|
+
return bpPath;
|
|
99
|
+
const globalPath = join(constraintsRoot, `${base}.order.json`);
|
|
100
|
+
return existsSync(globalPath) ? globalPath : undefined;
|
|
101
|
+
};
|
|
78
102
|
// 5. Order files (monotonic constraints)
|
|
79
103
|
const axes = ['typography', 'spacing', 'layout'];
|
|
80
104
|
for (const axis of axes) {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
if (existsSync(orderPath)) {
|
|
105
|
+
const orderPath = orderPathFor(axis);
|
|
106
|
+
if (orderPath) {
|
|
84
107
|
try {
|
|
85
108
|
const data = JSON.parse(readFileSync(orderPath, 'utf8'));
|
|
86
109
|
const orders = data.order || [];
|
|
@@ -93,10 +116,9 @@ export function discoverConstraints(opts) {
|
|
|
93
116
|
}
|
|
94
117
|
}
|
|
95
118
|
}
|
|
96
|
-
// 6. Color lightness order files
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
if (existsSync(colorOrderPath)) {
|
|
119
|
+
// 6. Color lightness order files (same bp → global fallback)
|
|
120
|
+
const colorOrderPath = orderPathFor('color');
|
|
121
|
+
if (colorOrderPath) {
|
|
100
122
|
try {
|
|
101
123
|
const data = JSON.parse(readFileSync(colorOrderPath, 'utf8'));
|
|
102
124
|
const orders = data.order || [];
|
|
@@ -109,13 +131,13 @@ export function discoverConstraints(opts) {
|
|
|
109
131
|
}
|
|
110
132
|
}
|
|
111
133
|
// 7. Cross-axis rules (global)
|
|
112
|
-
const crossAxisPath = join(
|
|
134
|
+
const crossAxisPath = join(constraintsRoot, 'cross-axis.rules.json');
|
|
113
135
|
if (existsSync(crossAxisPath)) {
|
|
114
136
|
sources.push({ type: 'cross-axis-file', path: crossAxisPath });
|
|
115
137
|
}
|
|
116
138
|
// 8. Cross-axis rules (breakpoint-specific)
|
|
117
139
|
if (bp) {
|
|
118
|
-
const crossAxisBpPath = join(
|
|
140
|
+
const crossAxisBpPath = join(constraintsRoot, `cross-axis.${bp}.rules.json`);
|
|
119
141
|
if (existsSync(crossAxisBpPath)) {
|
|
120
142
|
sources.push({ type: 'cross-axis-file', path: crossAxisBpPath, bp });
|
|
121
143
|
}
|
|
@@ -170,13 +192,17 @@ export function attachConstraints(engine, sources, opts) {
|
|
|
170
192
|
break;
|
|
171
193
|
}
|
|
172
194
|
case 'cross-axis-file': {
|
|
173
|
-
// Phase 3B: Load rules from filesystem in CLI layer, pass to core plugin
|
|
174
|
-
|
|
195
|
+
// Phase 3B: Load rules from filesystem in CLI layer, pass to core plugin.
|
|
196
|
+
// Detailed load also surfaces notices (unusable file / skipped invalid
|
|
197
|
+
// rules) as warnings so they are never silently dropped (TASK-037).
|
|
198
|
+
const { rules, notices } = loadCrossAxisRulesDetailed(source.path, {
|
|
175
199
|
bp: source.bp,
|
|
176
200
|
knownIds,
|
|
177
201
|
debug: crossAxisDebug,
|
|
178
202
|
});
|
|
179
203
|
engine.use(CrossAxisPlugin(rules, source.bp));
|
|
204
|
+
if (notices.length)
|
|
205
|
+
engine.use(noticePlugin(notices));
|
|
180
206
|
break;
|
|
181
207
|
}
|
|
182
208
|
}
|
|
@@ -249,9 +275,21 @@ export function collectReferencedIds(sources) {
|
|
|
249
275
|
case 'lightness-file':
|
|
250
276
|
addOrders(source.orders);
|
|
251
277
|
break;
|
|
252
|
-
case 'cross-axis-file':
|
|
253
|
-
|
|
278
|
+
case 'cross-axis-file': {
|
|
279
|
+
// TASK-031/037: enumerate referenced ids so coverage stays KNOWN, but
|
|
280
|
+
// MIRROR attach exactly — same `source.bp` filter and same shape
|
|
281
|
+
// validation. A rule that did not run (wrong breakpoint, or invalid)
|
|
282
|
+
// must not make coverage look "matched" and suppress the no-match note.
|
|
283
|
+
// An unusable file stays conservative (coverageKnown=false).
|
|
284
|
+
const { ids: caIds, coverageKnown: known } = referencedIdsForFile(source.path, source.bp);
|
|
285
|
+
if (!known) {
|
|
286
|
+
coverageKnown = false;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
for (const id of caIds)
|
|
290
|
+
ids.add(id);
|
|
254
291
|
break;
|
|
292
|
+
}
|
|
255
293
|
}
|
|
256
294
|
}
|
|
257
295
|
return { ids, coverageKnown };
|