@schalkneethling/css-property-type-validator-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +6 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +121 -0
- package/dist/registry.js.map +1 -0
- package/dist/syntax-samples.d.ts +2 -0
- package/dist/syntax-samples.d.ts.map +1 -0
- package/dist/syntax-samples.js +88 -0
- package/dist/syntax-samples.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +3 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +136 -0
- package/dist/validate.js.map +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Schalk Neethling
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RegisteredProperty, ValidationDiagnostic, ValidationInput } from "./types.js";
|
|
2
|
+
export declare function collectRegistry(inputs: ValidationInput[]): {
|
|
3
|
+
diagnostics: ValidationDiagnostic[];
|
|
4
|
+
registry: RegisteredProperty[];
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAoD5F,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG;IAC1D,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC,CAyFA"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import * as cssTree from "css-tree";
|
|
2
|
+
function toBoolean(value) {
|
|
3
|
+
if (value === "true") {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
if (value === "false") {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
function toLocation(loc) {
|
|
12
|
+
return loc
|
|
13
|
+
? {
|
|
14
|
+
source: loc.source,
|
|
15
|
+
start: { ...loc.start },
|
|
16
|
+
end: { ...loc.end },
|
|
17
|
+
}
|
|
18
|
+
: null;
|
|
19
|
+
}
|
|
20
|
+
function descriptorMap(block) {
|
|
21
|
+
const descriptors = new Map();
|
|
22
|
+
for (const declaration of block?.children ?? []) {
|
|
23
|
+
descriptors.set(declaration.property, declaration);
|
|
24
|
+
}
|
|
25
|
+
return descriptors;
|
|
26
|
+
}
|
|
27
|
+
function getStringDescriptor(declaration) {
|
|
28
|
+
const firstNode = declaration?.value?.children?.first ?? declaration?.value?.children?.[0];
|
|
29
|
+
if (firstNode?.type === "String") {
|
|
30
|
+
return firstNode.value;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
function getRawDescriptor(declaration) {
|
|
35
|
+
if (!declaration?.value) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return cssTree.generate(declaration.value).trim();
|
|
39
|
+
}
|
|
40
|
+
export function collectRegistry(inputs) {
|
|
41
|
+
const diagnostics = [];
|
|
42
|
+
const registry = new Map();
|
|
43
|
+
for (const input of inputs) {
|
|
44
|
+
let ast;
|
|
45
|
+
try {
|
|
46
|
+
ast = cssTree.parse(input.css, {
|
|
47
|
+
filename: input.path,
|
|
48
|
+
positions: true,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
diagnostics.push({
|
|
53
|
+
code: "unparseable-stylesheet",
|
|
54
|
+
filePath: input.path,
|
|
55
|
+
loc: null,
|
|
56
|
+
message: `Could not parse stylesheet: ${error.message}`,
|
|
57
|
+
});
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
cssTree.walk(ast, {
|
|
61
|
+
visit: "Atrule",
|
|
62
|
+
enter(node) {
|
|
63
|
+
if (node.name !== "property") {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const propertyName = node.prelude?.children?.first?.name ?? node.prelude?.children?.[0]?.name;
|
|
67
|
+
if (!propertyName) {
|
|
68
|
+
diagnostics.push({
|
|
69
|
+
code: "invalid-property-registration",
|
|
70
|
+
filePath: input.path,
|
|
71
|
+
loc: toLocation(node.loc),
|
|
72
|
+
message: "Found an @property rule without a custom property name.",
|
|
73
|
+
});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const descriptors = descriptorMap(node.block);
|
|
77
|
+
const syntaxDeclaration = descriptors.get("syntax");
|
|
78
|
+
const syntax = getStringDescriptor(syntaxDeclaration);
|
|
79
|
+
if (!syntax) {
|
|
80
|
+
diagnostics.push({
|
|
81
|
+
code: "invalid-property-registration",
|
|
82
|
+
filePath: input.path,
|
|
83
|
+
loc: toLocation(node.loc),
|
|
84
|
+
message: `@property ${propertyName} is missing a valid string-valued syntax descriptor.`,
|
|
85
|
+
propertyName,
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
if (syntax !== "*") {
|
|
91
|
+
cssTree.definitionSyntax.parse(syntax);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
diagnostics.push({
|
|
96
|
+
code: "invalid-property-registration",
|
|
97
|
+
filePath: input.path,
|
|
98
|
+
loc: toLocation(node.loc),
|
|
99
|
+
message: `@property ${propertyName} has an invalid syntax descriptor "${syntax}": ${error.message}`,
|
|
100
|
+
propertyName,
|
|
101
|
+
registeredSyntax: syntax,
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
registry.set(propertyName, {
|
|
106
|
+
filePath: input.path,
|
|
107
|
+
inherits: toBoolean(getRawDescriptor(descriptors.get("inherits"))),
|
|
108
|
+
initialValue: getRawDescriptor(descriptors.get("initial-value")),
|
|
109
|
+
loc: toLocation(node.loc),
|
|
110
|
+
name: propertyName,
|
|
111
|
+
syntax,
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
diagnostics,
|
|
118
|
+
registry: [...registry.values()],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax-samples.d.ts","sourceRoot":"","sources":["../src/syntax-samples.ts"],"names":[],"mappings":"AAsGA,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,GAAG,MAAM,EAAE,CAO1F"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const SIMPLE_TYPE_SAMPLES = {
|
|
2
|
+
"alpha-value": ["0.5"],
|
|
3
|
+
angle: ["45deg"],
|
|
4
|
+
color: ["red"],
|
|
5
|
+
"custom-ident": ["brand-token"],
|
|
6
|
+
"custom-property-name": ["--brand-token"],
|
|
7
|
+
"dashed-ident": ["--brand-token"],
|
|
8
|
+
flex: ["1"],
|
|
9
|
+
"font-family": ["serif"],
|
|
10
|
+
ident: ["token"],
|
|
11
|
+
image: ['url("image.png")'],
|
|
12
|
+
integer: ["1"],
|
|
13
|
+
length: ["1px"],
|
|
14
|
+
"length-percentage": ["1px", "50%"],
|
|
15
|
+
number: ["1"],
|
|
16
|
+
percentage: ["50%"],
|
|
17
|
+
position: ["center"],
|
|
18
|
+
ratio: ["16/9"],
|
|
19
|
+
resolution: ["96dpi"],
|
|
20
|
+
shadow: ["0 0 1px red"],
|
|
21
|
+
string: ['"value"'],
|
|
22
|
+
time: ["1s"],
|
|
23
|
+
transform: ["translateX(1px)"],
|
|
24
|
+
"transform-function": ["translateX(1px)"],
|
|
25
|
+
"transform-list": ["translateX(1px)"],
|
|
26
|
+
url: ['url("https://example.com/example.png")'],
|
|
27
|
+
};
|
|
28
|
+
function dedupe(values) {
|
|
29
|
+
return [...new Set(values)];
|
|
30
|
+
}
|
|
31
|
+
function combineTerms(parts, separator) {
|
|
32
|
+
const samples = parts.map((options) => options[0]).filter(Boolean);
|
|
33
|
+
return samples.length === parts.length ? [samples.join(separator)] : [];
|
|
34
|
+
}
|
|
35
|
+
function fromFunctionName(name) {
|
|
36
|
+
if (name === "calc()") {
|
|
37
|
+
return ["calc(1px + 1px)"];
|
|
38
|
+
}
|
|
39
|
+
if (name === "transform-function") {
|
|
40
|
+
return ["translateX(1px)"];
|
|
41
|
+
}
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
function fromNode(node) {
|
|
45
|
+
if (!node) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
switch (node.type) {
|
|
49
|
+
case "Group": {
|
|
50
|
+
const terms = Array.isArray(node.terms) ? node.terms : [];
|
|
51
|
+
if (node.combinator === "|") {
|
|
52
|
+
return dedupe(terms.flatMap(fromNode));
|
|
53
|
+
}
|
|
54
|
+
return combineTerms(terms.map(fromNode), node.combinator === "," ? ", " : " ");
|
|
55
|
+
}
|
|
56
|
+
case "Multiplier": {
|
|
57
|
+
const baseSamples = fromNode(node.term);
|
|
58
|
+
const count = Math.max(node.min ?? 1, 1);
|
|
59
|
+
if (baseSamples.length === 0) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
// Expand repeatable syntaxes like `<length>{1,4}` into a concrete sample value.
|
|
63
|
+
// For example: With a baseSample of ["1px"], count of 3, and comma false:
|
|
64
|
+
// ["1px", "1px", "1px"]
|
|
65
|
+
return baseSamples.map((sample) => Array.from({ length: count }, () => sample).join(node.comma ? ", " : " "));
|
|
66
|
+
}
|
|
67
|
+
case "Keyword":
|
|
68
|
+
return [node.name];
|
|
69
|
+
case "Type":
|
|
70
|
+
return SIMPLE_TYPE_SAMPLES[node.name] ?? fromFunctionName(node.name);
|
|
71
|
+
case "Property":
|
|
72
|
+
return SIMPLE_TYPE_SAMPLES[node.name] ?? [];
|
|
73
|
+
case "Function":
|
|
74
|
+
return fromFunctionName(node.name);
|
|
75
|
+
case "String":
|
|
76
|
+
return [`"${node.value ?? "value"}"`];
|
|
77
|
+
default:
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function buildRepresentativeSamples(syntax, definitionSyntax) {
|
|
82
|
+
if (syntax === "*") {
|
|
83
|
+
return ["0"];
|
|
84
|
+
}
|
|
85
|
+
const syntaxAst = definitionSyntax.parse(syntax);
|
|
86
|
+
return dedupe(fromNode(syntaxAst)).slice(0, 8);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=syntax-samples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax-samples.js","sourceRoot":"","sources":["../src/syntax-samples.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface SourcePosition {
|
|
2
|
+
offset: number;
|
|
3
|
+
line: number;
|
|
4
|
+
column: number;
|
|
5
|
+
}
|
|
6
|
+
export interface SourceLocation {
|
|
7
|
+
source?: string;
|
|
8
|
+
start: SourcePosition;
|
|
9
|
+
end: SourcePosition;
|
|
10
|
+
}
|
|
11
|
+
export interface ValidationInput {
|
|
12
|
+
path: string;
|
|
13
|
+
css: string;
|
|
14
|
+
}
|
|
15
|
+
export interface RegisteredProperty {
|
|
16
|
+
filePath: string;
|
|
17
|
+
inherits?: boolean;
|
|
18
|
+
initialValue?: string;
|
|
19
|
+
loc: SourceLocation | null;
|
|
20
|
+
name: string;
|
|
21
|
+
syntax: string;
|
|
22
|
+
}
|
|
23
|
+
export type DiagnosticCode = "invalid-property-registration" | "incompatible-var-usage" | "unparseable-stylesheet";
|
|
24
|
+
export interface ValidationDiagnostic {
|
|
25
|
+
code: DiagnosticCode;
|
|
26
|
+
filePath: string;
|
|
27
|
+
loc: SourceLocation | null;
|
|
28
|
+
message: string;
|
|
29
|
+
propertyName?: string;
|
|
30
|
+
registeredSyntax?: string;
|
|
31
|
+
expectedProperty?: string;
|
|
32
|
+
snippet?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ValidationResult {
|
|
35
|
+
diagnostics: ValidationDiagnostic[];
|
|
36
|
+
registry: RegisteredProperty[];
|
|
37
|
+
skippedDeclarations: number;
|
|
38
|
+
validatedDeclarations: number;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,CAAC;IACtB,GAAG,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GACtB,+BAA+B,GAC/B,wBAAwB,GACxB,wBAAwB,CAAC;AAE7B,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qBAAqB,EAAE,MAAM,CAAC;CAC/B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AA+HpB,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,gBAAgB,CAoCzE"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import * as cssTree from "css-tree";
|
|
2
|
+
import { buildRepresentativeSamples } from "./syntax-samples.js";
|
|
3
|
+
import { collectRegistry } from "./registry.js";
|
|
4
|
+
function toLocation(loc) {
|
|
5
|
+
return loc
|
|
6
|
+
? {
|
|
7
|
+
source: loc.source,
|
|
8
|
+
start: { ...loc.start },
|
|
9
|
+
end: { ...loc.end },
|
|
10
|
+
}
|
|
11
|
+
: null;
|
|
12
|
+
}
|
|
13
|
+
function registryMap(registry) {
|
|
14
|
+
return new Map(registry.map((entry) => [entry.name, entry]));
|
|
15
|
+
}
|
|
16
|
+
function collectVarFunctions(value) {
|
|
17
|
+
const functions = [];
|
|
18
|
+
cssTree.walk(value, {
|
|
19
|
+
visit: "Function",
|
|
20
|
+
enter(node) {
|
|
21
|
+
if (node.name === "var") {
|
|
22
|
+
functions.push(node);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
return functions;
|
|
27
|
+
}
|
|
28
|
+
function getVarPropertyName(node) {
|
|
29
|
+
const firstNode = node.children?.first ?? node.children?.[0];
|
|
30
|
+
return firstNode?.type === "Identifier" ? firstNode.name : undefined;
|
|
31
|
+
}
|
|
32
|
+
function parseValue(value) {
|
|
33
|
+
try {
|
|
34
|
+
return cssTree.parse(value, { context: "value" });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function declarationMatchesSample(declaration, varNode, sample) {
|
|
41
|
+
const valueSource = cssTree.generate(declaration.value);
|
|
42
|
+
const replacementTarget = cssTree.generate(varNode);
|
|
43
|
+
const replacedSource = valueSource.replace(replacementTarget, sample);
|
|
44
|
+
const replacedAst = parseValue(replacedSource);
|
|
45
|
+
if (!replacedAst) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const match = cssTree.lexer.matchProperty(declaration.property, replacedAst);
|
|
49
|
+
return Boolean(match?.matched);
|
|
50
|
+
}
|
|
51
|
+
function validateDeclaration(filePath, declaration, registry) {
|
|
52
|
+
const diagnostics = [];
|
|
53
|
+
const varFunctions = collectVarFunctions(declaration.value);
|
|
54
|
+
// v1 only validates var() consumption sites, not authored values assigned to custom properties.
|
|
55
|
+
if (varFunctions.length === 0 || declaration.property.startsWith("--")) {
|
|
56
|
+
return { diagnostics, skipped: 0, validated: 0 };
|
|
57
|
+
}
|
|
58
|
+
// Multiple var() usages need coordinated substitution, so we track them as skipped for now.
|
|
59
|
+
if (varFunctions.length > 1) {
|
|
60
|
+
return { diagnostics, skipped: 1, validated: 0 };
|
|
61
|
+
}
|
|
62
|
+
const varNode = varFunctions[0];
|
|
63
|
+
const propertyName = getVarPropertyName(varNode);
|
|
64
|
+
// If the first var() argument is not a custom property name, we cannot resolve it reliably.
|
|
65
|
+
if (!propertyName) {
|
|
66
|
+
return { diagnostics, skipped: 1, validated: 0 };
|
|
67
|
+
}
|
|
68
|
+
const registration = registry.get(propertyName);
|
|
69
|
+
// Unregistered custom properties are intentionally ignored in this first version.
|
|
70
|
+
if (!registration) {
|
|
71
|
+
return { diagnostics, skipped: 0, validated: 0 };
|
|
72
|
+
}
|
|
73
|
+
let samples;
|
|
74
|
+
try {
|
|
75
|
+
samples = buildRepresentativeSamples(registration.syntax, cssTree.definitionSyntax);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return { diagnostics, skipped: 1, validated: 0 };
|
|
79
|
+
}
|
|
80
|
+
// If we cannot materialize any valid sample values for the registered syntax,
|
|
81
|
+
// we skip the check.
|
|
82
|
+
if (samples.length === 0) {
|
|
83
|
+
return { diagnostics, skipped: 1, validated: 0 };
|
|
84
|
+
}
|
|
85
|
+
// A declaration is considered compatible if at least one representative
|
|
86
|
+
// sample fits the consumer property.
|
|
87
|
+
const isCompatible = samples.some((sample) => declarationMatchesSample(declaration, varNode, sample));
|
|
88
|
+
if (!isCompatible) {
|
|
89
|
+
diagnostics.push({
|
|
90
|
+
code: "incompatible-var-usage",
|
|
91
|
+
filePath,
|
|
92
|
+
loc: toLocation(varNode.loc),
|
|
93
|
+
message: `Registered property ${propertyName} uses syntax "${registration.syntax}" which is incompatible with ${declaration.property} at this var() usage.`,
|
|
94
|
+
propertyName,
|
|
95
|
+
registeredSyntax: registration.syntax,
|
|
96
|
+
expectedProperty: declaration.property,
|
|
97
|
+
snippet: cssTree.generate(declaration),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return { diagnostics, skipped: 0, validated: 1 };
|
|
101
|
+
}
|
|
102
|
+
export function validateFiles(inputs) {
|
|
103
|
+
const registryResult = collectRegistry(inputs);
|
|
104
|
+
const diagnostics = [...registryResult.diagnostics];
|
|
105
|
+
const registry = registryMap(registryResult.registry);
|
|
106
|
+
let skippedDeclarations = 0;
|
|
107
|
+
let validatedDeclarations = 0;
|
|
108
|
+
for (const input of inputs) {
|
|
109
|
+
let ast;
|
|
110
|
+
try {
|
|
111
|
+
ast = cssTree.parse(input.css, {
|
|
112
|
+
filename: input.path,
|
|
113
|
+
positions: true,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
cssTree.walk(ast, {
|
|
120
|
+
visit: "Declaration",
|
|
121
|
+
enter(node) {
|
|
122
|
+
const result = validateDeclaration(input.path, node, registry);
|
|
123
|
+
diagnostics.push(...result.diagnostics);
|
|
124
|
+
skippedDeclarations += result.skipped;
|
|
125
|
+
validatedDeclarations += result.validated;
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
diagnostics,
|
|
131
|
+
registry: registryResult.registry,
|
|
132
|
+
skippedDeclarations,
|
|
133
|
+
validatedDeclarations,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@schalkneethling/css-property-type-validator-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Standalone CSS custom property type validator core.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"css",
|
|
7
|
+
"custom-properties",
|
|
8
|
+
"property",
|
|
9
|
+
"validator",
|
|
10
|
+
"design-tokens"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Schalk Neethling",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/schalkneethling/css-property-type-validator.git",
|
|
23
|
+
"directory": "packages/core"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/schalkneethling/css-property-type-validator#readme",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/schalkneethling/css-property-type-validator/issues"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"css-tree": "^3.2.1"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"vitest": "^4.1.2"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -p tsconfig.json"
|
|
46
|
+
}
|
|
47
|
+
}
|