@vltpkg/query 1.5.0 → 1.6.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.
Files changed (210) hide show
  1. package/package.json +10 -12
  2. package/skills/dss-query/REFERENCE.md +0 -125
  3. package/skills/dss-query/SKILL.md +0 -190
  4. package/skills/dss-query/evals/README.md +0 -81
  5. package/skills/dss-query/evals/evals.json +0 -89
  6. package/skills/dss-query/evals/grade.mjs +0 -481
  7. package/src/attribute.ts +0 -190
  8. package/src/combinator.ts +0 -135
  9. package/src/error.ts +0 -78
  10. package/src/id.ts +0 -46
  11. package/src/index.ts +0 -670
  12. package/src/parser.ts +0 -122
  13. package/src/pseudo/abandoned.ts +0 -9
  14. package/src/pseudo/attr.ts +0 -92
  15. package/src/pseudo/built.ts +0 -19
  16. package/src/pseudo/confused.ts +0 -29
  17. package/src/pseudo/cve.ts +0 -93
  18. package/src/pseudo/cwe.ts +0 -97
  19. package/src/pseudo/debug.ts +0 -9
  20. package/src/pseudo/deprecated.ts +0 -9
  21. package/src/pseudo/dev.ts +0 -18
  22. package/src/pseudo/diff.ts +0 -90
  23. package/src/pseudo/dist.ts +0 -148
  24. package/src/pseudo/dynamic.ts +0 -9
  25. package/src/pseudo/empty.ts +0 -15
  26. package/src/pseudo/entropic.ts +0 -9
  27. package/src/pseudo/env.ts +0 -6
  28. package/src/pseudo/eval.ts +0 -9
  29. package/src/pseudo/fs.ts +0 -9
  30. package/src/pseudo/helpers.ts +0 -106
  31. package/src/pseudo/host.ts +0 -111
  32. package/src/pseudo/hostname.ts +0 -156
  33. package/src/pseudo/license.ts +0 -134
  34. package/src/pseudo/link.ts +0 -30
  35. package/src/pseudo/malware.ts +0 -41
  36. package/src/pseudo/minified.ts +0 -9
  37. package/src/pseudo/missing.ts +0 -16
  38. package/src/pseudo/native.ts +0 -9
  39. package/src/pseudo/network.ts +0 -9
  40. package/src/pseudo/obfuscated.ts +0 -9
  41. package/src/pseudo/optional.ts +0 -18
  42. package/src/pseudo/outdated.ts +0 -345
  43. package/src/pseudo/overridden.ts +0 -20
  44. package/src/pseudo/path.ts +0 -146
  45. package/src/pseudo/peer.ts +0 -18
  46. package/src/pseudo/prerelease.ts +0 -47
  47. package/src/pseudo/private.ts +0 -19
  48. package/src/pseudo/prod.ts +0 -18
  49. package/src/pseudo/published.ts +0 -250
  50. package/src/pseudo/registry.ts +0 -29
  51. package/src/pseudo/root.ts +0 -19
  52. package/src/pseudo/scanned.ts +0 -20
  53. package/src/pseudo/score.ts +0 -186
  54. package/src/pseudo/scripts.ts +0 -61
  55. package/src/pseudo/semver.ts +0 -320
  56. package/src/pseudo/severity.ts +0 -231
  57. package/src/pseudo/shell.ts +0 -9
  58. package/src/pseudo/shrinkwrap.ts +0 -9
  59. package/src/pseudo/skill.ts +0 -59
  60. package/src/pseudo/skills.ts +0 -29
  61. package/src/pseudo/spec.ts +0 -131
  62. package/src/pseudo/squat.ts +0 -225
  63. package/src/pseudo/suspicious.ts +0 -9
  64. package/src/pseudo/tracker.ts +0 -9
  65. package/src/pseudo/trivial.ts +0 -9
  66. package/src/pseudo/type.ts +0 -26
  67. package/src/pseudo/undesirable.ts +0 -9
  68. package/src/pseudo/unknown.ts +0 -9
  69. package/src/pseudo/unmaintained.ts +0 -9
  70. package/src/pseudo/unpopular.ts +0 -9
  71. package/src/pseudo/unstable.ts +0 -9
  72. package/src/pseudo/vuln.ts +0 -273
  73. package/src/pseudo/workspace.ts +0 -22
  74. package/src/pseudo.ts +0 -440
  75. package/src/types.ts +0 -206
  76. package/tap-snapshots/test/attribute.ts.test.cjs +0 -304
  77. package/tap-snapshots/test/combinator.ts.test.cjs +0 -333
  78. package/tap-snapshots/test/id.ts.test.cjs +0 -118
  79. package/tap-snapshots/test/parser.ts.test.cjs +0 -344
  80. package/tap-snapshots/test/pseudo/abandoned.ts.test.cjs +0 -18
  81. package/tap-snapshots/test/pseudo/attr.ts.test.cjs +0 -161
  82. package/tap-snapshots/test/pseudo/built.ts.test.cjs +0 -70
  83. package/tap-snapshots/test/pseudo/confused.ts.test.cjs +0 -32
  84. package/tap-snapshots/test/pseudo/cve.ts.test.cjs +0 -49
  85. package/tap-snapshots/test/pseudo/cwe.ts.test.cjs +0 -49
  86. package/tap-snapshots/test/pseudo/debug.ts.test.cjs +0 -18
  87. package/tap-snapshots/test/pseudo/deprecated.ts.test.cjs +0 -18
  88. package/tap-snapshots/test/pseudo/dist.ts.test.cjs +0 -30
  89. package/tap-snapshots/test/pseudo/dynamic.ts.test.cjs +0 -18
  90. package/tap-snapshots/test/pseudo/empty.ts.test.cjs +0 -50
  91. package/tap-snapshots/test/pseudo/entropic.ts.test.cjs +0 -18
  92. package/tap-snapshots/test/pseudo/env.ts.test.cjs +0 -18
  93. package/tap-snapshots/test/pseudo/eval.ts.test.cjs +0 -18
  94. package/tap-snapshots/test/pseudo/fs.ts.test.cjs +0 -18
  95. package/tap-snapshots/test/pseudo/helpers.ts.test.cjs +0 -18
  96. package/tap-snapshots/test/pseudo/hostname.ts.test.cjs +0 -148
  97. package/tap-snapshots/test/pseudo/license.ts.test.cjs +0 -41
  98. package/tap-snapshots/test/pseudo/link.ts.test.cjs +0 -36
  99. package/tap-snapshots/test/pseudo/malware.ts.test.cjs +0 -22
  100. package/tap-snapshots/test/pseudo/minified.ts.test.cjs +0 -18
  101. package/tap-snapshots/test/pseudo/missing.ts.test.cjs +0 -30
  102. package/tap-snapshots/test/pseudo/native.ts.test.cjs +0 -18
  103. package/tap-snapshots/test/pseudo/network.ts.test.cjs +0 -18
  104. package/tap-snapshots/test/pseudo/obfuscated.ts.test.cjs +0 -18
  105. package/tap-snapshots/test/pseudo/outdated.ts.test.cjs +0 -132
  106. package/tap-snapshots/test/pseudo/overridden.ts.test.cjs +0 -75
  107. package/tap-snapshots/test/pseudo/prerelease.ts.test.cjs +0 -101
  108. package/tap-snapshots/test/pseudo/private.ts.test.cjs +0 -38
  109. package/tap-snapshots/test/pseudo/published.ts.test.cjs +0 -171
  110. package/tap-snapshots/test/pseudo/registry.ts.test.cjs +0 -68
  111. package/tap-snapshots/test/pseudo/root.ts.test.cjs +0 -24
  112. package/tap-snapshots/test/pseudo/scanned.ts.test.cjs +0 -18
  113. package/tap-snapshots/test/pseudo/score.ts.test.cjs +0 -239
  114. package/tap-snapshots/test/pseudo/scripts.ts.test.cjs +0 -62
  115. package/tap-snapshots/test/pseudo/semver.ts.test.cjs +0 -575
  116. package/tap-snapshots/test/pseudo/severity.ts.test.cjs +0 -122
  117. package/tap-snapshots/test/pseudo/shell.ts.test.cjs +0 -18
  118. package/tap-snapshots/test/pseudo/shrinkwrap.ts.test.cjs +0 -18
  119. package/tap-snapshots/test/pseudo/skills.ts.test.cjs +0 -19
  120. package/tap-snapshots/test/pseudo/spec.ts.test.cjs +0 -148
  121. package/tap-snapshots/test/pseudo/squat.ts.test.cjs +0 -129
  122. package/tap-snapshots/test/pseudo/suspicious.ts.test.cjs +0 -18
  123. package/tap-snapshots/test/pseudo/tracker.ts.test.cjs +0 -18
  124. package/tap-snapshots/test/pseudo/trivial.ts.test.cjs +0 -18
  125. package/tap-snapshots/test/pseudo/type.ts.test.cjs +0 -51
  126. package/tap-snapshots/test/pseudo/undesirable.ts.test.cjs +0 -18
  127. package/tap-snapshots/test/pseudo/unknown.ts.test.cjs +0 -18
  128. package/tap-snapshots/test/pseudo/unmaintained.ts.test.cjs +0 -18
  129. package/tap-snapshots/test/pseudo/unpopular.ts.test.cjs +0 -18
  130. package/tap-snapshots/test/pseudo/unstable.ts.test.cjs +0 -18
  131. package/tap-snapshots/test/pseudo/vuln.ts.test.cjs +0 -208
  132. package/tap-snapshots/test/pseudo/vulnerable.ts.test.cjs +0 -20
  133. package/tap-snapshots/test/pseudo/workspace.ts.test.cjs +0 -19
  134. package/tap-snapshots/test/pseudo.ts.test.cjs +0 -1247
  135. package/test/attribute.ts +0 -273
  136. package/test/combinator.ts +0 -175
  137. package/test/error.ts +0 -60
  138. package/test/fixtures/graph.ts +0 -999
  139. package/test/fixtures/selector.ts +0 -103
  140. package/test/fixtures/types.ts +0 -7
  141. package/test/id.ts +0 -102
  142. package/test/index.ts +0 -1148
  143. package/test/parser.ts +0 -117
  144. package/test/pseudo/abandoned.ts +0 -98
  145. package/test/pseudo/attr.ts +0 -298
  146. package/test/pseudo/built.ts +0 -214
  147. package/test/pseudo/confused.ts +0 -160
  148. package/test/pseudo/cve.ts +0 -249
  149. package/test/pseudo/cwe.ts +0 -255
  150. package/test/pseudo/debug.ts +0 -98
  151. package/test/pseudo/deprecated.ts +0 -98
  152. package/test/pseudo/dev.ts +0 -61
  153. package/test/pseudo/diff.ts +0 -417
  154. package/test/pseudo/dist.ts +0 -215
  155. package/test/pseudo/dynamic.ts +0 -98
  156. package/test/pseudo/empty.ts +0 -108
  157. package/test/pseudo/entropic.ts +0 -101
  158. package/test/pseudo/env.ts +0 -98
  159. package/test/pseudo/eval.ts +0 -98
  160. package/test/pseudo/fs.ts +0 -98
  161. package/test/pseudo/helpers.ts +0 -370
  162. package/test/pseudo/host-context.ts +0 -276
  163. package/test/pseudo/hostname.ts +0 -314
  164. package/test/pseudo/license.ts +0 -265
  165. package/test/pseudo/link.ts +0 -94
  166. package/test/pseudo/malware.ts +0 -184
  167. package/test/pseudo/minified.ts +0 -98
  168. package/test/pseudo/missing.ts +0 -111
  169. package/test/pseudo/native.ts +0 -98
  170. package/test/pseudo/network.ts +0 -98
  171. package/test/pseudo/obfuscated.ts +0 -98
  172. package/test/pseudo/optional.ts +0 -73
  173. package/test/pseudo/outdated.ts +0 -461
  174. package/test/pseudo/overridden.ts +0 -317
  175. package/test/pseudo/path.ts +0 -680
  176. package/test/pseudo/peer.ts +0 -101
  177. package/test/pseudo/prerelease.ts +0 -279
  178. package/test/pseudo/private.ts +0 -108
  179. package/test/pseudo/prod.ts +0 -61
  180. package/test/pseudo/published.ts +0 -557
  181. package/test/pseudo/registry.ts +0 -122
  182. package/test/pseudo/root.ts +0 -66
  183. package/test/pseudo/scanned.ts +0 -144
  184. package/test/pseudo/score.ts +0 -591
  185. package/test/pseudo/scripts.ts +0 -324
  186. package/test/pseudo/semver.ts +0 -822
  187. package/test/pseudo/severity.ts +0 -342
  188. package/test/pseudo/shell.ts +0 -98
  189. package/test/pseudo/shrinkwrap.ts +0 -98
  190. package/test/pseudo/skill.ts +0 -189
  191. package/test/pseudo/skills.ts +0 -90
  192. package/test/pseudo/spec.ts +0 -525
  193. package/test/pseudo/squat.ts +0 -565
  194. package/test/pseudo/suspicious.ts +0 -98
  195. package/test/pseudo/tracker.ts +0 -98
  196. package/test/pseudo/trivial.ts +0 -98
  197. package/test/pseudo/type.ts +0 -105
  198. package/test/pseudo/undesirable.ts +0 -98
  199. package/test/pseudo/unknown.ts +0 -98
  200. package/test/pseudo/unmaintained.ts +0 -98
  201. package/test/pseudo/unpopular.ts +0 -98
  202. package/test/pseudo/unstable.ts +0 -98
  203. package/test/pseudo/vuln.ts +0 -625
  204. package/test/pseudo/vulnerable.ts +0 -137
  205. package/test/pseudo/workspace.ts +0 -111
  206. package/test/pseudo.ts +0 -584
  207. package/tsconfig.json +0 -3
  208. package/tsconfig.publish.json +0 -19
  209. package/tsconfig.publish.tsbuildinfo +0 -1
  210. package/typedoc.mjs +0 -2
package/test/pseudo.ts DELETED
@@ -1,584 +0,0 @@
1
- import t from 'tap'
2
- import { joinDepIDTuple } from '@vltpkg/dep-id'
3
- import { pseudoClassNames } from '@vltpkg/dss-parser'
4
- import { pseudo, pseudoSelectorNames } from '../src/pseudo.ts'
5
- import {
6
- getCycleGraph,
7
- getMissingManifestsGraph,
8
- getMissingNodeGraph,
9
- getMultiWorkspaceGraph,
10
- getSimpleGraph,
11
- getSingleWorkspaceGraph,
12
- getPathBasedGraph,
13
- } from './fixtures/graph.ts'
14
- import {
15
- copyGraphSelectionState,
16
- getGraphSelectionState,
17
- selectorFixture,
18
- } from './fixtures/selector.ts'
19
- import type { PostcssNodeWithChildren } from '@vltpkg/dss-parser'
20
- import type { TestCase } from './fixtures/types.ts'
21
- import type {
22
- GraphSelectionState,
23
- ParserState,
24
- } from '../src/types.ts'
25
-
26
- const testPseudo = selectorFixture(pseudo)
27
-
28
- t.test('pseudo', async t => {
29
- const simpleGraph = getSimpleGraph()
30
- const all = {
31
- edges: new Set(simpleGraph.edges),
32
- nodes: new Set(simpleGraph.nodes.values()),
33
- }
34
- const a = getGraphSelectionState(simpleGraph, 'a')
35
- const b = getGraphSelectionState(simpleGraph, 'b')
36
- const d = getGraphSelectionState(simpleGraph, 'd')
37
- const empty: GraphSelectionState = {
38
- edges: new Set(),
39
- nodes: new Set(),
40
- }
41
- const queryToExpected = new Set<TestCase>([
42
- [':root', all, ['my-project']], // from initial nodes
43
- [':root', empty, []], // from empty nodes
44
- [':root', b, []], // from diff node
45
- [':project /*all*/', all, ['my-project']], // no workspaces in graph
46
- [':project /*empty*/', empty, []], // from empty nodes
47
- [':project /*b*/', b, []], // from diff node
48
- [':scope', all, ['my-project']], // :scope refers to the initial values from initial
49
- [':scope', b, []], // :scope resets the initial values from a partial
50
- [':scope', empty, []], // :scope resets the initial values from empty partial
51
- // :attr selector
52
- [':attr([scripts])', all, ['b']], // prop lookup only
53
- [':attr([scripts])', b, ['b']], // start with a single node
54
- [':attr([scripts])', a, []], // unmatching single node
55
- [':attr([scripts])', empty, []], // starting from empty
56
- [':attr([bolinha])', all, []], // missing property
57
- [':attr(a, e, [bolinha])', all, []], // fail to match something in an array of strings
58
- [':attr(a, e, [bar])', all, []], // attr key can not match array items
59
- [':attr(a, [e])', all, ['d']], // match something in an array of strings
60
- [':attr(a, [e=bar])', all, ['d']], // match something in an array of strings
61
- [':attr(a, [e=foo])', all, ['d']], // match something in an array of strings
62
- [':attr([keywords=something])', all, ['c']], // match something in an array of strings
63
- [':attr([keywords=missing])', all, []], // can not match missing item in array
64
- [':attr(a, [e=baz])', all, []], // match something missing in an array of strings
65
- [':attr(foo, bar, [baz])', all, []], // multiple missing properties
66
- [':attr(scripts, [baz])', all, []], // mixed missing properties
67
- [':attr(scripts, bar, [baz])', all, []], // mixed missing properties
68
- [':attr(scripts, [postinstall])', all, ['b']], // nested prop
69
- [':attr(scripts, [test=test])', all, ['b']], // nested prop match
70
- [':attr(contributors, [name^=Ruy])', all, ['b']], // nested array
71
- [
72
- ':attr(contributors, [email=ruyadorno@example.com])',
73
- all,
74
- ['b'],
75
- ],
76
- [':attr([peerDependenciesMeta])', all, ['c']],
77
- [':attr(peerDependenciesMeta, [foo])', all, ['c']],
78
- [':attr(peerDependenciesMeta, foo, [optional])', all, ['c']], // 2-lvls
79
- [':attr(peerDependenciesMeta, foo, [optional=true])', all, ['c']],
80
- [':attr([a])', all, ['d']], // nested props start
81
- [':attr(a, [b])', all, ['d']], // nested props
82
- [':attr(a, b, [c])', all, ['d']], // nested props within array
83
- [':attr(a, b, c, [d])', all, ['d']], // nested props within array
84
- [':attr(a, b, c, [d=foo])', all, ['d']], // nested props within array
85
- [':attr(a, b, c, [d=bar])', all, ['d']], // nested props within array
86
- [
87
- ':attr([name])',
88
- all,
89
- ['my-project', 'a', 'b', 'c', 'd', 'e', 'f', '@x/y'],
90
- ], // nested props within array
91
- [
92
- ':attr([version^=1])',
93
- all,
94
- ['my-project', 'a', 'c', 'd', 'e', 'f', '@x/y'],
95
- ], // nested props within array
96
- [':empty', all, ['a', 'c', 'e', 'f', '@x/y']], // deps with no deps
97
- [':empty', a, ['a']], // single :empty item
98
- [':empty', b, []], // single not :empty item
99
- [':empty', empty, []], // no items to filter
100
- [':has(*)', all, ['my-project', 'b', 'd']], // has any sub selector matches, e.g: children
101
- [':has(*)', b, ['b']], // has any sub selector matches, e.g: children
102
- [':has(> *)', all, ['my-project', 'b', 'd']], // has any sub selector matches, e.g: children
103
- [':has(> *)', b, ['b']], // has any sub selector matches, e.g: children
104
- [':has([name=e])', all, ['my-project', 'd']], // has any sub selector matches, e.g: children
105
- [':has(* [name=e])', all, ['my-project', 'd']], // has any sub selector matches, e.g: children
106
- [':has(* > [name=e])', all, ['my-project', 'd']], // has any sub selector matches, e.g: children
107
- [':has(* > * > [name=f])', all, ['d']], // has any sub selector matches, e.g: children
108
- [':has([name=c], [name=f])', all, ['b', 'd']], // multi sub selectors
109
- [':has([name=c], [name=f])', b, ['b']], // multi sub selectors, selecting from single item
110
- [':has([name=c], [name=f])', empty, []], // multi sub selectors, selecting from no item
111
- [':has(*[nonexistingattribute])', all, []], // nothing to match
112
- [':has(~ :attr([peerDependenciesMeta]))', all, ['b']], // has any sub selector matches, e.g: children
113
- [':has(:attr([scripts]))', all, ['my-project']], // has child prop lookup
114
- [':has(:type(workspace))', all, []], // has no result
115
- [':is(:root)', all, ['my-project']], // can match a single node
116
- [':is([name=a], [name=b], [name=f])', all, ['a', 'b', 'f']], // can match multiple nodes
117
- [':is(:root)', empty, []], // can't match from empty partial
118
- [
119
- ':is(#foo, [name===z], :root +, :nonexistingselector)',
120
- all,
121
- ['my-project', 'a', 'b', 'c', 'd', 'e', 'f', '@x/y'],
122
- ], // ignore any invalid selectors on loose mode
123
- [':is(:foo)', all, []], // broken selectors fail to match items when in loose mode
124
- [':is([name=a], [name=b], [name=f])', empty, []], // can match multiple nodes if no partial
125
- [':missing', all, []], // no dangling edges in this graph
126
- [':not(:root)', all, ['a', 'b', 'c', 'd', 'e', 'f', '@x/y']], // can negate single node
127
- [
128
- ':not([name=a], [name=b], [name=f])',
129
- all,
130
- ['my-project', 'c', 'd', 'e', '@x/y'],
131
- ], // can negate multiple selectors
132
- [':not(:root)', empty, []], // can't negate from empty partial
133
- [':not([name=a], [name=b], [name=f])', empty, []], // can negate multiple nodes if no partial
134
- [':private', all, ['d']], // private dep
135
- [':private', d, ['d']], // single :private item
136
- [':private', b, []], // single not :private item
137
- [':private', empty, []], // no items to filter
138
- [':semver(^2)', all, ['b']], // semver selector
139
- [':semver(=2.0.0)', all, ['b']], // semver selector
140
- [
141
- ':semver("<2.0.0")',
142
- all,
143
- ['my-project', 'a', 'c', 'd', 'e', 'f', '@x/y'],
144
- ], // quoted semver selector
145
- [':type(file)', all, ['my-project', '@x/y']], // type selector
146
- [':type(git)', all, []], // type selector, no matches
147
- [':type(registry)', all, ['a', 'b', 'c', 'd', 'e', 'f']], // type selector, no matches
148
- [':type(registry)', empty, []], // type selector, nothing to match
149
- [':dev', all, ['b', '@x/y']], // select dev deps
150
- [':dev', b, ['b']], // single item dev dep
151
- [':dev', empty, []], // empty starting partial
152
- ])
153
- const initial = copyGraphSelectionState(all)
154
- for (const [query, partial, expected] of queryToExpected) {
155
- const result = await testPseudo(
156
- query,
157
- initial,
158
- copyGraphSelectionState(partial),
159
- )
160
- t.strictSame(
161
- result.nodes.map(i => i.name),
162
- expected,
163
- `query > "${query}"`,
164
- )
165
- t.matchSnapshot(
166
- {
167
- edges: result.edges.map(i => i.name).sort(),
168
- nodes: result.nodes.map(i => i.name).sort(),
169
- },
170
- `query > "${query}"`,
171
- )
172
- }
173
-
174
- await t.test('workspace', async t => {
175
- const wsGraph = getSingleWorkspaceGraph()
176
- const all: GraphSelectionState = {
177
- edges: new Set(wsGraph.edges),
178
- nodes: new Set(wsGraph.nodes.values()),
179
- }
180
- const w: GraphSelectionState = {
181
- edges: new Set(),
182
- nodes: new Set([
183
- wsGraph.nodes.get(joinDepIDTuple(['workspace', 'w']))!,
184
- ]),
185
- }
186
- const empty: GraphSelectionState = {
187
- edges: new Set(),
188
- nodes: new Set(),
189
- }
190
- const queryToExpected = new Set<TestCase>([
191
- [':root', all, ['ws']], // root
192
- [':project /*all*/', all, ['ws', 'w']], // project = root & workspaces
193
- [':project /*empty*/', empty, []], // from empty nodes
194
- [':project /*w*/', w, ['w']], // from single node
195
- [':empty', all, ['ws', 'w']], // deps with no deps
196
- [':is(:workspace, :root)', all, ['ws', 'w']],
197
- [':is(:workspace, :root)', empty, []],
198
- [':is(:workspace)', all, ['w']],
199
- [':is(:workspace)', empty, []],
200
- [':not(:workspace, :root)', all, []], // excludes all items
201
- [':not(:workspace)', all, ['ws']], // excludes workspaces
202
- [':not(:root)', all, ['w']], // excludes root
203
- [':not(:root)', empty, []], // empty starting partial
204
- [':private', all, []], // private dep
205
- [':type(registry)', all, []], // type selector
206
- [':type(workspace)', all, ['w']], // type selector workspace
207
- [':type(file)', all, ['ws']], // type selector root
208
- [':dev', all, []], // no dev deps in this graph
209
- [':dev', empty, []], // empty starting partial
210
- ])
211
- const initial = copyGraphSelectionState(all)
212
- for (const [query, partial, expected] of queryToExpected) {
213
- const result = await testPseudo(
214
- query,
215
- initial,
216
- copyGraphSelectionState(partial),
217
- )
218
- t.strictSame(
219
- result.nodes.map(i => i.name),
220
- expected,
221
- `query > "${query}"`,
222
- )
223
- t.matchSnapshot(
224
- {
225
- edges: result.edges.map(i => i.name).sort(),
226
- nodes: result.nodes.map(i => i.name).sort(),
227
- },
228
- `query > "${query}"`,
229
- )
230
- }
231
-
232
- // test custom scopedID
233
- const result = await testPseudo(
234
- ':scope',
235
- initial,
236
- copyGraphSelectionState(all),
237
- false,
238
- [joinDepIDTuple(['workspace', 'w'])],
239
- )
240
- t.strictSame(
241
- result.nodes.map(i => i.name),
242
- ['w'],
243
- 'query > customScopedID',
244
- )
245
- t.matchSnapshot(
246
- {
247
- edges: result.edges.map(i => i.name).sort(),
248
- nodes: result.nodes.map(i => i.name).sort(),
249
- },
250
- 'query > customScopedID',
251
- )
252
- })
253
-
254
- await t.test('complex workspace', async t => {
255
- const wsGraph = getMultiWorkspaceGraph()
256
- const all: GraphSelectionState = {
257
- edges: new Set(wsGraph.edges),
258
- nodes: new Set(wsGraph.nodes.values()),
259
- }
260
- //const w = getGraphSelectionState(wsGraph, 'w')
261
- const queryToExpected = new Set<TestCase>([
262
- [':root', all, ['ws']], // root
263
- [':project', all, ['ws', 'a', 'b', 'c']], // project = root & workspaces
264
- ])
265
- const initial = copyGraphSelectionState(all)
266
- for (const [query, partial, expected] of queryToExpected) {
267
- const result = await testPseudo(
268
- query,
269
- initial,
270
- copyGraphSelectionState(partial),
271
- )
272
- t.strictSame(
273
- result.nodes.map(i => i.name),
274
- expected,
275
- `query > "${query}"`,
276
- )
277
- t.matchSnapshot(
278
- {
279
- edges: result.edges.map(i => i.name).sort(),
280
- nodes: result.nodes.map(i => i.name).sort(),
281
- },
282
- `query > "${query}"`,
283
- )
284
- }
285
- })
286
-
287
- await t.test('cycle', async t => {
288
- const cycleGraph = getCycleGraph()
289
- const all: GraphSelectionState = {
290
- edges: new Set(cycleGraph.edges),
291
- nodes: new Set(cycleGraph.nodes.values()),
292
- }
293
- const queryToExpected = new Set<TestCase>([
294
- [':root', all, ['cycle-project']], // root
295
- [':project', all, ['cycle-project']], // project = root & workspaces
296
- [':attr([scripts])', all, ['a', 'b']], // any pkgs with scripts
297
- [':attr(scripts, [test=foo])', all, ['a']], // any pkgs with scripts
298
- [':empty', all, []], // no deps with no deps
299
- [':is([name=a])', all, ['a']],
300
- [':private', all, []], // private dep
301
- [':type(registry)', all, ['a', 'b']], // type selector
302
- [':dev', all, []], // no dev deps in this graph
303
- ])
304
- const initial = copyGraphSelectionState(all)
305
- for (const [query, partial, expected] of queryToExpected) {
306
- const result = await testPseudo(
307
- query,
308
- initial,
309
- copyGraphSelectionState(partial),
310
- )
311
- t.strictSame(
312
- result.nodes.map(i => i.name),
313
- expected,
314
- `query > "${query}"`,
315
- )
316
- t.matchSnapshot(
317
- {
318
- edges: result.edges.map(i => i.name).sort(),
319
- nodes: result.nodes.map(i => i.name).sort(),
320
- },
321
- `query > "${query}"`,
322
- )
323
- }
324
- })
325
-
326
- await t.test('missing manifest', async t => {
327
- const mmGraph = getMissingManifestsGraph()
328
- const all: GraphSelectionState = {
329
- edges: new Set(mmGraph.edges),
330
- nodes: new Set(mmGraph.nodes.values()),
331
- }
332
- const queryToExpected = new Set<TestCase>([
333
- [':attr([scripts])', all, []],
334
- [':attr(scripts, [test=foo])', all, []],
335
- [':is([name=a])', all, []],
336
- ])
337
- const initial = copyGraphSelectionState(all)
338
- for (const [query, partial, expected] of queryToExpected) {
339
- const result = await testPseudo(
340
- query,
341
- initial,
342
- copyGraphSelectionState(partial),
343
- )
344
- t.strictSame(
345
- result.nodes.map(i => i.name),
346
- expected,
347
- `query > "${query}"`,
348
- )
349
- t.matchSnapshot(
350
- {
351
- edges: result.edges.map(i => i.name).sort(),
352
- nodes: result.nodes.map(i => i.name).sort(),
353
- },
354
- `query > "${query}"`,
355
- )
356
- }
357
- })
358
-
359
- await t.test('missing node', async t => {
360
- const missingNodeGraph = getMissingNodeGraph()
361
- const all: GraphSelectionState = {
362
- edges: new Set(missingNodeGraph.edges),
363
- nodes: new Set(missingNodeGraph.nodes.values()),
364
- }
365
- // tests on missing node cases use only snapshot-check
366
- // giving that we want to assert missing / present edges
367
- const queryToExpected = new Set<TestCase>([
368
- [':missing', all, []],
369
- [':has(:dev)', all, []],
370
- [':private', all, []],
371
- [':dev', all, []], // test that :dev works with missing nodes as well
372
- ])
373
- const initial = copyGraphSelectionState(all)
374
- for (const [query, partial] of queryToExpected) {
375
- const result = await testPseudo(
376
- query,
377
- initial,
378
- copyGraphSelectionState(partial),
379
- )
380
- t.matchSnapshot(
381
- {
382
- edges: result.edges.map(i => i.name).sort(),
383
- nodes: result.nodes.map(i => i.name).sort(),
384
- },
385
- `query > "${query}"`,
386
- )
387
- }
388
- })
389
- })
390
-
391
- t.test('bad selector type', async t => {
392
- await t.rejects(
393
- testPseudo('[name=a]'),
394
- /Mismatching query node/,
395
- 'should throw an error',
396
- )
397
- })
398
-
399
- t.test('unsupported pseudo', async t => {
400
- await t.rejects(
401
- testPseudo(':unsupportedpseudoclass'),
402
- {
403
- message: 'Unsupported pseudo-class: :unsupportedpseudoclass',
404
- cause: { code: 'EQUERY', found: ':unsupportedpseudoclass' },
405
- },
406
- 'should throw an unsupported selector error',
407
- )
408
-
409
- await t.rejects(
410
- testPseudo(':difff'),
411
- { cause: { wanted: ':diff' } },
412
- 'should suggest the one pseudo-class a typo away',
413
- )
414
-
415
- await t.rejects(
416
- testPseudo(':difff(main)'),
417
- { cause: { found: ':difff(main)', wanted: ':diff' } },
418
- 'should suggest past the arguments',
419
- )
420
-
421
- await t.rejects(
422
- testPseudo(':dif'),
423
- { cause: { validOptions: [':diff', ':dev', ':dist', ':is'] } },
424
- 'should list every pseudo-class a typo away',
425
- )
426
- })
427
-
428
- t.test('specificity calculation for pseudo selectors', async t => {
429
- const simpleGraph = getSimpleGraph()
430
- const all = {
431
- edges: new Set(simpleGraph.edges),
432
- nodes: new Set(simpleGraph.nodes.values()),
433
- }
434
- const initial = copyGraphSelectionState(all)
435
-
436
- // Test normal pseudo selectors (should increment commonCounter)
437
- const normalState: ParserState = {
438
- cancellable: async () => {},
439
- collect: {
440
- nodes: new Set(simpleGraph.nodes.values()),
441
- edges: new Set(simpleGraph.edges),
442
- },
443
- current: {
444
- type: 'pseudo',
445
- value: ':dev',
446
- spaces: { before: '', after: '' },
447
- } as any,
448
- initial: copyGraphSelectionState(initial),
449
- loose: false,
450
- partial: copyGraphSelectionState(initial),
451
- importers: new Set(simpleGraph.importers),
452
- hostContexts: undefined,
453
- retries: 0,
454
- securityArchive: undefined,
455
- signal: { throwIfAborted: () => {} } as AbortSignal,
456
- walk: async (state: ParserState) => state,
457
- specificity: { idCounter: 0, commonCounter: 0 },
458
- comment: '',
459
- }
460
-
461
- const result = await pseudo(normalState)
462
- t.equal(
463
- result.specificity.commonCounter,
464
- 1,
465
- ':dev should increment commonCounter',
466
- )
467
-
468
- // Test :not, :is, :has pseudo selectors (should not increment commonCounter)
469
- const notCounter = { idCounter: 0, commonCounter: 0 }
470
- const isCounter = { idCounter: 0, commonCounter: 0 }
471
- const hasCounter = { idCounter: 0, commonCounter: 0 }
472
-
473
- const notState: ParserState = {
474
- ...normalState,
475
- current: {
476
- type: 'pseudo',
477
- value: ':not',
478
- spaces: { before: '', after: '' },
479
- nodes: [],
480
- } as unknown as PostcssNodeWithChildren,
481
- specificity: { ...notCounter },
482
- }
483
-
484
- const isState: ParserState = {
485
- ...normalState,
486
- current: {
487
- type: 'pseudo',
488
- value: ':is',
489
- spaces: { before: '', after: '' },
490
- nodes: [],
491
- } as unknown as PostcssNodeWithChildren,
492
- specificity: { ...isCounter },
493
- }
494
-
495
- const hasState: ParserState = {
496
- ...normalState,
497
- current: {
498
- type: 'pseudo',
499
- value: ':has',
500
- spaces: { before: '', after: '' },
501
- nodes: [],
502
- } as unknown as PostcssNodeWithChildren,
503
- specificity: { ...hasCounter },
504
- }
505
-
506
- const notResult = await pseudo(notState)
507
- const isResult = await pseudo(isState)
508
- const hasResult = await pseudo(hasState)
509
-
510
- t.equal(
511
- notResult.specificity.commonCounter,
512
- 0,
513
- ':not should not increment commonCounter',
514
- )
515
- t.equal(
516
- isResult.specificity.commonCounter,
517
- 0,
518
- ':is should not increment commonCounter',
519
- )
520
- t.equal(
521
- hasResult.specificity.commonCounter,
522
- 0,
523
- ':has should not increment commonCounter',
524
- )
525
- })
526
-
527
- t.test(':path selector', async t => {
528
- const pathBasedGraph = getPathBasedGraph()
529
- const all = {
530
- edges: new Set(pathBasedGraph.edges),
531
- nodes: new Set(pathBasedGraph.nodes.values()),
532
- }
533
- const empty: GraphSelectionState = {
534
- edges: new Set(),
535
- nodes: new Set(),
536
- }
537
-
538
- const queryToExpected = new Set<TestCase>([
539
- // Test basic path matching - all patterns must be quoted
540
- [
541
- ':path("*")',
542
- all,
543
- ['path-based-project', 'a', 'b', 'c', 'x', 'y'],
544
- ], // Match all workspace and file nodes
545
- [':path("packages/*")', all, ['a', 'b']], // Match workspace packages in packages directory
546
- [':path("packages/a")', all, ['a']], // Match specific workspace
547
- [':path(".")', all, ['path-based-project']], // Match root project
548
- [':path("x")', all, ['x']], // Match file dependency
549
- [':path("packages/**")', all, ['a', 'b', 'y']], // Match with glob patterns
550
- [':path("packages/a/*")', all, ['y']], // Match nested file paths
551
- [':path("nonexistent/**")', all, []], // No matches
552
-
553
- // Test edge cases
554
- [':path("")', all, []], // Empty pattern should match nothing
555
- [':path()', all, []], // Missing pattern should match nothing
556
-
557
- // Test from empty partial
558
- [':path("*")', empty, []], // Empty input should return empty
559
- ])
560
-
561
- for (const [query, partial, expectedNames] of queryToExpected) {
562
- try {
563
- // Convert string names to DepID array
564
- const expectedDepIDs = expectedNames.map(name =>
565
- joinDepIDTuple(['registry', '', `${name}@1.0.0`]),
566
- )
567
- await testPseudo(query, all, partial, false, expectedDepIDs)
568
- } catch (error) {
569
- t.fail(`Failed query "${query}": ${error}`)
570
- }
571
- }
572
- })
573
-
574
- t.test('unexpected attr usage', async t => {
575
- await t.rejects(
576
- testPseudo(':attr', undefined, undefined, true),
577
- /Failed to parse :attr selector/,
578
- 'should throw a failure to parse error',
579
- )
580
- })
581
-
582
- t.test('pseudo-class names match dss-parser grammar', async t => {
583
- t.strictSame(pseudoSelectorNames, new Set(pseudoClassNames))
584
- })
package/tsconfig.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json"
3
- }
@@ -1,19 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "include": [
4
- "src/**/*.ts",
5
- "src/**/*.mts",
6
- "src/**/*.tsx",
7
- "src/**/*.json"
8
- ],
9
- "exclude": ["src/package.json"],
10
- "compilerOptions": {
11
- "outDir": "dist",
12
- "rootDir": "src",
13
- "module": "nodenext",
14
- "moduleResolution": "nodenext",
15
- "sourceMap": false,
16
- "declarationMap": false,
17
- "inlineSources": false
18
- }
19
- }