@vltpkg/dss-parser 1.3.8 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/grammar.d.ts +8 -1
- package/dist/grammar.js +8 -0
- package/dist/index.js +16 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -27,9 +27,11 @@ const ast = parse(':root > *')
|
|
|
27
27
|
- dangling combinators, e.g. `:root >`, `> >`
|
|
28
28
|
- bare words, strings, empty ids / attributes, e.g. `foo`, `.dev`,
|
|
29
29
|
`"foo"`, `#`, `[]`
|
|
30
|
+
- a part selector (`:skill()`) with an empty argument, not ending a
|
|
31
|
+
top-level selector, or inside `:not()`/`:is()`/`:has()`
|
|
30
32
|
|
|
31
|
-
`:is()` arguments are a forgiving list: only the
|
|
32
|
-
|
|
33
|
+
`:is()` arguments are a forgiving list: only the bare words group and
|
|
34
|
+
the part selector rule apply there.
|
|
33
35
|
|
|
34
36
|
Pass `{ loose: true }` to skip the DSS checks (malformed syntax still
|
|
35
37
|
throws):
|
|
@@ -38,5 +40,5 @@ throws):
|
|
|
38
40
|
parse('#a, :unknown', { loose: true }) // no throw
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
Supported names are exported as `pseudoClassNames`, `combinatorNames
|
|
42
|
-
and `
|
|
43
|
+
Supported names are exported as `pseudoClassNames`, `combinatorNames`,
|
|
44
|
+
`attributeOperatorNames` and `partPseudoNames`.
|
package/dist/grammar.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pseudo-class names supported by DSS, without the leading `:`.
|
|
3
3
|
*/
|
|
4
|
-
export declare const pseudoClassNames: readonly ["abandoned", "attr", "built", "confused", "cve", "cwe", "debug", "deprecated", "dev", "diff", "dist", "dynamic", "empty", "entropic", "env", "eval", "fs", "has", "host", "hostname", "is", "license", "link", "malware", "minified", "missing", "native", "network", "not", "obfuscated", "optional", "outdated", "overridden", "path", "peer", "prerelease", "private", "prod", "project", "published", "registry", "root", "scanned", "scope", "score", "scripts", "semver", "sev", "severity", "shell", "shrinkwrap", "spec", "squat", "suspicious", "tracker", "trivial", "type", "undesirable", "unknown", "unmaintained", "unpopular", "unstable", "v", "vuln", "vulnerable", "workspace"];
|
|
4
|
+
export declare const pseudoClassNames: readonly ["abandoned", "attr", "built", "confused", "cve", "cwe", "debug", "deprecated", "dev", "diff", "dist", "dynamic", "empty", "entropic", "env", "eval", "fs", "has", "host", "hostname", "is", "license", "link", "malware", "minified", "missing", "native", "network", "not", "obfuscated", "optional", "outdated", "overridden", "path", "peer", "prerelease", "private", "prod", "project", "published", "registry", "root", "scanned", "scope", "score", "scripts", "semver", "sev", "severity", "shell", "shrinkwrap", "skill", "skills", "spec", "squat", "suspicious", "tracker", "trivial", "type", "undesirable", "unknown", "unmaintained", "unpopular", "unstable", "v", "vuln", "vulnerable", "workspace"];
|
|
5
5
|
export type PseudoClassName = (typeof pseudoClassNames)[number];
|
|
6
|
+
/**
|
|
7
|
+
* Part selectors: pseudo-classes that pick a part of the packages
|
|
8
|
+
* their selector matched, e.g. `:skill()`. They must end a top-level
|
|
9
|
+
* selector.
|
|
10
|
+
*/
|
|
11
|
+
export declare const partPseudoNames: readonly ["skill"];
|
|
12
|
+
export type PartPseudoName = (typeof partPseudoNames)[number];
|
|
6
13
|
/**
|
|
7
14
|
* Combinators supported by DSS.
|
|
8
15
|
*/
|
package/dist/grammar.js
CHANGED
|
@@ -53,6 +53,8 @@ export const pseudoClassNames = [
|
|
|
53
53
|
'severity',
|
|
54
54
|
'shell',
|
|
55
55
|
'shrinkwrap',
|
|
56
|
+
'skill',
|
|
57
|
+
'skills',
|
|
56
58
|
'spec',
|
|
57
59
|
'squat',
|
|
58
60
|
'suspicious',
|
|
@@ -69,6 +71,12 @@ export const pseudoClassNames = [
|
|
|
69
71
|
'vulnerable',
|
|
70
72
|
'workspace',
|
|
71
73
|
];
|
|
74
|
+
/**
|
|
75
|
+
* Part selectors: pseudo-classes that pick a part of the packages
|
|
76
|
+
* their selector matched, e.g. `:skill()`. They must end a top-level
|
|
77
|
+
* selector.
|
|
78
|
+
*/
|
|
79
|
+
export const partPseudoNames = ['skill'];
|
|
72
80
|
/**
|
|
73
81
|
* Combinators supported by DSS.
|
|
74
82
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import postcssSelectorParser from 'postcss-selector-parser';
|
|
2
2
|
import { syntaxError } from '@vltpkg/error-cause';
|
|
3
|
-
import { attributeOperatorNames, combinatorNames, pseudoClassNames, } from "./grammar.js";
|
|
3
|
+
import { attributeOperatorNames, combinatorNames, partPseudoNames, pseudoClassNames, } from "./grammar.js";
|
|
4
4
|
import { asSelectorNode, isAttributeNode, isCombinatorNode, isPseudoNode, isStringNode, isTagNode, } from "./types.js";
|
|
5
5
|
export * from "./types.js";
|
|
6
6
|
export * from "./grammar.js";
|
|
@@ -25,6 +25,7 @@ const pseudoCleanUpNeeded = new Set([
|
|
|
25
25
|
]);
|
|
26
26
|
const hasParamsToEscape = (node) => pseudoCleanUpNeeded.has(node.value);
|
|
27
27
|
const pseudoClasses = new Set(pseudoClassNames);
|
|
28
|
+
const partPseudos = new Set(partPseudoNames);
|
|
28
29
|
const combinators = new Set(combinatorNames);
|
|
29
30
|
const attributeOperators = new Set(attributeOperatorNames);
|
|
30
31
|
// pseudo-classes taking selector args, all others take strings
|
|
@@ -33,9 +34,10 @@ const invalid = (message, found) => syntaxError(message, { code: 'EQUERY', found
|
|
|
33
34
|
/**
|
|
34
35
|
* Checks a parsed selector against the DSS grammar.
|
|
35
36
|
* `forgiving`: inside `:is()`, only bare words / strings / empty
|
|
36
|
-
* `#` `[]` are rejected.
|
|
37
|
+
* `#` `[]` and part selectors are rejected.
|
|
38
|
+
* `nested`: inside `:not()`/`:is()`/`:has()` (part selectors rejected).
|
|
37
39
|
*/
|
|
38
|
-
const validate = (selector, query, forgiving = false) => {
|
|
40
|
+
const validate = (selector, query, forgiving = false, nested = false) => {
|
|
39
41
|
const nodes = selector.nodes.filter(n => n.type !== 'comment');
|
|
40
42
|
if (!nodes.length && !forgiving) {
|
|
41
43
|
throw invalid('Empty selector', query);
|
|
@@ -68,9 +70,19 @@ const validate = (selector, query, forgiving = false) => {
|
|
|
68
70
|
return;
|
|
69
71
|
throw invalid(`Unsupported pseudo-class: ${node.value}`, node.value);
|
|
70
72
|
}
|
|
73
|
+
if (partPseudos.has(name)) {
|
|
74
|
+
if (nested || i < nodes.length - 1) {
|
|
75
|
+
throw invalid(`:${name}() must end a top-level selector`, node.value);
|
|
76
|
+
}
|
|
77
|
+
// `:skill`, `:skill()`, `:skill(a,)`
|
|
78
|
+
if (!node.nodes.length ||
|
|
79
|
+
node.nodes.some(s => s.nodes.every(n => n.type === 'comment'))) {
|
|
80
|
+
throw invalid(`Missing ${name} name in :${name}()`, node.value);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
71
83
|
if (selectorPseudos.has(name)) {
|
|
72
84
|
for (const n of node.nodes) {
|
|
73
|
-
validate(asSelectorNode(n), query, forgiving || name === 'is');
|
|
85
|
+
validate(asSelectorNode(n), query, forgiving || name === 'is', true);
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
88
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vltpkg/dss-parser",
|
|
3
3
|
"description": "The Dependency Selector Syntax (DSS) parser",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/vltpkg/vltpkg.git",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"url": "http://vlt.sh"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@vltpkg/error-cause": "1.
|
|
16
|
+
"@vltpkg/error-cause": "1.5.0",
|
|
17
17
|
"postcss-selector-parser": "^7.1.1"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|