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 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
+ }
@@ -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 { attachRuntimeConstraints } from '../constraints-loader.js';
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
- attachRuntimeConstraints(engine, { config, knownIds, bp: breakpoint });
130
+ setupConstraints(engine, { config, bp: breakpoint }, { knownIds });
131
131
  const runtimeIssues = engine.evaluate(allIdsInHasse);
132
132
  issues.push(...runtimeIssues);
133
133
  }
@@ -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 { attachRuntimeConstraints } from '../constraints-loader.js';
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
- attachRuntimeConstraints(engine, { config, knownIds, bp: breakpoint });
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;AAMnD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoK9E"}
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"}
@@ -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');
@@ -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');
@@ -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: {
@@ -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;AAKzD,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;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,CAmBlB;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"}
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"}
@@ -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
  /**
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "design-constraint-validator",
3
- "version": "1.1.0",
3
+ "version": "2.0.1",
4
4
  "description": "Mathematical constraint validator for design systems — ensuring consistency, accessibility, and logical coherence",
5
5
  "type": "module",
6
6
  "engines": {
@@ -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
- }
@@ -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