design-constraint-validator 1.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +229 -659
- package/adapters/README.md +46 -46
- package/adapters/css.ts +116 -116
- 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/adapters/js.ts +14 -14
- package/adapters/json.ts +45 -45
- package/cli/build-css.ts +32 -32
- package/cli/commands/build.ts +65 -65
- package/cli/commands/graph.d.ts.map +1 -1
- package/cli/commands/graph.js +26 -10
- package/cli/commands/graph.ts +180 -137
- package/cli/commands/index.ts +7 -7
- package/cli/commands/patch-apply.ts +80 -80
- package/cli/commands/patch.ts +22 -22
- package/cli/commands/set.d.ts.map +1 -1
- package/cli/commands/set.js +12 -4
- package/cli/commands/set.ts +239 -225
- package/cli/commands/utils.ts +50 -50
- package/cli/commands/validate.d.ts.map +1 -1
- package/cli/commands/validate.js +89 -33
- package/cli/commands/validate.ts +180 -115
- package/cli/commands/why.d.ts.map +1 -1
- package/cli/commands/why.js +86 -20
- package/cli/commands/why.ts +158 -46
- package/cli/config-schema.ts +27 -27
- package/cli/config.ts +35 -35
- package/cli/constraint-registry.d.ts +101 -0
- package/cli/constraint-registry.d.ts.map +1 -0
- package/cli/constraint-registry.js +225 -0
- package/cli/constraint-registry.ts +304 -0
- package/cli/constraints-loader.d.ts.map +1 -0
- package/cli/cross-axis-loader.d.ts +91 -0
- package/cli/cross-axis-loader.d.ts.map +1 -0
- package/cli/cross-axis-loader.js +222 -0
- package/cli/cross-axis-loader.ts +289 -0
- package/cli/dcv.js +4 -0
- package/cli/dcv.ts +111 -107
- package/cli/engine-helpers.d.ts.map +1 -1
- package/cli/graph-poset.ts +74 -74
- package/cli/json-output.d.ts +69 -0
- package/cli/json-output.d.ts.map +1 -0
- package/cli/json-output.js +109 -0
- package/cli/json-output.ts +184 -0
- package/cli/result.ts +27 -27
- package/cli/run.ts +54 -54
- package/cli/smoke-test.ts +40 -40
- package/cli/types.d.ts +6 -0
- package/cli/types.d.ts.map +1 -1
- package/cli/types.ts +84 -78
- 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.ts +50 -50
- package/core/cli-format.ts +31 -31
- package/core/color.ts +148 -148
- package/core/constraints/cross-axis.ts +114 -114
- package/core/constraints/monotonic-lightness.ts +38 -38
- package/core/constraints/monotonic.ts +74 -74
- package/core/constraints/threshold.ts +43 -43
- package/core/constraints/wcag.ts +70 -70
- package/core/cross-axis-config.d.ts.map +1 -1
- package/core/engine.d.ts +95 -0
- package/core/engine.d.ts.map +1 -1
- package/core/engine.js +22 -0
- package/core/engine.ts +167 -65
- package/core/flatten.ts +116 -116
- package/core/image-export.ts +48 -48
- package/core/index.d.ts +9 -30
- package/core/index.d.ts.map +1 -1
- package/core/index.js +7 -54
- package/core/index.ts +10 -72
- package/core/patch.ts +134 -134
- package/core/poset.ts +311 -311
- package/core/why.ts +63 -63
- package/package.json +96 -90
- package/themes/color.lg.order.json +15 -15
- package/themes/color.md.order.json +15 -15
- package/themes/color.order.json +15 -15
- package/themes/color.sm.order.json +15 -15
- package/themes/cross-axis.rules.json +35 -35
- package/themes/cross-axis.sm.rules.json +12 -12
- package/themes/layout.lg.order.json +18 -18
- package/themes/layout.md.order.json +18 -18
- package/themes/layout.order.json +18 -18
- package/themes/layout.sm.order.json +18 -18
- package/themes/spacing.order.json +14 -14
- package/themes/typography.lg.order.json +15 -15
- package/themes/typography.md.order.json +15 -15
- package/themes/typography.order.json +15 -15
- package/themes/typography.sm.order.json +15 -15
- package/cli/engine-helpers.d.ts +0 -8
- package/cli/engine-helpers.js +0 -70
- package/cli/engine-helpers.ts +0 -61
- package/core/cross-axis-config.d.ts +0 -5
- package/core/cross-axis-config.js +0 -144
- package/core/cross-axis-config.ts +0 -152
- package/dist/test-overrides-removal.json +0 -4
- package/dist/tmp.patch.json +0 -35
- package/tokens/overrides/base.json +0 -22
- package/tokens/overrides/lg.json +0 -20
- package/tokens/overrides/md.json +0 -16
- package/tokens/overrides/sm.json +0 -16
- package/tokens/overrides/viol.color.json +0 -6
- package/tokens/overrides/viol.typography.json +0 -6
- package/tokens/tokens.demo-violations.json +0 -116
- package/tokens/tokens.example.json +0 -128
- package/tokens/tokens.json +0 -67
- package/tokens/tokens.multi-violations.json +0 -21
- package/tokens/tokens.schema.d.ts +0 -2298
- package/tokens/tokens.schema.d.ts.map +0 -1
- package/tokens/tokens.schema.js +0 -148
- package/tokens/tokens.schema.ts +0 -196
- package/tokens/tokens.test.json +0 -38
- package/tokens/tokens.touch-violation.json +0 -8
- package/tokens/typography.classes.css +0 -11
- package/tokens/typography.css +0 -20
package/README.md
CHANGED
|
@@ -1,659 +1,229 @@
|
|
|
1
|
-
# Design Constraint Validator (DCV)
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[![
|
|
6
|
-
[![
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- ✅ **
|
|
14
|
-
- ✅ **
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
**
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
**
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
**3. Create `themes/wcag.json`** (WCAG contrast constraint):
|
|
231
|
-
```json
|
|
232
|
-
{
|
|
233
|
-
"constraints": {
|
|
234
|
-
"wcag": [{
|
|
235
|
-
"foreground": "color.text",
|
|
236
|
-
"background": "color.background",
|
|
237
|
-
"ratio": 4.5
|
|
238
|
-
}]
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
**4. Create `themes/typography.order.json`** (size hierarchy):
|
|
244
|
-
```json
|
|
245
|
-
{
|
|
246
|
-
"order": [
|
|
247
|
-
["typography.size.h1", ">=", "typography.size.h2"],
|
|
248
|
-
["typography.size.h2", ">=", "typography.size.body"]
|
|
249
|
-
]
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
**5. Validate**
|
|
254
|
-
```bash
|
|
255
|
-
npx dcv validate
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**Output:**
|
|
259
|
-
```
|
|
260
|
-
✅ validate: 0 error(s), 0 warning(s)
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
Success! Your tokens pass all constraints.
|
|
264
|
-
|
|
265
|
-
### What if validation fails?
|
|
266
|
-
|
|
267
|
-
Try changing `h2` to `"40px"` (larger than h1) and run validation again:
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
npx dcv validate
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**Output:**
|
|
274
|
-
```
|
|
275
|
-
validate: 1 error(s), 0 warning(s)
|
|
276
|
-
ERROR monotonic typography.size.h2 @ typography.order.json — typography.size.h1 >= typography.size.h2 violated: 32px < 40px
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
The validator explains exactly what failed and why.
|
|
280
|
-
|
|
281
|
-
### Minimal Working Example
|
|
282
|
-
|
|
283
|
-
See [examples/minimal/](examples/minimal/) for a complete minimal setup you can copy.
|
|
284
|
-
|
|
285
|
-
## Example Output
|
|
286
|
-
|
|
287
|
-
### ✅ Successful Validation
|
|
288
|
-
```bash
|
|
289
|
-
$ npx dcv validate
|
|
290
|
-
✅ validate: 0 error(s), 0 warning(s)
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### ❌ Failed Validation
|
|
294
|
-
```bash
|
|
295
|
-
$ npx dcv validate
|
|
296
|
-
validate: 2 error(s), 1 warning(s)
|
|
297
|
-
|
|
298
|
-
ERROR monotonic typography.size.h2
|
|
299
|
-
typography.size.h1 >= typography.size.h2 violated: 32px < 40px
|
|
300
|
-
Defined in: themes/typography.order.json
|
|
301
|
-
|
|
302
|
-
ERROR wcag color.text vs color.background
|
|
303
|
-
Contrast ratio 4.5:1 required, got 2.1:1
|
|
304
|
-
Defined in: themes/wcag.json
|
|
305
|
-
|
|
306
|
-
WARN threshold control.size.min
|
|
307
|
-
Touch target should be >= 44px, got 30px
|
|
308
|
-
Defined in: themes/touch.json
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
## Constraint Types
|
|
312
|
-
|
|
313
|
-
### 1. Monotonic Constraints
|
|
314
|
-
Enforce ordering relationships (e.g., h1 ≥ h2 ≥ h3)
|
|
315
|
-
|
|
316
|
-
```json
|
|
317
|
-
{
|
|
318
|
-
"order": [
|
|
319
|
-
["typography.size.h1", ">=", "typography.size.h2"],
|
|
320
|
-
["typography.size.h2", ">=", "typography.size.h3"]
|
|
321
|
-
]
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### 2. WCAG Contrast
|
|
326
|
-
Validate color accessibility
|
|
327
|
-
|
|
328
|
-
```json
|
|
329
|
-
{
|
|
330
|
-
"constraints": {
|
|
331
|
-
"wcag": [
|
|
332
|
-
{
|
|
333
|
-
"foreground": "color.role.text.default",
|
|
334
|
-
"background": "color.role.bg.surface",
|
|
335
|
-
"ratio": 4.5
|
|
336
|
-
}
|
|
337
|
-
]
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### 3. Threshold Rules
|
|
343
|
-
Size guardrails (e.g., ≥44px touch targets)
|
|
344
|
-
|
|
345
|
-
```typescript
|
|
346
|
-
{
|
|
347
|
-
id: 'control.size.min',
|
|
348
|
-
op: '>=',
|
|
349
|
-
valuePx: 44,
|
|
350
|
-
where: 'Touch target (WCAG / Apple HIG)'
|
|
351
|
-
}
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### 4. Lightness Ordering
|
|
355
|
-
Color palette progression
|
|
356
|
-
|
|
357
|
-
```json
|
|
358
|
-
{
|
|
359
|
-
"order": [
|
|
360
|
-
["color.palette.brand.100", ">=", "color.palette.brand.200"],
|
|
361
|
-
["color.palette.brand.200", ">=", "color.palette.brand.300"]
|
|
362
|
-
]
|
|
363
|
-
}
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### 5. Cross-Axis Constraints
|
|
367
|
-
Multi-domain relationships
|
|
368
|
-
|
|
369
|
-
```json
|
|
370
|
-
{
|
|
371
|
-
"when": { "id": "typography.weight.body", "op": "<=", "value": 400 },
|
|
372
|
-
"require": { "id": "typography.size.body", "op": ">=", "fallback": "16px" }
|
|
373
|
-
}
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
## CLI Commands
|
|
377
|
-
|
|
378
|
-
### Validate
|
|
379
|
-
|
|
380
|
-
```bash
|
|
381
|
-
# Validate all tokens
|
|
382
|
-
dcv validate
|
|
383
|
-
|
|
384
|
-
# Validate specific breakpoint
|
|
385
|
-
dcv validate --breakpoint md
|
|
386
|
-
|
|
387
|
-
# All breakpoints with summary
|
|
388
|
-
dcv validate --all-breakpoints --summary table
|
|
389
|
-
|
|
390
|
-
# Fail on warnings
|
|
391
|
-
dcv validate --fail-on warn
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
### Graph Visualization
|
|
395
|
-
|
|
396
|
-
Export token dependency graphs in text formats (Mermaid, Graphviz DOT):
|
|
397
|
-
|
|
398
|
-
```bash
|
|
399
|
-
# Export Mermaid format (renders on GitHub)
|
|
400
|
-
dcv graph --hasse typography --format mermaid > typography.mmd
|
|
401
|
-
|
|
402
|
-
# Export Graphviz DOT format
|
|
403
|
-
dcv graph --hasse color --format dot > color.dot
|
|
404
|
-
|
|
405
|
-
# JSON format for programmatic use
|
|
406
|
-
dcv graph --hasse layout --format json > layout.json
|
|
407
|
-
|
|
408
|
-
# Show only violations
|
|
409
|
-
dcv graph --hasse color --only-violations --format mermaid
|
|
410
|
-
|
|
411
|
-
# Highlight violations
|
|
412
|
-
dcv graph --hasse layout --highlight-violations --format mermaid
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
**Rendering Options:**
|
|
416
|
-
1. **GitHub** - Paste Mermaid code into `.md` files (native support)
|
|
417
|
-
2. **mermaid.live** - Online Mermaid editor and renderer
|
|
418
|
-
3. **VS Code** - Use Mermaid Preview extension
|
|
419
|
-
4. **Graphviz** - Render DOT files: `dot -Tpng color.dot -o color.png`
|
|
420
|
-
|
|
421
|
-
**For PNG/SVG generation** (optional):
|
|
422
|
-
```bash
|
|
423
|
-
# Install Mermaid CLI globally
|
|
424
|
-
npm install -g @mermaid-js/mermaid-cli
|
|
425
|
-
|
|
426
|
-
# Generate image
|
|
427
|
-
mmdc -i typography.mmd -o typography.png
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### Provenance Analysis
|
|
431
|
-
|
|
432
|
-
```bash
|
|
433
|
-
# Why does this token have this value?
|
|
434
|
-
dcv why typography.size.h1
|
|
435
|
-
|
|
436
|
-
# JSON output
|
|
437
|
-
dcv why color.role.text.default --format json
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
### Build Tokens
|
|
441
|
-
|
|
442
|
-
```bash
|
|
443
|
-
# Build tokens
|
|
444
|
-
dcv build
|
|
445
|
-
|
|
446
|
-
# Build all formats
|
|
447
|
-
dcv build --all-formats
|
|
448
|
-
|
|
449
|
-
# Watch mode
|
|
450
|
-
dcv build --watch
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
### Set Token Values
|
|
454
|
-
|
|
455
|
-
```bash
|
|
456
|
-
# Set a single token
|
|
457
|
-
dcv set typography.size.h1=32px
|
|
458
|
-
|
|
459
|
-
# Set color with OKLCH
|
|
460
|
-
dcv set color.palette.brand.500=oklch(0.65 0.15 280)
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
## Use Cases
|
|
464
|
-
|
|
465
|
-
✅ **Design System Validation** - Catch inconsistencies in CI/CD
|
|
466
|
-
✅ **Accessibility Compliance** - Ensure WCAG 2.1 AA/AAA
|
|
467
|
-
✅ **Multi-Breakpoint** - Validate responsive token overrides
|
|
468
|
-
✅ **Dependency Analysis** - Visualize token relationships
|
|
469
|
-
✅ **Token Debugging** - Understand where values come from
|
|
470
|
-
|
|
471
|
-
## Example
|
|
472
|
-
|
|
473
|
-
**tokens.json:**
|
|
474
|
-
```json
|
|
475
|
-
{
|
|
476
|
-
"typography": {
|
|
477
|
-
"size": {
|
|
478
|
-
"h1": "32px",
|
|
479
|
-
"h2": "24px",
|
|
480
|
-
"body": "16px"
|
|
481
|
-
}
|
|
482
|
-
},
|
|
483
|
-
"color": {
|
|
484
|
-
"role": {
|
|
485
|
-
"text": { "default": "#1a1a1a" },
|
|
486
|
-
"bg": { "surface": "#ffffff" }
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
**themes/typography.order.json:**
|
|
493
|
-
```json
|
|
494
|
-
{
|
|
495
|
-
"order": [
|
|
496
|
-
["typography.size.h1", ">=", "typography.size.h2"],
|
|
497
|
-
["typography.size.h2", ">=", "typography.size.body"]
|
|
498
|
-
]
|
|
499
|
-
}
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
**Validate:**
|
|
503
|
-
```bash
|
|
504
|
-
$ npx dcv validate
|
|
505
|
-
|
|
506
|
-
✅ validate [bp=base]: 0 error(s), 0 warning(s)
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
## Architecture
|
|
510
|
-
|
|
511
|
-
```
|
|
512
|
-
┌─────────────────────────────────────┐
|
|
513
|
-
│ Token Dependency Graph (DAG) │
|
|
514
|
-
│ Tracks references & dependencies │
|
|
515
|
-
└─────────────────────────────────────┘
|
|
516
|
-
↓
|
|
517
|
-
┌─────────────────────────────────────┐
|
|
518
|
-
│ Constraint Validation Engine │
|
|
519
|
-
│ ┌──────────────────────────────┐ │
|
|
520
|
-
│ │ Plugin-based architecture │ │
|
|
521
|
-
│ │ - Monotonic │ │
|
|
522
|
-
│ │ - WCAG Contrast │ │
|
|
523
|
-
│ │ - Threshold │ │
|
|
524
|
-
│ │ - Lightness │ │
|
|
525
|
-
│ │ - Cross-Axis │ │
|
|
526
|
-
│ └──────────────────────────────┘ │
|
|
527
|
-
└─────────────────────────────────────┘
|
|
528
|
-
↓
|
|
529
|
-
┌─────────────────────────────────────┐
|
|
530
|
-
│ Violation Reporting │
|
|
531
|
-
│ - Descriptive error messages │
|
|
532
|
-
│ - Provenance tracing │
|
|
533
|
-
│ - Graph visualization │
|
|
534
|
-
└─────────────────────────────────────┘
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
## Documentation
|
|
538
|
-
|
|
539
|
-
- **[Getting Started](docs/Getting-Started.md)** - 5-minute quick start
|
|
540
|
-
- **[Constraint Types](docs/Constraints.md)** - All constraint types
|
|
541
|
-
- **[CLI Reference](docs/CLI.md)** - Complete command documentation
|
|
542
|
-
- **[Configuration](docs/Configuration.md)** - Config file options
|
|
543
|
-
- **[Architecture](docs/Architecture.md)** - How DCV works
|
|
544
|
-
- **[API Reference](docs/API.md)** - Programmatic usage
|
|
545
|
-
|
|
546
|
-
---
|
|
547
|
-
|
|
548
|
-
## Roadmap
|
|
549
|
-
|
|
550
|
-
* Plugin API for **custom constraints**
|
|
551
|
-
* **VS Code** diagnostics (inline explain)
|
|
552
|
-
* **Cross-axis packs** (typography × weight × contrast)
|
|
553
|
-
* **Receipts & provenance** (hashes, signable reports)
|
|
554
|
-
* UI graph explorer (node inspector, violations focus)
|
|
555
|
-
|
|
556
|
-
---
|
|
557
|
-
|
|
558
|
-
## Philosophy
|
|
559
|
-
|
|
560
|
-
> **Constraints, not conventions.**
|
|
561
|
-
|
|
562
|
-
Design systems need more than naming conventions - they need mathematical guarantees. This validator:
|
|
563
|
-
|
|
564
|
-
1. **Enforces relationships** - Typography hierarchies, color progressions
|
|
565
|
-
2. **Validates accessibility** - WCAG contrast with alpha compositing
|
|
566
|
-
3. **Explains violations** - Provenance tracing shows why rules fail
|
|
567
|
-
4. **Scales with complexity** - Incremental validation of 1000s of tokens
|
|
568
|
-
|
|
569
|
-
## Related Projects
|
|
570
|
-
|
|
571
|
-
This is the **core validation engine**. For a complete decision-driven design system with a 5-axis framework (Tone, Emphasis, Size, Density, Shape) and theme configurator UI, see **DecisionThemes** (coming soon).
|
|
572
|
-
|
|
573
|
-
## FAQ
|
|
574
|
-
|
|
575
|
-
### How does the tool find my tokens and constraints?
|
|
576
|
-
|
|
577
|
-
By default, it looks for:
|
|
578
|
-
- **Tokens**: `tokens.json` or `tokens/*.json`
|
|
579
|
-
- **Constraints**: `themes/*.json` or `themes/**/*.json`
|
|
580
|
-
|
|
581
|
-
You can customize paths in a `dcv.config.json` file. See [CONFIGURATION.md](CONFIGURATION.md) for details.
|
|
582
|
-
|
|
583
|
-
### What's the relationship with DecisionThemes?
|
|
584
|
-
|
|
585
|
-
`design-constraint-validator` is the **core validation engine** - it validates any design tokens against constraints.
|
|
586
|
-
|
|
587
|
-
**DecisionThemes** (coming soon) is a complete design system framework that uses this validator under the hood, plus adds:
|
|
588
|
-
- 5-axis decision framework (Tone, Emphasis, Size, Density, Shape)
|
|
589
|
-
- Theme configurator UI
|
|
590
|
-
- Decision → Token mapping
|
|
591
|
-
|
|
592
|
-
Think of it as: **design-token-validator** = engine, **DecisionThemes** = full product built on the engine.
|
|
593
|
-
|
|
594
|
-
### Can I use this with my existing tokens?
|
|
595
|
-
|
|
596
|
-
Yes! As long as your tokens follow a structured JSON format. The tool supports:
|
|
597
|
-
- [W3C Design Tokens Community Group](https://design-tokens.github.io/community-group/) format
|
|
598
|
-
- Custom nested JSON structures
|
|
599
|
-
- Token references with `{token.path}` syntax
|
|
600
|
-
|
|
601
|
-
### How do I use incremental validation?
|
|
602
|
-
|
|
603
|
-
Incremental validation automatically detects changed tokens and only validates those tokens plus their dependents. This feature is built-in - no configuration needed. When you run `dcv validate`, it will use cached results for unchanged tokens.
|
|
604
|
-
|
|
605
|
-
### What breakpoints are supported?
|
|
606
|
-
|
|
607
|
-
The tool supports responsive tokens with breakpoint-specific overrides. Place override files in `tokens/overrides/`:
|
|
608
|
-
- `tokens/overrides/sm.json` - Small screens
|
|
609
|
-
- `tokens/overrides/md.json` - Medium screens
|
|
610
|
-
- `tokens/overrides/lg.json` - Large screens
|
|
611
|
-
|
|
612
|
-
Validate specific breakpoints with `--breakpoint md` or all breakpoints with `--all-breakpoints`.
|
|
613
|
-
|
|
614
|
-
### Can I use this in CI/CD?
|
|
615
|
-
|
|
616
|
-
Absolutely! That's a primary use case:
|
|
617
|
-
|
|
618
|
-
```yaml
|
|
619
|
-
# .github/workflows/validate-tokens.yml
|
|
620
|
-
name: Validate Design Tokens
|
|
621
|
-
on: [push, pull_request]
|
|
622
|
-
jobs:
|
|
623
|
-
validate:
|
|
624
|
-
runs-on: ubuntu-latest
|
|
625
|
-
steps:
|
|
626
|
-
- uses: actions/checkout@v4
|
|
627
|
-
- uses: actions/setup-node@v4
|
|
628
|
-
- run: npm ci
|
|
629
|
-
- run: npx dcv validate --fail-on warn
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
The tool exits with non-zero code on validation failures, making it perfect for CI/CD gates.
|
|
633
|
-
|
|
634
|
-
### How do I visualize my token dependencies?
|
|
635
|
-
|
|
636
|
-
Use the `graph` command:
|
|
637
|
-
|
|
638
|
-
```bash
|
|
639
|
-
# Generate Mermaid diagram (renders on GitHub)
|
|
640
|
-
dcv graph --hasse typography --format mermaid > typography.mmd
|
|
641
|
-
|
|
642
|
-
# Generate Graphviz DOT
|
|
643
|
-
dcv graph --hasse color --format dot > color.dot
|
|
644
|
-
|
|
645
|
-
# Then render with Graphviz
|
|
646
|
-
dot -Tpng color.dot -o color.png
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
### What Node.js version do I need?
|
|
650
|
-
|
|
651
|
-
Node.js 18 or higher is required.
|
|
652
|
-
|
|
653
|
-
## Contributing
|
|
654
|
-
|
|
655
|
-
Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
656
|
-
|
|
657
|
-
## License
|
|
658
|
-
|
|
659
|
-
MIT © Cseperke Papp
|
|
1
|
+
# Design Constraint Validator (DCV)
|
|
2
|
+
|
|
3
|
+
> Mathematical constraint validator for design systems — ensuring consistency, accessibility, and logical coherence.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/design-constraint-validator)
|
|
6
|
+
[](https://www.npmjs.com/package/design-constraint-validator)
|
|
7
|
+
[](https://github.com/CseperkePapp/design-constraint-validator/actions/workflows/ci.yml)
|
|
8
|
+
[](https://github.com/CseperkePapp/design-constraint-validator/actions/workflows/sbom.yml)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](#)
|
|
11
|
+
|
|
12
|
+
**Design Constraint Validator (DCV)** validates design constraints across token sets and styles:
|
|
13
|
+
- ✅ **Accessibility:** WCAG text contrast, perceptual lightness floor/ceilings
|
|
14
|
+
- ✅ **Order & Monotonicity:** increasing typography scales, spacing hierarchies
|
|
15
|
+
- ✅ **Thresholds & Policies:** min/max ranges, cross-axis guards (size × weight × contrast)
|
|
16
|
+
- ✅ **Graph Intelligence:** Hasse/poset graph export; "why" explanations with implicated edges
|
|
17
|
+
|
|
18
|
+
This is **not** a schema linter; it's a **reasoning validator** for values and relationships.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Local (recommended)
|
|
26
|
+
npm i -D design-constraint-validator
|
|
27
|
+
|
|
28
|
+
# One-off run
|
|
29
|
+
npx dcv --help
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Requirements:** Node.js ≥ 18.x (ESM)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Validate tokens with default constraints
|
|
40
|
+
npx dcv validate ./tokens/tokens.json
|
|
41
|
+
|
|
42
|
+
# Explain failures
|
|
43
|
+
npx dcv why --format table
|
|
44
|
+
|
|
45
|
+
# Export dependency graph
|
|
46
|
+
npx dcv graph --format mermaid > graph.mmd
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Example Output:**
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Constraint Status Details
|
|
53
|
+
──────────────────────────── ────── ─────────────────────────────────────────────
|
|
54
|
+
WCAG Contrast ≥ 4.5:1 FAIL text.primary(#5A5A5A) on bg.body(#F5F5F5) ⇒ 3.8
|
|
55
|
+
Typography monotonic scale FAIL h3(22) < body(18) < h2(21) < h1(34) ✖ out-of-order: h2<h3
|
|
56
|
+
Cross-axis (weight vs size) PASS all headings satisfy min weight for size bucket
|
|
57
|
+
Exit code: 1 (violations found)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Programmatic API
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { validate } from 'design-constraint-validator';
|
|
66
|
+
|
|
67
|
+
const result = await validate({
|
|
68
|
+
tokensPath: './tokens/tokens.json',
|
|
69
|
+
policyPath: './themes/policies/aa.json'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!result.ok) {
|
|
73
|
+
for (const v of result.violations) {
|
|
74
|
+
console.log(`[${v.kind}] ${v.message}`, v.context);
|
|
75
|
+
}
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
See **[API Reference](docs/API.md)** for complete programmatic usage.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Documentation
|
|
85
|
+
|
|
86
|
+
### For Everyone
|
|
87
|
+
- **[Getting Started](docs/Getting-Started.md)** - 5-minute tutorial
|
|
88
|
+
- **[Features & Complete Guide](docs/Features.md)** - All features, examples, and FAQ
|
|
89
|
+
- **[Examples](docs/Examples.md)** - Sample projects and use cases
|
|
90
|
+
|
|
91
|
+
### For Users
|
|
92
|
+
- **[Constraints](docs/Constraints.md)** - All 5 constraint types in detail
|
|
93
|
+
- **[CLI Reference](docs/CLI.md)** - Complete command documentation
|
|
94
|
+
- **[Configuration](docs/Configuration.md)** - Config file options
|
|
95
|
+
- **[Concepts](docs/Concepts.md)** - Core terminology and defaults
|
|
96
|
+
|
|
97
|
+
### For Developers
|
|
98
|
+
- **[API Reference](docs/API.md)** - Programmatic usage
|
|
99
|
+
- **[Architecture](docs/Architecture.md)** - Internal design
|
|
100
|
+
- **[Adapters](docs/Adapters.md)** - Input/output formats
|
|
101
|
+
|
|
102
|
+
### Additional Resources
|
|
103
|
+
- **[Prior Art / Method](docs/prior-art/)** - Design rationale (Decision Themes, receipts)
|
|
104
|
+
- **[AI Guide](docs/AI-GUIDE.md)** - Using DCV with ChatGPT/Claude/Copilot
|
|
105
|
+
- **[Contributing](CONTRIBUTING.md)** - Contribution guidelines
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Why Constraints, Not Conventions?
|
|
110
|
+
|
|
111
|
+
Conventional linters catch **schema** issues ("has a value, has a type").
|
|
112
|
+
**DCV** enforces **relationships** that matter to users and brand integrity:
|
|
113
|
+
|
|
114
|
+
- Legible contrast under all themes and states
|
|
115
|
+
- Proper hierarchical spacing/typography (monotonic scales)
|
|
116
|
+
- Coherent cross-axis behavior (e.g., weight increases with size where needed)
|
|
117
|
+
- Policy conformance (AA/AAA, internal thresholds)
|
|
118
|
+
|
|
119
|
+
This transforms tokens from "bags of numbers" into a **formal design system**.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Comparison: Schema Linters vs DCV
|
|
124
|
+
|
|
125
|
+
| Feature | Schema Linters | DCV |
|
|
126
|
+
|---------|----------------|-----|
|
|
127
|
+
| **Validates** | JSON structure, types | Mathematical relationships, accessibility |
|
|
128
|
+
| **Catches** | Missing fields, wrong types | Contrast violations, hierarchy breaks |
|
|
129
|
+
| **Purpose** | Format compliance | Design system integrity |
|
|
130
|
+
| **Examples** | DTCG schema validator | WCAG checks, monotonic scales |
|
|
131
|
+
|
|
132
|
+
> DCV is not affiliated with Anima's `design-tokens-validator` (schema-focused).
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Input Formats
|
|
137
|
+
|
|
138
|
+
DCV accepts **token JSON** (flat or nested) and optional **policy JSON**.
|
|
139
|
+
Adapters normalize common ecosystems:
|
|
140
|
+
|
|
141
|
+
- **Style Dictionary** - See [examples/style-dictionary/](examples/style-dictionary/)
|
|
142
|
+
- **Tokens Studio JSON** - See [examples/tokens-studio/](examples/tokens-studio/)
|
|
143
|
+
- **DTCG** (Design Tokens Community Group) - See [examples/dtcg/](examples/dtcg/)
|
|
144
|
+
|
|
145
|
+
Full adapter documentation: **[Adapters](docs/Adapters.md)**
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## DCV & DecisionThemes
|
|
150
|
+
|
|
151
|
+
DCV is the **standalone validation engine** — use it for any token system.
|
|
152
|
+
|
|
153
|
+
**DecisionThemes** (coming 2026) is a complete design system framework built on DCV:
|
|
154
|
+
- **5-axis decision model** (Tone, Emphasis, Size, Density, Shape)
|
|
155
|
+
- **VT/DT pipeline** (Value Themes + Decision Themes → deterministic CSS configs)
|
|
156
|
+
- **Studio UI** + **Hub marketplace** for sharing Decision Systems
|
|
157
|
+
|
|
158
|
+
DCV powers DecisionThemes' validation layer — but works perfectly standalone.
|
|
159
|
+
Preview: [www.decisionthemes.com](https://www.decisionthemes.com)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Method & Prior Art
|
|
164
|
+
|
|
165
|
+
The Design Constraint Validator engine is based on a theming and validation method published as **defensive prior art**.
|
|
166
|
+
|
|
167
|
+
To understand the underlying architecture (Decision Themes / Value Themes, deterministic compute, post-compute validation and receipts):
|
|
168
|
+
|
|
169
|
+
- [Decision Themes Method](docs/prior-art/Decision-Themes-Deterministic-Compute-and-Dual-Namespaces.md)
|
|
170
|
+
- [DCV Validation & Receipts](docs/prior-art/DCV-Post-Compute-Validation-and-Receipts.md)
|
|
171
|
+
|
|
172
|
+
These documents keep the method openly implementable and prevent patent lock-up.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Security & Supply Chain
|
|
177
|
+
|
|
178
|
+
### SBOM (Software Bill of Materials)
|
|
179
|
+
|
|
180
|
+
DCV generates CycloneDX-compliant SBOMs for supply chain transparency:
|
|
181
|
+
|
|
182
|
+
- **CI Builds:** SBOM artifacts on every CI run (90-day retention)
|
|
183
|
+
- **Releases:** SBOM files (JSON + XML) attached to GitHub releases
|
|
184
|
+
- **Manual:** Run `npx @cyclonedx/cyclonedx-npm` in project root
|
|
185
|
+
|
|
186
|
+
**Download:**
|
|
187
|
+
- [GitHub Actions Artifacts](https://github.com/CseperkePapp/design-constraint-validator/actions/workflows/sbom.yml)
|
|
188
|
+
- [Latest Release](https://github.com/CseperkePapp/design-constraint-validator/releases/latest)
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Roadmap
|
|
193
|
+
|
|
194
|
+
- Plugin API for **custom constraints**
|
|
195
|
+
- **VS Code** diagnostics (inline explain)
|
|
196
|
+
- **Cross-axis packs** (typography × weight × contrast)
|
|
197
|
+
- **Receipts & provenance** (hashes, signable reports)
|
|
198
|
+
- UI graph explorer (node inspector, violations focus)
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Philosophy
|
|
203
|
+
|
|
204
|
+
> **Constraints, not conventions.**
|
|
205
|
+
|
|
206
|
+
Design systems need mathematical guarantees. This validator:
|
|
207
|
+
|
|
208
|
+
1. **Enforces relationships** - Typography hierarchies, color progressions
|
|
209
|
+
2. **Validates accessibility** - WCAG contrast with alpha compositing
|
|
210
|
+
3. **Explains violations** - Provenance tracing shows why rules fail
|
|
211
|
+
4. **Scales with complexity** - Incremental validation of 1000s of tokens
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Related Projects
|
|
216
|
+
|
|
217
|
+
This is the **core validation engine**. For a complete decision-driven design system with a 5-axis framework (Tone, Emphasis, Size, Density, Shape) and theme configurator UI, see **DecisionThemes** (coming soon).
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Contributing
|
|
222
|
+
|
|
223
|
+
Contributions welcome! See **[CONTRIBUTING.md](CONTRIBUTING.md)**
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
[MIT](LICENSE) © Cseperke Papp
|