design-constraint-validator 1.1.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/README.md +14 -0
- 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/graph.js +2 -2
- package/cli/commands/graph.ts +2 -2
- package/cli/commands/validate.d.ts.map +1 -1
- package/cli/commands/validate.js +3 -0
- package/cli/commands/validate.ts +4 -0
- package/cli/json-output.d.ts +5 -0
- package/cli/json-output.d.ts.map +1 -1
- package/cli/json-output.js +2 -0
- package/cli/json-output.ts +7 -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/package.json +1 -1
- package/cli/constraints-loader.d.ts +0 -30
- 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.js +0 -135
- package/cli/engine-helpers.ts +0 -133
- package/core/cross-axis-config.d.ts +0 -34
- package/core/cross-axis-config.js +0 -173
- package/core/cross-axis-config.ts +0 -182
package/README.md
CHANGED
|
@@ -146,6 +146,20 @@ Full adapter documentation: **[Adapters](docs/Adapters.md)**
|
|
|
146
146
|
|
|
147
147
|
---
|
|
148
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
|
+
|
|
149
163
|
## Method & Prior Art
|
|
150
164
|
|
|
151
165
|
The Design Constraint Validator engine is based on a theming and validation method published as **defensive prior art**.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DecisionThemes Adapter (Placeholder)
|
|
3
|
+
*
|
|
4
|
+
* This adapter will integrate with the DecisionThemes framework (coming 2026).
|
|
5
|
+
* It transforms VT (Value Themes) + DT (Decision Themes) into flat tokens for DCV validation.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.decisionthemes.com
|
|
8
|
+
* @see docs/Adapters.md for implementation details
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { decisionthemesAdapter } from './adapters/decisionthemes.js';
|
|
13
|
+
*
|
|
14
|
+
* const { tokens, policy } = decisionthemesAdapter({
|
|
15
|
+
* vt: { ... }, // Value Themes (raw values)
|
|
16
|
+
* dt: { ... } // Decision Themes (formulas)
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // tokens = flat token object for DCV validation
|
|
20
|
+
* // policy = auto-generated constraints from 5-axis model
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export interface VT {
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}
|
|
26
|
+
export interface DT {
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
}
|
|
29
|
+
export interface DecisionThemesInput {
|
|
30
|
+
vt: VT;
|
|
31
|
+
dt: DT;
|
|
32
|
+
}
|
|
33
|
+
export interface DecisionThemesOutput {
|
|
34
|
+
tokens: Record<string, any>;
|
|
35
|
+
policy?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Transform DecisionThemes (VT+DT) into DCV-compatible tokens
|
|
39
|
+
*
|
|
40
|
+
* @param input - VT (values) + DT (decisions)
|
|
41
|
+
* @returns Flat tokens + optional policy JSON
|
|
42
|
+
*/
|
|
43
|
+
export declare function decisionthemesAdapter(_input: DecisionThemesInput): DecisionThemesOutput;
|
|
44
|
+
//# sourceMappingURL=decisionthemes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decisionthemes.d.ts","sourceRoot":"","sources":["decisionthemes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,EAAE;IAEjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,EAAE;IAEjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,EAAE,CAAC;IACP,EAAE,EAAE,EAAE,CAAC;CACR;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,mBAAmB,GAAG,oBAAoB,CASvF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DecisionThemes Adapter (Placeholder)
|
|
3
|
+
*
|
|
4
|
+
* This adapter will integrate with the DecisionThemes framework (coming 2026).
|
|
5
|
+
* It transforms VT (Value Themes) + DT (Decision Themes) into flat tokens for DCV validation.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.decisionthemes.com
|
|
8
|
+
* @see docs/Adapters.md for implementation details
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { decisionthemesAdapter } from './adapters/decisionthemes.js';
|
|
13
|
+
*
|
|
14
|
+
* const { tokens, policy } = decisionthemesAdapter({
|
|
15
|
+
* vt: { ... }, // Value Themes (raw values)
|
|
16
|
+
* dt: { ... } // Decision Themes (formulas)
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // tokens = flat token object for DCV validation
|
|
20
|
+
* // policy = auto-generated constraints from 5-axis model
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Transform DecisionThemes (VT+DT) into DCV-compatible tokens
|
|
25
|
+
*
|
|
26
|
+
* @param input - VT (values) + DT (decisions)
|
|
27
|
+
* @returns Flat tokens + optional policy JSON
|
|
28
|
+
*/
|
|
29
|
+
export function decisionthemesAdapter(_input) {
|
|
30
|
+
// TODO: Implement when DecisionThemes integration is ready
|
|
31
|
+
// This will call the DecisionThemes resolver/compute engine to process _input
|
|
32
|
+
throw new Error('DecisionThemes adapter not yet implemented. ' +
|
|
33
|
+
'This is a placeholder for future integration with the DecisionThemes framework. ' +
|
|
34
|
+
'See https://www.decisionthemes.com for updates.');
|
|
35
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DecisionThemes Adapter (Placeholder)
|
|
3
|
+
*
|
|
4
|
+
* This adapter will integrate with the DecisionThemes framework (coming 2026).
|
|
5
|
+
* It transforms VT (Value Themes) + DT (Decision Themes) into flat tokens for DCV validation.
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.decisionthemes.com
|
|
8
|
+
* @see docs/Adapters.md for implementation details
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { decisionthemesAdapter } from './adapters/decisionthemes.js';
|
|
13
|
+
*
|
|
14
|
+
* const { tokens, policy } = decisionthemesAdapter({
|
|
15
|
+
* vt: { ... }, // Value Themes (raw values)
|
|
16
|
+
* dt: { ... } // Decision Themes (formulas)
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // tokens = flat token object for DCV validation
|
|
20
|
+
* // policy = auto-generated constraints from 5-axis model
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export interface VT {
|
|
25
|
+
// Value Themes - raw design values
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface DT {
|
|
30
|
+
// Decision Themes - formulas and decision mappings
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface DecisionThemesInput {
|
|
35
|
+
vt: VT;
|
|
36
|
+
dt: DT;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface DecisionThemesOutput {
|
|
40
|
+
tokens: Record<string, any>;
|
|
41
|
+
policy?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Transform DecisionThemes (VT+DT) into DCV-compatible tokens
|
|
46
|
+
*
|
|
47
|
+
* @param input - VT (values) + DT (decisions)
|
|
48
|
+
* @returns Flat tokens + optional policy JSON
|
|
49
|
+
*/
|
|
50
|
+
export function decisionthemesAdapter(_input: DecisionThemesInput): DecisionThemesOutput {
|
|
51
|
+
// TODO: Implement when DecisionThemes integration is ready
|
|
52
|
+
// This will call the DecisionThemes resolver/compute engine to process _input
|
|
53
|
+
|
|
54
|
+
throw new Error(
|
|
55
|
+
'DecisionThemes adapter not yet implemented. ' +
|
|
56
|
+
'This is a placeholder for future integration with the DecisionThemes framework. ' +
|
|
57
|
+
'See https://www.decisionthemes.com for updates.'
|
|
58
|
+
);
|
|
59
|
+
}
|
package/cli/commands/graph.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import { flattenTokens } from '../../core/flatten.js';
|
|
3
3
|
import { exportGraphImage } from '../../core/image-export.js';
|
|
4
|
-
import {
|
|
4
|
+
import { setupConstraints } from '../constraint-registry.js';
|
|
5
5
|
import { loadConfig } from '../config.js';
|
|
6
6
|
// Local helper for non-poset dependency graphs
|
|
7
7
|
function generateDependencyGraph(edges, format) {
|
|
@@ -127,7 +127,7 @@ export async function graphCommand(options) {
|
|
|
127
127
|
if (cfgRes.ok) {
|
|
128
128
|
const config = cfgRes.value;
|
|
129
129
|
const knownIds = new Set(Object.keys(flat));
|
|
130
|
-
|
|
130
|
+
setupConstraints(engine, { config, bp: breakpoint }, { knownIds });
|
|
131
131
|
const runtimeIssues = engine.evaluate(allIdsInHasse);
|
|
132
132
|
issues.push(...runtimeIssues);
|
|
133
133
|
}
|
package/cli/commands/graph.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
|
2
2
|
import type { GraphOptions } from '../types.js';
|
|
3
3
|
import { flattenTokens, type FlatToken } from '../../core/flatten.js';
|
|
4
4
|
import { exportGraphImage } from '../../core/image-export.js';
|
|
5
|
-
import {
|
|
5
|
+
import { setupConstraints } from '../constraint-registry.js';
|
|
6
6
|
import { loadConfig } from '../config.js';
|
|
7
7
|
|
|
8
8
|
// Local helper for non-poset dependency graphs
|
|
@@ -98,7 +98,7 @@ export async function graphCommand(options: GraphOptions): Promise<void> {
|
|
|
98
98
|
if (cfgRes.ok) {
|
|
99
99
|
const config = cfgRes.value;
|
|
100
100
|
const knownIds = new Set(Object.keys(flat as Record<string, FlatToken>));
|
|
101
|
-
|
|
101
|
+
setupConstraints(engine, { config, bp: breakpoint }, { knownIds });
|
|
102
102
|
const runtimeIssues = engine.evaluate(allIdsInHasse);
|
|
103
103
|
issues.push(...runtimeIssues);
|
|
104
104
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["validate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["validate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOnD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuK9E"}
|
package/cli/commands/validate.js
CHANGED
|
@@ -6,7 +6,10 @@ import { createValidationResult, createValidationReceipt, writeJsonOutput } from
|
|
|
6
6
|
import { readFileSync, existsSync } from 'node:fs';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { setupConstraints } from '../constraint-registry.js';
|
|
9
|
+
import { printVersionBanner } from '../version-banner.js';
|
|
9
10
|
export async function validateCommand(_options) {
|
|
11
|
+
// Show version banner (subtle, dimmed)
|
|
12
|
+
printVersionBanner({ quiet: _options.format === 'json' });
|
|
10
13
|
try {
|
|
11
14
|
const bps = parseBreakpoints(process.argv);
|
|
12
15
|
const crossAxisDebug = process.argv.includes('--cross-axis-debug');
|
package/cli/commands/validate.ts
CHANGED
|
@@ -8,8 +8,12 @@ import { createValidationResult, createValidationReceipt, writeJsonOutput } from
|
|
|
8
8
|
import { readFileSync, existsSync } from 'node:fs';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
10
|
import { setupConstraints } from '../constraint-registry.js';
|
|
11
|
+
import { printVersionBanner } from '../version-banner.js';
|
|
11
12
|
|
|
12
13
|
export async function validateCommand(_options: ValidateOptions): Promise<void> {
|
|
14
|
+
// Show version banner (subtle, dimmed)
|
|
15
|
+
printVersionBanner({ quiet: _options.format === 'json' });
|
|
16
|
+
|
|
13
17
|
try {
|
|
14
18
|
const bps = parseBreakpoints(process.argv);
|
|
15
19
|
const crossAxisDebug = process.argv.includes('--cross-axis-debug');
|
package/cli/json-output.d.ts
CHANGED
|
@@ -26,6 +26,11 @@ export interface ValidationResult {
|
|
|
26
26
|
engineVersion: string;
|
|
27
27
|
timestamp: string;
|
|
28
28
|
};
|
|
29
|
+
dcv: {
|
|
30
|
+
name: string;
|
|
31
|
+
version: string;
|
|
32
|
+
repository: string;
|
|
33
|
+
};
|
|
29
34
|
}
|
|
30
35
|
export interface ValidationReceipt extends ValidationResult {
|
|
31
36
|
environment: {
|
package/cli/json-output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-output.d.ts","sourceRoot":"","sources":["json-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"json-output.d.ts","sourceRoot":"","sources":["json-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMzD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,GAAG,EAAE;QACH,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,WAAW,EAAE;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;QACjC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,mBAAmB,CAiB3E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EAAE,EACzB,QAAQ,EAAE,eAAe,EAAE,EAC3B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACpB,gBAAgB,CAoBlB;AAcD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAC/B,iBAAiB,CAoCnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CASxE"}
|
package/cli/json-output.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { createHash } from 'node:crypto';
|
|
4
|
+
import { getVersionInfo } from './version-banner.js';
|
|
4
5
|
/**
|
|
5
6
|
* Convert internal ConstraintIssue to standardized ConstraintViolation format
|
|
6
7
|
*/
|
|
@@ -39,6 +40,7 @@ export function createValidationResult(errors, warnings, durationMs, engineVersi
|
|
|
39
40
|
engineVersion,
|
|
40
41
|
timestamp: new Date().toISOString(),
|
|
41
42
|
},
|
|
43
|
+
dcv: getVersionInfo(),
|
|
42
44
|
};
|
|
43
45
|
}
|
|
44
46
|
/**
|
package/cli/json-output.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ConstraintIssue } from '../core/engine.js';
|
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import { createHash } from 'node:crypto';
|
|
5
|
+
import { getVersionInfo } from './version-banner.js';
|
|
5
6
|
|
|
6
7
|
export interface ConstraintViolation {
|
|
7
8
|
ruleId: string;
|
|
@@ -31,6 +32,11 @@ export interface ValidationResult {
|
|
|
31
32
|
engineVersion: string;
|
|
32
33
|
timestamp: string;
|
|
33
34
|
};
|
|
35
|
+
dcv: {
|
|
36
|
+
name: string;
|
|
37
|
+
version: string;
|
|
38
|
+
repository: string;
|
|
39
|
+
};
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
export interface ValidationReceipt extends ValidationResult {
|
|
@@ -100,6 +106,7 @@ export function createValidationResult(
|
|
|
100
106
|
engineVersion,
|
|
101
107
|
timestamp: new Date().toISOString(),
|
|
102
108
|
},
|
|
109
|
+
dcv: getVersionInfo(),
|
|
103
110
|
};
|
|
104
111
|
}
|
|
105
112
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version banner utility
|
|
3
|
+
* Displays DCV version info when validation runs
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Print DCV version banner
|
|
7
|
+
* Shows: DCV v{version} | {repo_url}
|
|
8
|
+
*/
|
|
9
|
+
export declare function printVersionBanner(options?: {
|
|
10
|
+
quiet?: boolean;
|
|
11
|
+
}): void;
|
|
12
|
+
/**
|
|
13
|
+
* Get version string for JSON output
|
|
14
|
+
*/
|
|
15
|
+
export declare function getVersionInfo(): {
|
|
16
|
+
name: string;
|
|
17
|
+
version: string;
|
|
18
|
+
repository: string;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=version-banner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-banner.d.ts","sourceRoot":"","sources":["version-banner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkCH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAOtE;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAOtF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version banner utility
|
|
3
|
+
* Displays DCV version info when validation runs
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { join, dirname } from 'node:path';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
let cachedPkg = null;
|
|
10
|
+
function getPackageInfo() {
|
|
11
|
+
if (cachedPkg)
|
|
12
|
+
return cachedPkg;
|
|
13
|
+
try {
|
|
14
|
+
const pkgPath = join(__dirname, '../package.json');
|
|
15
|
+
const pkgContent = readFileSync(pkgPath, 'utf-8');
|
|
16
|
+
cachedPkg = JSON.parse(pkgContent);
|
|
17
|
+
return cachedPkg;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Fallback if package.json not found
|
|
21
|
+
return {
|
|
22
|
+
name: 'design-constraint-validator',
|
|
23
|
+
version: '2.0.0',
|
|
24
|
+
homepage: 'https://github.com/CseperkePapp/design-constraint-validator'
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Print DCV version banner
|
|
30
|
+
* Shows: DCV v{version} | {repo_url}
|
|
31
|
+
*/
|
|
32
|
+
export function printVersionBanner(options) {
|
|
33
|
+
if (options?.quiet)
|
|
34
|
+
return;
|
|
35
|
+
const pkg = getPackageInfo();
|
|
36
|
+
const repoUrl = pkg.homepage || 'https://github.com/CseperkePapp/design-constraint-validator';
|
|
37
|
+
console.log(`\x1b[2m${pkg.name} v${pkg.version} | ${repoUrl}\x1b[0m`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get version string for JSON output
|
|
41
|
+
*/
|
|
42
|
+
export function getVersionInfo() {
|
|
43
|
+
const pkg = getPackageInfo();
|
|
44
|
+
return {
|
|
45
|
+
name: pkg.name,
|
|
46
|
+
version: pkg.version,
|
|
47
|
+
repository: pkg.homepage || 'https://github.com/CseperkePapp/design-constraint-validator'
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version banner utility
|
|
3
|
+
* Displays DCV version info when validation runs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
import { join, dirname } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
interface PackageJson {
|
|
13
|
+
name: string;
|
|
14
|
+
version: string;
|
|
15
|
+
homepage?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let cachedPkg: PackageJson | null = null;
|
|
19
|
+
|
|
20
|
+
function getPackageInfo(): PackageJson {
|
|
21
|
+
if (cachedPkg) return cachedPkg;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const pkgPath = join(__dirname, '../package.json');
|
|
25
|
+
const pkgContent = readFileSync(pkgPath, 'utf-8');
|
|
26
|
+
cachedPkg = JSON.parse(pkgContent);
|
|
27
|
+
return cachedPkg!;
|
|
28
|
+
} catch {
|
|
29
|
+
// Fallback if package.json not found
|
|
30
|
+
return {
|
|
31
|
+
name: 'design-constraint-validator',
|
|
32
|
+
version: '2.0.0',
|
|
33
|
+
homepage: 'https://github.com/CseperkePapp/design-constraint-validator'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Print DCV version banner
|
|
40
|
+
* Shows: DCV v{version} | {repo_url}
|
|
41
|
+
*/
|
|
42
|
+
export function printVersionBanner(options?: { quiet?: boolean }): void {
|
|
43
|
+
if (options?.quiet) return;
|
|
44
|
+
|
|
45
|
+
const pkg = getPackageInfo();
|
|
46
|
+
const repoUrl = pkg.homepage || 'https://github.com/CseperkePapp/design-constraint-validator';
|
|
47
|
+
|
|
48
|
+
console.log(`\x1b[2m${pkg.name} v${pkg.version} | ${repoUrl}\x1b[0m`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get version string for JSON output
|
|
53
|
+
*/
|
|
54
|
+
export function getVersionInfo(): { name: string; version: string; repository: string } {
|
|
55
|
+
const pkg = getPackageInfo();
|
|
56
|
+
return {
|
|
57
|
+
name: pkg.name,
|
|
58
|
+
version: pkg.version,
|
|
59
|
+
repository: pkg.homepage || 'https://github.com/CseperkePapp/design-constraint-validator'
|
|
60
|
+
};
|
|
61
|
+
}
|
package/package.json
CHANGED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated This module is deprecated. Use constraint-registry.ts instead.
|
|
3
|
-
*
|
|
4
|
-
* Phase 3A (Architectural Cleanup): This file contains legacy runtime constraint
|
|
5
|
-
* loading logic that has been replaced by the centralized constraint-registry.ts module.
|
|
6
|
-
*
|
|
7
|
-
* Migration: Replace attachRuntimeConstraints() with setupConstraints() from constraint-registry.ts
|
|
8
|
-
*
|
|
9
|
-
* This file will be removed in a future major version.
|
|
10
|
-
*/
|
|
11
|
-
import type { Engine } from '../core/engine.js';
|
|
12
|
-
import type { Breakpoint } from '../core/breakpoints.js';
|
|
13
|
-
import type { DcvConfig } from './types.js';
|
|
14
|
-
type AttachRuntimeOpts = {
|
|
15
|
-
config: DcvConfig;
|
|
16
|
-
knownIds: Set<string>;
|
|
17
|
-
bp?: Breakpoint;
|
|
18
|
-
crossAxisDebug?: boolean;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Attach runtime constraints that depend on project files or built-in policies:
|
|
22
|
-
* - Cross-axis rules from themes/cross-axis*.rules.json
|
|
23
|
-
* - Built-in threshold rules (e.g., control.size.min >= 44px)
|
|
24
|
-
*
|
|
25
|
-
* @deprecated Use setupConstraints() from constraint-registry.ts instead.
|
|
26
|
-
* This function will be removed in a future major version.
|
|
27
|
-
*/
|
|
28
|
-
export declare function attachRuntimeConstraints(engine: Engine, opts: AttachRuntimeOpts): void;
|
|
29
|
-
export {};
|
|
30
|
-
//# sourceMappingURL=constraints-loader.d.ts.map
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated This module is deprecated. Use constraint-registry.ts instead.
|
|
3
|
-
*
|
|
4
|
-
* Phase 3A (Architectural Cleanup): This file contains legacy runtime constraint
|
|
5
|
-
* loading logic that has been replaced by the centralized constraint-registry.ts module.
|
|
6
|
-
*
|
|
7
|
-
* Migration: Replace attachRuntimeConstraints() with setupConstraints() from constraint-registry.ts
|
|
8
|
-
*
|
|
9
|
-
* This file will be removed in a future major version.
|
|
10
|
-
*/
|
|
11
|
-
import { loadCrossAxisPlugin } from '../core/cross-axis-config.js';
|
|
12
|
-
import { ThresholdPlugin } from '../core/constraints/threshold.js';
|
|
13
|
-
/**
|
|
14
|
-
* Attach runtime constraints that depend on project files or built-in policies:
|
|
15
|
-
* - Cross-axis rules from themes/cross-axis*.rules.json
|
|
16
|
-
* - Built-in threshold rules (e.g., control.size.min >= 44px)
|
|
17
|
-
*
|
|
18
|
-
* @deprecated Use setupConstraints() from constraint-registry.ts instead.
|
|
19
|
-
* This function will be removed in a future major version.
|
|
20
|
-
*/
|
|
21
|
-
export function attachRuntimeConstraints(engine, opts) {
|
|
22
|
-
const { knownIds, bp, crossAxisDebug, config } = opts;
|
|
23
|
-
// Cross-axis rules: global + optional breakpoint-specific
|
|
24
|
-
try {
|
|
25
|
-
engine.use(loadCrossAxisPlugin('themes/cross-axis.rules.json', bp, {
|
|
26
|
-
debug: !!crossAxisDebug,
|
|
27
|
-
knownIds,
|
|
28
|
-
}));
|
|
29
|
-
if (bp) {
|
|
30
|
-
const bpRulesPath = `themes/cross-axis.${bp}.rules.json`;
|
|
31
|
-
engine.use(loadCrossAxisPlugin(bpRulesPath, bp, {
|
|
32
|
-
debug: !!crossAxisDebug,
|
|
33
|
-
knownIds,
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
// If cross-axis configuration fails, continue with other constraints.
|
|
39
|
-
}
|
|
40
|
-
const constraintsCfg = config.constraints ?? {};
|
|
41
|
-
// Built-in threshold rule for touch targets (configurable)
|
|
42
|
-
const enableBuiltInThreshold = constraintsCfg.enableBuiltInThreshold === undefined ? true : !!constraintsCfg.enableBuiltInThreshold;
|
|
43
|
-
if (enableBuiltInThreshold) {
|
|
44
|
-
try {
|
|
45
|
-
engine.use(ThresholdPlugin([
|
|
46
|
-
{
|
|
47
|
-
id: 'control.size.min',
|
|
48
|
-
op: '>=',
|
|
49
|
-
valuePx: 44,
|
|
50
|
-
where: 'Touch target (WCAG / Apple HIG)',
|
|
51
|
-
},
|
|
52
|
-
], 'threshold'));
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
// Threshold attachment is best-effort; failures should not abort validation.
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated This module is deprecated. Use constraint-registry.ts instead.
|
|
3
|
-
*
|
|
4
|
-
* Phase 3A (Architectural Cleanup): This file contains legacy runtime constraint
|
|
5
|
-
* loading logic that has been replaced by the centralized constraint-registry.ts module.
|
|
6
|
-
*
|
|
7
|
-
* Migration: Replace attachRuntimeConstraints() with setupConstraints() from constraint-registry.ts
|
|
8
|
-
*
|
|
9
|
-
* This file will be removed in a future major version.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { Engine } from '../core/engine.js';
|
|
13
|
-
import { loadCrossAxisPlugin } from '../core/cross-axis-config.js';
|
|
14
|
-
import { ThresholdPlugin } from '../core/constraints/threshold.js';
|
|
15
|
-
import type { Breakpoint } from '../core/breakpoints.js';
|
|
16
|
-
import type { DcvConfig } from './types.js';
|
|
17
|
-
|
|
18
|
-
type AttachRuntimeOpts = {
|
|
19
|
-
config: DcvConfig;
|
|
20
|
-
knownIds: Set<string>;
|
|
21
|
-
bp?: Breakpoint;
|
|
22
|
-
crossAxisDebug?: boolean;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Attach runtime constraints that depend on project files or built-in policies:
|
|
27
|
-
* - Cross-axis rules from themes/cross-axis*.rules.json
|
|
28
|
-
* - Built-in threshold rules (e.g., control.size.min >= 44px)
|
|
29
|
-
*
|
|
30
|
-
* @deprecated Use setupConstraints() from constraint-registry.ts instead.
|
|
31
|
-
* This function will be removed in a future major version.
|
|
32
|
-
*/
|
|
33
|
-
export function attachRuntimeConstraints(engine: Engine, opts: AttachRuntimeOpts): void {
|
|
34
|
-
const { knownIds, bp, crossAxisDebug, config } = opts;
|
|
35
|
-
|
|
36
|
-
// Cross-axis rules: global + optional breakpoint-specific
|
|
37
|
-
try {
|
|
38
|
-
engine.use(
|
|
39
|
-
loadCrossAxisPlugin('themes/cross-axis.rules.json', bp, {
|
|
40
|
-
debug: !!crossAxisDebug,
|
|
41
|
-
knownIds,
|
|
42
|
-
}),
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
if (bp) {
|
|
46
|
-
const bpRulesPath = `themes/cross-axis.${bp}.rules.json`;
|
|
47
|
-
engine.use(
|
|
48
|
-
loadCrossAxisPlugin(bpRulesPath, bp, {
|
|
49
|
-
debug: !!crossAxisDebug,
|
|
50
|
-
knownIds,
|
|
51
|
-
}),
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
} catch {
|
|
55
|
-
// If cross-axis configuration fails, continue with other constraints.
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const constraintsCfg = config.constraints ?? {};
|
|
59
|
-
|
|
60
|
-
// Built-in threshold rule for touch targets (configurable)
|
|
61
|
-
const enableBuiltInThreshold =
|
|
62
|
-
constraintsCfg.enableBuiltInThreshold === undefined ? true : !!constraintsCfg.enableBuiltInThreshold;
|
|
63
|
-
|
|
64
|
-
if (enableBuiltInThreshold) {
|
|
65
|
-
try {
|
|
66
|
-
engine.use(
|
|
67
|
-
ThresholdPlugin(
|
|
68
|
-
[
|
|
69
|
-
{
|
|
70
|
-
id: 'control.size.min',
|
|
71
|
-
op: '>=',
|
|
72
|
-
valuePx: 44,
|
|
73
|
-
where: 'Touch target (WCAG / Apple HIG)',
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
'threshold',
|
|
77
|
-
),
|
|
78
|
-
);
|
|
79
|
-
} catch {
|
|
80
|
-
// Threshold attachment is best-effort; failures should not abort validation.
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
package/cli/engine-helpers.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated This module is deprecated. Use constraint-registry.ts instead.
|
|
3
|
-
*
|
|
4
|
-
* Phase 3A (Architectural Cleanup): This file contains legacy constraint loading logic
|
|
5
|
-
* that has been replaced by the centralized constraint-registry.ts module.
|
|
6
|
-
*
|
|
7
|
-
* Migration guide:
|
|
8
|
-
* - Replace createEngine() or createValidationEngine() with:
|
|
9
|
-
* ```ts
|
|
10
|
-
* import { Engine } from '../core/engine.js';
|
|
11
|
-
* import { flattenTokens, type FlatToken } from '../core/flatten.js';
|
|
12
|
-
* import { setupConstraints } from './constraint-registry.js';
|
|
13
|
-
*
|
|
14
|
-
* const { flat, edges } = flattenTokens(tokens);
|
|
15
|
-
* const init = {};
|
|
16
|
-
* for (const t of Object.values(flat)) {
|
|
17
|
-
* init[(t as FlatToken).id] = (t as FlatToken).value;
|
|
18
|
-
* }
|
|
19
|
-
* const engine = new Engine(init, edges);
|
|
20
|
-
* const knownIds = new Set(Object.keys(init));
|
|
21
|
-
* setupConstraints(engine, { config, bp }, { knownIds });
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* This file will be removed in a future major version.
|
|
25
|
-
*/
|
|
26
|
-
import { type TokenNode } from '../core/flatten.js';
|
|
27
|
-
import { Engine } from '../core/engine.js';
|
|
28
|
-
import { loadTokensWithBreakpoint, type Breakpoint } from '../core/breakpoints.js';
|
|
29
|
-
import type { DcvConfig } from './types.js';
|
|
30
|
-
/**
|
|
31
|
-
* @deprecated Use constraint-registry.ts setupConstraints() instead.
|
|
32
|
-
* This function will be removed in a future major version.
|
|
33
|
-
*/
|
|
34
|
-
export declare function createEngine(tokensRoot: TokenNode, config?: DcvConfig): Engine;
|
|
35
|
-
/**
|
|
36
|
-
* @deprecated Use constraint-registry.ts setupConstraints() instead.
|
|
37
|
-
* This function will be removed in a future major version.
|
|
38
|
-
*/
|
|
39
|
-
export declare function createValidationEngine(tokensRoot: TokenNode, bp: Breakpoint | undefined, config: DcvConfig): Engine;
|
|
40
|
-
export { loadTokensWithBreakpoint };
|
|
41
|
-
//# sourceMappingURL=engine-helpers.d.ts.map
|