@vltpkg/query 1.0.0-rc.22 → 1.0.0-rc.24

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.
Files changed (129) hide show
  1. package/dist/attribute.d.ts +14 -0
  2. package/dist/attribute.js +132 -0
  3. package/dist/combinator.d.ts +5 -0
  4. package/dist/combinator.js +111 -0
  5. package/dist/id.d.ts +5 -0
  6. package/dist/id.js +35 -0
  7. package/dist/index.d.ts +48 -0
  8. package/dist/index.js +410 -0
  9. package/dist/parser.d.ts +14 -0
  10. package/dist/parser.js +92 -0
  11. package/dist/pseudo/abandoned.d.ts +6 -0
  12. package/dist/pseudo/abandoned.js +5 -0
  13. package/dist/pseudo/attr.d.ts +18 -0
  14. package/dist/pseudo/attr.js +57 -0
  15. package/dist/pseudo/built.d.ts +7 -0
  16. package/dist/pseudo/built.js +15 -0
  17. package/dist/pseudo/confused.d.ts +8 -0
  18. package/dist/pseudo/confused.js +18 -0
  19. package/dist/pseudo/cve.d.ts +12 -0
  20. package/dist/pseudo/cve.js +43 -0
  21. package/dist/pseudo/cwe.d.ts +12 -0
  22. package/dist/pseudo/cwe.js +42 -0
  23. package/dist/pseudo/debug.d.ts +6 -0
  24. package/dist/pseudo/debug.js +5 -0
  25. package/dist/pseudo/deprecated.d.ts +6 -0
  26. package/dist/pseudo/deprecated.js +5 -0
  27. package/dist/pseudo/dev.d.ts +5 -0
  28. package/dist/pseudo/dev.js +14 -0
  29. package/dist/pseudo/diff.d.ts +26 -0
  30. package/dist/pseudo/diff.js +75 -0
  31. package/dist/pseudo/dynamic.d.ts +6 -0
  32. package/dist/pseudo/dynamic.js +5 -0
  33. package/dist/pseudo/empty.d.ts +6 -0
  34. package/dist/pseudo/empty.js +13 -0
  35. package/dist/pseudo/entropic.d.ts +6 -0
  36. package/dist/pseudo/entropic.js +5 -0
  37. package/dist/pseudo/env.d.ts +6 -0
  38. package/dist/pseudo/env.js +5 -0
  39. package/dist/pseudo/eval.d.ts +6 -0
  40. package/dist/pseudo/eval.js +5 -0
  41. package/dist/pseudo/fs.d.ts +6 -0
  42. package/dist/pseudo/fs.js +5 -0
  43. package/dist/pseudo/helpers.d.ts +38 -0
  44. package/dist/pseudo/helpers.js +79 -0
  45. package/dist/pseudo/host.d.ts +19 -0
  46. package/dist/pseudo/host.js +79 -0
  47. package/dist/pseudo/hostname.d.ts +11 -0
  48. package/dist/pseudo/hostname.js +138 -0
  49. package/dist/pseudo/license.d.ts +12 -0
  50. package/dist/pseudo/license.js +74 -0
  51. package/dist/pseudo/link.d.ts +8 -0
  52. package/dist/pseudo/link.js +24 -0
  53. package/dist/pseudo/malware.d.ts +23 -0
  54. package/dist/pseudo/malware.js +186 -0
  55. package/dist/pseudo/minified.d.ts +6 -0
  56. package/dist/pseudo/minified.js +5 -0
  57. package/dist/pseudo/missing.d.ts +7 -0
  58. package/dist/pseudo/missing.js +14 -0
  59. package/dist/pseudo/native.d.ts +6 -0
  60. package/dist/pseudo/native.js +5 -0
  61. package/dist/pseudo/network.d.ts +6 -0
  62. package/dist/pseudo/network.js +5 -0
  63. package/dist/pseudo/obfuscated.d.ts +6 -0
  64. package/dist/pseudo/obfuscated.js +5 -0
  65. package/dist/pseudo/optional.d.ts +5 -0
  66. package/dist/pseudo/optional.js +14 -0
  67. package/dist/pseudo/outdated.d.ts +53 -0
  68. package/dist/pseudo/outdated.js +211 -0
  69. package/dist/pseudo/overridden.d.ts +7 -0
  70. package/dist/pseudo/overridden.js +16 -0
  71. package/dist/pseudo/path.d.ts +18 -0
  72. package/dist/pseudo/path.js +110 -0
  73. package/dist/pseudo/peer.d.ts +5 -0
  74. package/dist/pseudo/peer.js +14 -0
  75. package/dist/pseudo/prerelease.d.ts +17 -0
  76. package/dist/pseudo/prerelease.js +40 -0
  77. package/dist/pseudo/private.d.ts +6 -0
  78. package/dist/pseudo/private.js +15 -0
  79. package/dist/pseudo/prod.d.ts +5 -0
  80. package/dist/pseudo/prod.js +14 -0
  81. package/dist/pseudo/published.d.ts +39 -0
  82. package/dist/pseudo/published.js +179 -0
  83. package/dist/pseudo/registry.d.ts +10 -0
  84. package/dist/pseudo/registry.js +24 -0
  85. package/dist/pseudo/root.d.ts +6 -0
  86. package/dist/pseudo/root.js +17 -0
  87. package/dist/pseudo/scanned.d.ts +8 -0
  88. package/dist/pseudo/scanned.js +16 -0
  89. package/dist/pseudo/score.d.ts +15 -0
  90. package/dist/pseudo/score.js +132 -0
  91. package/dist/pseudo/scripts.d.ts +9 -0
  92. package/dist/pseudo/scripts.js +43 -0
  93. package/dist/pseudo/semver.d.ts +16 -0
  94. package/dist/pseudo/semver.js +166 -0
  95. package/dist/pseudo/severity.d.ts +14 -0
  96. package/dist/pseudo/severity.js +159 -0
  97. package/dist/pseudo/shell.d.ts +6 -0
  98. package/dist/pseudo/shell.js +5 -0
  99. package/dist/pseudo/shrinkwrap.d.ts +6 -0
  100. package/dist/pseudo/shrinkwrap.js +5 -0
  101. package/dist/pseudo/spec.d.ts +16 -0
  102. package/dist/pseudo/spec.js +101 -0
  103. package/dist/pseudo/squat.d.ts +14 -0
  104. package/dist/pseudo/squat.js +171 -0
  105. package/dist/pseudo/suspicious.d.ts +6 -0
  106. package/dist/pseudo/suspicious.js +5 -0
  107. package/dist/pseudo/tracker.d.ts +6 -0
  108. package/dist/pseudo/tracker.js +5 -0
  109. package/dist/pseudo/trivial.d.ts +6 -0
  110. package/dist/pseudo/trivial.js +5 -0
  111. package/dist/pseudo/type.d.ts +7 -0
  112. package/dist/pseudo/type.js +21 -0
  113. package/dist/pseudo/undesirable.d.ts +6 -0
  114. package/dist/pseudo/undesirable.js +5 -0
  115. package/dist/pseudo/unknown.d.ts +6 -0
  116. package/dist/pseudo/unknown.js +5 -0
  117. package/dist/pseudo/unmaintained.d.ts +6 -0
  118. package/dist/pseudo/unmaintained.js +5 -0
  119. package/dist/pseudo/unpopular.d.ts +6 -0
  120. package/dist/pseudo/unpopular.js +5 -0
  121. package/dist/pseudo/unstable.d.ts +6 -0
  122. package/dist/pseudo/unstable.js +5 -0
  123. package/dist/pseudo/workspace.d.ts +5 -0
  124. package/dist/pseudo/workspace.js +19 -0
  125. package/dist/pseudo.d.ts +5 -0
  126. package/dist/pseudo.js +366 -0
  127. package/dist/types.d.ts +124 -0
  128. package/dist/types.js +1 -0
  129. package/package.json +10 -10
@@ -0,0 +1,159 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { asPostcssNodeWithChildren, asStringNode, asTagNode, isStringNode, isTagNode, } from '@vltpkg/dss-parser';
3
+ import { assertSecurityArchive, removeDanglingEdges, removeNode, removeQuotes, } from "./helpers.js";
4
+ const kindsMap = new Map([
5
+ ['critical', 'criticalCVE'],
6
+ ['high', 'cve'],
7
+ ['medium', 'potentialVulnerability'],
8
+ ['low', 'mildCVE'],
9
+ ['0', 'criticalCVE'],
10
+ ['1', 'cve'],
11
+ ['2', 'potentialVulnerability'],
12
+ ['3', 'mildCVE'],
13
+ ]);
14
+ // Map numerical values to their respective kinds for comparison operations
15
+ const kindLevelMap = new Map([
16
+ ['critical', 0],
17
+ ['high', 1],
18
+ ['medium', 2],
19
+ ['low', 3],
20
+ ['0', 0],
21
+ ['1', 1],
22
+ ['2', 2],
23
+ ['3', 3],
24
+ ]);
25
+ const kinds = new Set(kindsMap.keys());
26
+ export const isSeverityKind = (value) => kinds.has(value);
27
+ export const asSeverityKind = (value) => {
28
+ if (!isSeverityKind(value)) {
29
+ throw error('Expected a valid severity kind', {
30
+ found: value,
31
+ validOptions: Array.from(kinds),
32
+ });
33
+ }
34
+ return value;
35
+ };
36
+ export const parseInternals = (nodes) => {
37
+ let kind;
38
+ let comparator;
39
+ if (nodes.length === 0) {
40
+ throw error('Missing severity kind parameter');
41
+ }
42
+ let kindValue = '';
43
+ if (isStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])) {
44
+ kindValue = removeQuotes(asStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])
45
+ .value);
46
+ }
47
+ else if (isTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])) {
48
+ kindValue = asTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0]).value;
49
+ }
50
+ // Extract comparator if present
51
+ if (kindValue.startsWith('>=')) {
52
+ comparator = '>=';
53
+ kindValue = kindValue.substring(2);
54
+ }
55
+ else if (kindValue.startsWith('<=')) {
56
+ comparator = '<=';
57
+ kindValue = kindValue.substring(2);
58
+ }
59
+ else if (kindValue.startsWith('>')) {
60
+ comparator = '>';
61
+ kindValue = kindValue.substring(1);
62
+ }
63
+ else if (kindValue.startsWith('<')) {
64
+ comparator = '<';
65
+ kindValue = kindValue.substring(1);
66
+ }
67
+ // Parse kind value
68
+ if (kindValue) {
69
+ if (isSeverityKind(kindValue)) {
70
+ kind = kindValue;
71
+ }
72
+ else {
73
+ throw error('Expected a valid severity kind or number between 0-3', {
74
+ found: kindValue,
75
+ });
76
+ }
77
+ }
78
+ return { kind, comparator };
79
+ };
80
+ export const severity = async (state) => {
81
+ assertSecurityArchive(state, 'severity');
82
+ let internals;
83
+ try {
84
+ internals = parseInternals(asPostcssNodeWithChildren(state.current).nodes);
85
+ }
86
+ catch (err) {
87
+ throw error('Failed to parse :severity selector', { cause: err });
88
+ }
89
+ const { kind, comparator } = internals;
90
+ for (const node of state.partial.nodes) {
91
+ const report = state.securityArchive.get(node.id);
92
+ // Always exclude nodes that don't have security data or alerts
93
+ if (!report?.alerts || report.alerts.length === 0) {
94
+ removeNode(state, node);
95
+ }
96
+ }
97
+ for (const node of state.partial.nodes) {
98
+ const report = state.securityArchive.get(node.id);
99
+ let exclude = true;
100
+ if (report) {
101
+ if (comparator) {
102
+ // retrieve the value to compare against
103
+ const kindLevel = kindLevelMap.get(kind);
104
+ // the kindLevel value has already been validated at this point
105
+ // and thus can never return an undefined/falsy value but ts doesn't
106
+ // know about that, so we have the extra check here
107
+ /* c8 ignore next - impossible */
108
+ if (!kindLevel)
109
+ break;
110
+ // Check each alert to find any that match our comparison criteria
111
+ for (const alert of report.alerts) {
112
+ // Get the numerical value of the alert type
113
+ const alertType = alert.type;
114
+ // retrieve a key to the current alert level to be compared against
115
+ const currentAlertLevelKey = [...kindsMap.entries()].find(([_, alertValue]) => alertValue === alertType)?.[0];
116
+ // perform the comparison based on the user-provided kindLevel
117
+ if (currentAlertLevelKey) {
118
+ const currentAlertLevel = kindLevelMap.get(currentAlertLevelKey);
119
+ /* c8 ignore next - impossible but ts doesn't know */
120
+ if (currentAlertLevel == null)
121
+ continue;
122
+ switch (comparator) {
123
+ case '>':
124
+ if (currentAlertLevel > kindLevel) {
125
+ exclude = false;
126
+ }
127
+ break;
128
+ case '<':
129
+ if (currentAlertLevel < kindLevel) {
130
+ exclude = false;
131
+ }
132
+ break;
133
+ case '>=':
134
+ if (currentAlertLevel >= kindLevel) {
135
+ exclude = false;
136
+ }
137
+ break;
138
+ case '<=':
139
+ if (currentAlertLevel <= kindLevel) {
140
+ exclude = false;
141
+ }
142
+ break;
143
+ }
144
+ }
145
+ }
146
+ }
147
+ else {
148
+ // Original exact match behavior
149
+ const alertName = kindsMap.get(kind);
150
+ exclude = !report.alerts.some(alert => alert.type === alertName);
151
+ }
152
+ }
153
+ if (exclude) {
154
+ removeNode(state, node);
155
+ }
156
+ }
157
+ removeDanglingEdges(state);
158
+ return state;
159
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **shellAccess** report alert.
3
+ */
4
+ export declare const shell: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **shellAccess** report alert.
4
+ */
5
+ export const shell = createSecuritySelectorFilter('shell', 'shellAccess');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **shrinkwrap** report alert.
3
+ */
4
+ export declare const shrinkwrap: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **shrinkwrap** report alert.
4
+ */
5
+ export const shrinkwrap = createSecuritySelectorFilter('shrinkwrap', 'shrinkwrap');
@@ -0,0 +1,16 @@
1
+ import type { ParserState } from '../types.ts';
2
+ import type { PostcssNode } from '@vltpkg/dss-parser';
3
+ export type SpecInternals = {
4
+ specValue: string;
5
+ };
6
+ export declare const parseInternals: (nodes: PostcssNode[]) => SpecInternals;
7
+ /**
8
+ * :spec Pseudo-Selector, matches edges where edge.spec.bareSpec equals the provided value.
9
+ *
10
+ * Examples:
11
+ * - :spec("*") matches edges with a package specifier equal to "*"
12
+ * - :spec(^1.0.0) matches edges with a package specifier equal to "^1.0.0"
13
+ * - :spec("catalog:") matches edges with a package specifier equal to "catalog:"
14
+ * - :spec("workspace:dev") matches edges with a package specifier equal to "workspace:dev"
15
+ */
16
+ export declare const spec: (state: ParserState) => Promise<ParserState>;
@@ -0,0 +1,101 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { asError } from '@vltpkg/types';
3
+ import { asPostcssNodeWithChildren, asStringNode, asTagNode, isTagNode, } from '@vltpkg/dss-parser';
4
+ import { removeEdge, removeUnlinkedNodes, removeQuotes, } from "./helpers.js";
5
+ export const parseInternals = (nodes) => {
6
+ // tries to parse the first param as a string node, otherwise defaults
7
+ // to reading all postcss nodes as just strings, since it just means
8
+ // the value was defined as an unquoted string
9
+ let specValue = '';
10
+ if (nodes.length === 0) {
11
+ throw new Error('No nodes provided to parseInternals');
12
+ }
13
+ const firstNode = asPostcssNodeWithChildren(nodes[0]);
14
+ if (firstNode.nodes.length === 0) {
15
+ throw new Error('First node has no child nodes');
16
+ }
17
+ // Try to parse as a quoted string first (single string node)
18
+ if (firstNode.nodes.length === 1) {
19
+ const targetNode = firstNode.nodes[0];
20
+ try {
21
+ specValue = removeQuotes(asStringNode(targetNode).value);
22
+ return { specValue };
23
+ }
24
+ catch (err) {
25
+ if (asError(err).message === 'Mismatching query node' &&
26
+ isTagNode(targetNode)
27
+ /* c8 ignore start */
28
+ ) {
29
+ // Handle simple unquoted single-token values like "1"
30
+ const tagNode = asTagNode(targetNode);
31
+ specValue = tagNode.value;
32
+ return { specValue };
33
+ /* c8 ignore stop */
34
+ }
35
+ else {
36
+ throw err;
37
+ }
38
+ }
39
+ }
40
+ // Handle unquoted complex values that get parsed into multiple nodes
41
+ // This happens when unquoted values contain dots, like ^1.0.0 which becomes:
42
+ // - Tag: "^1"
43
+ // - ClassName: "0" (from .0)
44
+ // - ClassName: "0" (from .0)
45
+ // We need to reconstruct the original value by concatenating all nodes
46
+ const parts = [];
47
+ for (const node of firstNode.nodes) {
48
+ switch (node.type) {
49
+ case 'tag':
50
+ parts.push(asTagNode(node).value);
51
+ break;
52
+ case 'class':
53
+ // Class nodes represent .className in CSS, so we need to add the dot back
54
+ parts.push('.' + node.value);
55
+ break;
56
+ case 'id':
57
+ // ID nodes represent #idName in CSS, so we need to add the hash back
58
+ parts.push('#' + node.value);
59
+ break;
60
+ case 'string':
61
+ parts.push(removeQuotes(asStringNode(node).value));
62
+ break;
63
+ default:
64
+ // For other node types, try to get the value property or convert to string
65
+ /* c8 ignore next */
66
+ parts.push(node.value ?? String(node));
67
+ break;
68
+ }
69
+ }
70
+ specValue = parts.join('');
71
+ return { specValue };
72
+ };
73
+ /**
74
+ * :spec Pseudo-Selector, matches edges where edge.spec.bareSpec equals the provided value.
75
+ *
76
+ * Examples:
77
+ * - :spec("*") matches edges with a package specifier equal to "*"
78
+ * - :spec(^1.0.0) matches edges with a package specifier equal to "^1.0.0"
79
+ * - :spec("catalog:") matches edges with a package specifier equal to "catalog:"
80
+ * - :spec("workspace:dev") matches edges with a package specifier equal to "workspace:dev"
81
+ */
82
+ export const spec = async (state) => {
83
+ let internals;
84
+ try {
85
+ internals = parseInternals(asPostcssNodeWithChildren(state.current).nodes);
86
+ }
87
+ catch (err) {
88
+ throw error('Failed to parse :spec selector', {
89
+ cause: err,
90
+ });
91
+ }
92
+ const { specValue } = internals;
93
+ for (const edge of state.partial.edges) {
94
+ if (edge.spec.bareSpec !== specValue) {
95
+ removeEdge(state, edge);
96
+ }
97
+ }
98
+ // Clean up unlinked nodes after removing edges
99
+ removeUnlinkedNodes(state);
100
+ return state;
101
+ };
@@ -0,0 +1,14 @@
1
+ import type { ParserState } from '../types.ts';
2
+ import type { PostcssNode } from '@vltpkg/dss-parser';
3
+ export type SquatKinds = '0' | '2' | 'critical' | 'medium' | undefined;
4
+ export type SquatAlertTypes = 'didYouMean' | 'gptDidYouMean' | undefined;
5
+ export type SquatComparator = '>' | '<' | '>=' | '<=' | undefined;
6
+ export declare const isSquatKind: (value?: string) => value is SquatKinds;
7
+ export declare const asSquatKind: (value?: string) => SquatKinds;
8
+ export declare const parseInternals: (nodes: PostcssNode[]) => {
9
+ kind: SquatKinds;
10
+ comparator: SquatComparator;
11
+ };
12
+ export declare const squat: (state: ParserState) => Promise<ParserState & {
13
+ securityArchive: NonNullable<ParserState["securityArchive"]>;
14
+ }>;
@@ -0,0 +1,171 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { asError } from '@vltpkg/types';
3
+ import { asPostcssNodeWithChildren, asStringNode, asTagNode, isStringNode, isTagNode, } from '@vltpkg/dss-parser';
4
+ import { assertSecurityArchive, removeDanglingEdges, removeNode, removeQuotes, } from "./helpers.js";
5
+ const kindsMap = new Map([
6
+ ['critical', 'didYouMean'],
7
+ ['medium', 'gptDidYouMean'],
8
+ ['0', 'didYouMean'],
9
+ ['2', 'gptDidYouMean'],
10
+ [undefined, undefined],
11
+ ]);
12
+ // Map numerical values to their respective kinds for comparison operations
13
+ const kindLevelMap = new Map([
14
+ ['critical', 0],
15
+ ['medium', 2],
16
+ ['0', 0],
17
+ ['2', 2],
18
+ ]);
19
+ const kinds = new Set(kindsMap.keys());
20
+ export const isSquatKind = (value) => kinds.has(value);
21
+ export const asSquatKind = (value) => {
22
+ if (!isSquatKind(value)) {
23
+ throw error('Expected a valid squat kind', {
24
+ found: value,
25
+ validOptions: Array.from(kinds),
26
+ });
27
+ }
28
+ return value;
29
+ };
30
+ export const parseInternals = (nodes) => {
31
+ let kind;
32
+ let comparator;
33
+ let kindValue = '';
34
+ if (isStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])) {
35
+ kindValue = removeQuotes(asStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])
36
+ .value);
37
+ }
38
+ else if (isTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])) {
39
+ kindValue = asTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0]).value;
40
+ }
41
+ // Extract comparator if present
42
+ if (kindValue.startsWith('>=')) {
43
+ comparator = '>=';
44
+ kindValue = kindValue.substring(2);
45
+ }
46
+ else if (kindValue.startsWith('<=')) {
47
+ comparator = '<=';
48
+ kindValue = kindValue.substring(2);
49
+ }
50
+ else if (kindValue.startsWith('>')) {
51
+ comparator = '>';
52
+ kindValue = kindValue.substring(1);
53
+ }
54
+ else if (kindValue.startsWith('<')) {
55
+ comparator = '<';
56
+ kindValue = kindValue.substring(1);
57
+ }
58
+ // Parse kind value
59
+ if (kindValue) {
60
+ if (isSquatKind(kindValue)) {
61
+ kind = kindValue;
62
+ }
63
+ else {
64
+ throw error('Expected a valid squat kind for comparison', {
65
+ found: kindValue,
66
+ validOptions: Array.from(kinds),
67
+ });
68
+ }
69
+ }
70
+ return { kind, comparator };
71
+ };
72
+ export const squat = async (state) => {
73
+ assertSecurityArchive(state, 'squat');
74
+ let internals;
75
+ try {
76
+ internals = parseInternals(asPostcssNodeWithChildren(state.current).nodes);
77
+ }
78
+ catch (err) {
79
+ if (asError(err).message === 'Expected a query node') {
80
+ // No parameters provided - pseudo state form: match ANY squat level
81
+ internals = { kind: undefined, comparator: undefined };
82
+ }
83
+ else {
84
+ throw error('Failed to parse :squat selector', { cause: err });
85
+ }
86
+ }
87
+ const { kind, comparator } = internals;
88
+ // First pass: Remove nodes without security data
89
+ for (const node of state.partial.nodes) {
90
+ const report = state.securityArchive.get(node.id);
91
+ // Always exclude nodes that don't have security data or alerts
92
+ if (!report?.alerts || report.alerts.length === 0) {
93
+ removeNode(state, node);
94
+ }
95
+ }
96
+ // Second pass: Apply comparison filtering
97
+ for (const node of state.partial.nodes) {
98
+ const report = state.securityArchive.get(node.id);
99
+ // Skip if report is undefined
100
+ // (should never happen since we filtered above)
101
+ /* c8 ignore next - impossible */
102
+ if (!report)
103
+ continue;
104
+ // At this point we know report exists and has alerts
105
+ let exclude = true;
106
+ if (kind === undefined && comparator === undefined) {
107
+ // Pseudo state form: match ANY squat level
108
+ exclude = !report.alerts.some(alert => [...kindsMap.values()].includes(alert.type));
109
+ }
110
+ else if (comparator) {
111
+ // Get the value to compare against
112
+ const kindLevel = kindLevelMap.get(kind);
113
+ /* c8 ignore next - impossible */
114
+ if (kindLevel === undefined)
115
+ break;
116
+ // For each alert, check if it matches the comparison criteria
117
+ let matchesComparison = false;
118
+ for (const alert of report.alerts) {
119
+ // Get the alert type
120
+ const alertType = alert.type;
121
+ // Find the corresponding kind for this alert type
122
+ const alertLevelKey = [...kindsMap.entries()].find(([_, value]) => value === alertType)?.[0];
123
+ if (alertLevelKey) {
124
+ // Get the numeric level for this alert
125
+ const alertLevel = kindLevelMap.get(alertLevelKey);
126
+ /* c8 ignore next - impossible */
127
+ if (alertLevel === undefined)
128
+ continue;
129
+ // Apply the comparison based on the comparator
130
+ switch (comparator) {
131
+ case '>':
132
+ if (alertLevel > kindLevel) {
133
+ matchesComparison = true;
134
+ }
135
+ break;
136
+ case '<':
137
+ if (alertLevel < kindLevel) {
138
+ matchesComparison = true;
139
+ }
140
+ break;
141
+ case '>=':
142
+ if (alertLevel >= kindLevel) {
143
+ matchesComparison = true;
144
+ }
145
+ break;
146
+ case '<=':
147
+ if (alertLevel <= kindLevel) {
148
+ matchesComparison = true;
149
+ }
150
+ break;
151
+ }
152
+ // If we found a match, we can stop checking other alerts
153
+ if (matchesComparison)
154
+ break;
155
+ }
156
+ }
157
+ // Exclude the node if it doesn't match the comparison
158
+ exclude = !matchesComparison;
159
+ }
160
+ else {
161
+ // Original exact match behavior
162
+ const alertName = kindsMap.get(kind);
163
+ exclude = !report.alerts.some(alert => alert.type === alertName);
164
+ }
165
+ if (exclude) {
166
+ removeNode(state, node);
167
+ }
168
+ }
169
+ removeDanglingEdges(state);
170
+ return state;
171
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **suspiciousStarActivity** report alert.
3
+ */
4
+ export declare const suspicious: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **suspiciousStarActivity** report alert.
4
+ */
5
+ export const suspicious = createSecuritySelectorFilter('suspicious', 'suspiciousStarActivity');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **telemetry** report alert.
3
+ */
4
+ export declare const tracker: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **telemetry** report alert.
4
+ */
5
+ export const tracker = createSecuritySelectorFilter('tracker', 'telemetry');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **trivialPackage** report alert.
3
+ */
4
+ export declare const trivial: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **trivialPackage** report alert.
4
+ */
5
+ export const trivial = createSecuritySelectorFilter('trivial', 'trivialPackage');
@@ -0,0 +1,7 @@
1
+ import type { ParserState } from '../types.ts';
2
+ /**
3
+ * :type(str) Pseudo-Element will match only nodes that are of
4
+ * the same type as the value used. The type is determined by the
5
+ * first part of the dependency ID.
6
+ */
7
+ export declare const type: (state: ParserState) => Promise<ParserState>;
@@ -0,0 +1,21 @@
1
+ import { splitDepID } from '@vltpkg/dep-id/browser';
2
+ import { asPostcssNodeWithChildren, asTagNode, } from '@vltpkg/dss-parser';
3
+ import { removeDanglingEdges, removeNode } from "./helpers.js";
4
+ /**
5
+ * :type(str) Pseudo-Element will match only nodes that are of
6
+ * the same type as the value used. The type is determined by the
7
+ * first part of the dependency ID.
8
+ */
9
+ export const type = async (state) => {
10
+ const type = asPostcssNodeWithChildren(state.current);
11
+ const selector = asPostcssNodeWithChildren(type.nodes[0]);
12
+ const name = asTagNode(selector.nodes[0]).value;
13
+ for (const node of state.partial.nodes) {
14
+ const nodeType = splitDepID(node.id)[0];
15
+ if (nodeType !== name) {
16
+ removeNode(state, node);
17
+ }
18
+ }
19
+ removeDanglingEdges(state);
20
+ return state;
21
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **troll** report alert.
3
+ */
4
+ export declare const undesirable: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **troll** report alert.
4
+ */
5
+ export const undesirable = createSecuritySelectorFilter('undesirable', 'troll');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **newAuthor** report alert.
3
+ */
4
+ export declare const unknown: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **newAuthor** report alert.
4
+ */
5
+ export const unknown = createSecuritySelectorFilter('unknown', 'newAuthor');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **unmaintained** report alert.
3
+ */
4
+ export declare const unmaintained: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **unmaintained** report alert.
4
+ */
5
+ export const unmaintained = createSecuritySelectorFilter('unmaintained', 'unmaintained');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **unpopularPackage** report alert.
3
+ */
4
+ export declare const unpopular: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **unpopularPackage** report alert.
4
+ */
5
+ export const unpopular = createSecuritySelectorFilter('unpopular', 'unpopularPackage');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Filters out any node that does not have a **unstableOwnership** report alert.
3
+ */
4
+ export declare const unstable: (state: import("../types.ts").ParserState) => Promise<import("../types.ts").ParserState & {
5
+ securityArchive: NonNullable<import("../types.ts").ParserState["securityArchive"]>;
6
+ }>;
@@ -0,0 +1,5 @@
1
+ import { createSecuritySelectorFilter } from "./helpers.js";
2
+ /**
3
+ * Filters out any node that does not have a **unstableOwnership** report alert.
4
+ */
5
+ export const unstable = createSecuritySelectorFilter('unstable', 'unstableOwnership');
@@ -0,0 +1,5 @@
1
+ import type { ParserState } from '../types.ts';
2
+ /**
3
+ * :workspace Pseudo-Selector will only match workspace dependencies.
4
+ */
5
+ export declare const workspace: (state: ParserState) => Promise<ParserState>;