@vltpkg/query 1.4.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 (213) hide show
  1. package/dist/index.d.ts +7 -2
  2. package/dist/index.js +23 -4
  3. package/dist/pseudo/skill.d.ts +7 -0
  4. package/dist/pseudo/skill.js +52 -0
  5. package/dist/pseudo/skills.d.ts +6 -0
  6. package/dist/pseudo/skills.js +26 -0
  7. package/dist/pseudo.js +7 -0
  8. package/dist/types.d.ts +29 -1
  9. package/package.json +10 -12
  10. package/skills/dss-query/REFERENCE.md +0 -123
  11. package/skills/dss-query/SKILL.md +0 -190
  12. package/skills/dss-query/evals/README.md +0 -81
  13. package/skills/dss-query/evals/evals.json +0 -89
  14. package/skills/dss-query/evals/grade.mjs +0 -481
  15. package/src/attribute.ts +0 -190
  16. package/src/combinator.ts +0 -135
  17. package/src/error.ts +0 -78
  18. package/src/id.ts +0 -46
  19. package/src/index.ts +0 -640
  20. package/src/parser.ts +0 -122
  21. package/src/pseudo/abandoned.ts +0 -9
  22. package/src/pseudo/attr.ts +0 -92
  23. package/src/pseudo/built.ts +0 -19
  24. package/src/pseudo/confused.ts +0 -29
  25. package/src/pseudo/cve.ts +0 -93
  26. package/src/pseudo/cwe.ts +0 -97
  27. package/src/pseudo/debug.ts +0 -9
  28. package/src/pseudo/deprecated.ts +0 -9
  29. package/src/pseudo/dev.ts +0 -18
  30. package/src/pseudo/diff.ts +0 -90
  31. package/src/pseudo/dist.ts +0 -148
  32. package/src/pseudo/dynamic.ts +0 -9
  33. package/src/pseudo/empty.ts +0 -15
  34. package/src/pseudo/entropic.ts +0 -9
  35. package/src/pseudo/env.ts +0 -6
  36. package/src/pseudo/eval.ts +0 -9
  37. package/src/pseudo/fs.ts +0 -9
  38. package/src/pseudo/helpers.ts +0 -106
  39. package/src/pseudo/host.ts +0 -111
  40. package/src/pseudo/hostname.ts +0 -156
  41. package/src/pseudo/license.ts +0 -134
  42. package/src/pseudo/link.ts +0 -30
  43. package/src/pseudo/malware.ts +0 -41
  44. package/src/pseudo/minified.ts +0 -9
  45. package/src/pseudo/missing.ts +0 -16
  46. package/src/pseudo/native.ts +0 -9
  47. package/src/pseudo/network.ts +0 -9
  48. package/src/pseudo/obfuscated.ts +0 -9
  49. package/src/pseudo/optional.ts +0 -18
  50. package/src/pseudo/outdated.ts +0 -345
  51. package/src/pseudo/overridden.ts +0 -20
  52. package/src/pseudo/path.ts +0 -146
  53. package/src/pseudo/peer.ts +0 -18
  54. package/src/pseudo/prerelease.ts +0 -47
  55. package/src/pseudo/private.ts +0 -19
  56. package/src/pseudo/prod.ts +0 -18
  57. package/src/pseudo/published.ts +0 -250
  58. package/src/pseudo/registry.ts +0 -29
  59. package/src/pseudo/root.ts +0 -19
  60. package/src/pseudo/scanned.ts +0 -20
  61. package/src/pseudo/score.ts +0 -186
  62. package/src/pseudo/scripts.ts +0 -61
  63. package/src/pseudo/semver.ts +0 -320
  64. package/src/pseudo/severity.ts +0 -231
  65. package/src/pseudo/shell.ts +0 -9
  66. package/src/pseudo/shrinkwrap.ts +0 -9
  67. package/src/pseudo/spec.ts +0 -131
  68. package/src/pseudo/squat.ts +0 -225
  69. package/src/pseudo/suspicious.ts +0 -9
  70. package/src/pseudo/tracker.ts +0 -9
  71. package/src/pseudo/trivial.ts +0 -9
  72. package/src/pseudo/type.ts +0 -26
  73. package/src/pseudo/undesirable.ts +0 -9
  74. package/src/pseudo/unknown.ts +0 -9
  75. package/src/pseudo/unmaintained.ts +0 -9
  76. package/src/pseudo/unpopular.ts +0 -9
  77. package/src/pseudo/unstable.ts +0 -9
  78. package/src/pseudo/vuln.ts +0 -273
  79. package/src/pseudo/workspace.ts +0 -22
  80. package/src/pseudo.ts +0 -433
  81. package/src/types.ts +0 -176
  82. package/tap-snapshots/test/attribute.ts.test.cjs +0 -304
  83. package/tap-snapshots/test/combinator.ts.test.cjs +0 -333
  84. package/tap-snapshots/test/id.ts.test.cjs +0 -118
  85. package/tap-snapshots/test/parser.ts.test.cjs +0 -344
  86. package/tap-snapshots/test/pseudo/abandoned.ts.test.cjs +0 -18
  87. package/tap-snapshots/test/pseudo/attr.ts.test.cjs +0 -161
  88. package/tap-snapshots/test/pseudo/built.ts.test.cjs +0 -70
  89. package/tap-snapshots/test/pseudo/confused.ts.test.cjs +0 -32
  90. package/tap-snapshots/test/pseudo/cve.ts.test.cjs +0 -49
  91. package/tap-snapshots/test/pseudo/cwe.ts.test.cjs +0 -49
  92. package/tap-snapshots/test/pseudo/debug.ts.test.cjs +0 -18
  93. package/tap-snapshots/test/pseudo/deprecated.ts.test.cjs +0 -18
  94. package/tap-snapshots/test/pseudo/dist.ts.test.cjs +0 -30
  95. package/tap-snapshots/test/pseudo/dynamic.ts.test.cjs +0 -18
  96. package/tap-snapshots/test/pseudo/empty.ts.test.cjs +0 -50
  97. package/tap-snapshots/test/pseudo/entropic.ts.test.cjs +0 -18
  98. package/tap-snapshots/test/pseudo/env.ts.test.cjs +0 -18
  99. package/tap-snapshots/test/pseudo/eval.ts.test.cjs +0 -18
  100. package/tap-snapshots/test/pseudo/fs.ts.test.cjs +0 -18
  101. package/tap-snapshots/test/pseudo/helpers.ts.test.cjs +0 -18
  102. package/tap-snapshots/test/pseudo/hostname.ts.test.cjs +0 -148
  103. package/tap-snapshots/test/pseudo/license.ts.test.cjs +0 -41
  104. package/tap-snapshots/test/pseudo/link.ts.test.cjs +0 -36
  105. package/tap-snapshots/test/pseudo/malware.ts.test.cjs +0 -22
  106. package/tap-snapshots/test/pseudo/minified.ts.test.cjs +0 -18
  107. package/tap-snapshots/test/pseudo/missing.ts.test.cjs +0 -30
  108. package/tap-snapshots/test/pseudo/native.ts.test.cjs +0 -18
  109. package/tap-snapshots/test/pseudo/network.ts.test.cjs +0 -18
  110. package/tap-snapshots/test/pseudo/obfuscated.ts.test.cjs +0 -18
  111. package/tap-snapshots/test/pseudo/outdated.ts.test.cjs +0 -132
  112. package/tap-snapshots/test/pseudo/overridden.ts.test.cjs +0 -75
  113. package/tap-snapshots/test/pseudo/prerelease.ts.test.cjs +0 -101
  114. package/tap-snapshots/test/pseudo/private.ts.test.cjs +0 -38
  115. package/tap-snapshots/test/pseudo/published.ts.test.cjs +0 -171
  116. package/tap-snapshots/test/pseudo/registry.ts.test.cjs +0 -68
  117. package/tap-snapshots/test/pseudo/root.ts.test.cjs +0 -24
  118. package/tap-snapshots/test/pseudo/scanned.ts.test.cjs +0 -18
  119. package/tap-snapshots/test/pseudo/score.ts.test.cjs +0 -239
  120. package/tap-snapshots/test/pseudo/scripts.ts.test.cjs +0 -62
  121. package/tap-snapshots/test/pseudo/semver.ts.test.cjs +0 -575
  122. package/tap-snapshots/test/pseudo/severity.ts.test.cjs +0 -122
  123. package/tap-snapshots/test/pseudo/shell.ts.test.cjs +0 -18
  124. package/tap-snapshots/test/pseudo/shrinkwrap.ts.test.cjs +0 -18
  125. package/tap-snapshots/test/pseudo/spec.ts.test.cjs +0 -148
  126. package/tap-snapshots/test/pseudo/squat.ts.test.cjs +0 -129
  127. package/tap-snapshots/test/pseudo/suspicious.ts.test.cjs +0 -18
  128. package/tap-snapshots/test/pseudo/tracker.ts.test.cjs +0 -18
  129. package/tap-snapshots/test/pseudo/trivial.ts.test.cjs +0 -18
  130. package/tap-snapshots/test/pseudo/type.ts.test.cjs +0 -51
  131. package/tap-snapshots/test/pseudo/undesirable.ts.test.cjs +0 -18
  132. package/tap-snapshots/test/pseudo/unknown.ts.test.cjs +0 -18
  133. package/tap-snapshots/test/pseudo/unmaintained.ts.test.cjs +0 -18
  134. package/tap-snapshots/test/pseudo/unpopular.ts.test.cjs +0 -18
  135. package/tap-snapshots/test/pseudo/unstable.ts.test.cjs +0 -18
  136. package/tap-snapshots/test/pseudo/vuln.ts.test.cjs +0 -208
  137. package/tap-snapshots/test/pseudo/vulnerable.ts.test.cjs +0 -20
  138. package/tap-snapshots/test/pseudo/workspace.ts.test.cjs +0 -19
  139. package/tap-snapshots/test/pseudo.ts.test.cjs +0 -1247
  140. package/test/attribute.ts +0 -273
  141. package/test/combinator.ts +0 -175
  142. package/test/error.ts +0 -60
  143. package/test/fixtures/graph.ts +0 -999
  144. package/test/fixtures/selector.ts +0 -103
  145. package/test/fixtures/types.ts +0 -7
  146. package/test/id.ts +0 -102
  147. package/test/index.ts +0 -1049
  148. package/test/parser.ts +0 -117
  149. package/test/pseudo/abandoned.ts +0 -98
  150. package/test/pseudo/attr.ts +0 -298
  151. package/test/pseudo/built.ts +0 -214
  152. package/test/pseudo/confused.ts +0 -160
  153. package/test/pseudo/cve.ts +0 -249
  154. package/test/pseudo/cwe.ts +0 -255
  155. package/test/pseudo/debug.ts +0 -98
  156. package/test/pseudo/deprecated.ts +0 -98
  157. package/test/pseudo/dev.ts +0 -61
  158. package/test/pseudo/diff.ts +0 -417
  159. package/test/pseudo/dist.ts +0 -215
  160. package/test/pseudo/dynamic.ts +0 -98
  161. package/test/pseudo/empty.ts +0 -108
  162. package/test/pseudo/entropic.ts +0 -101
  163. package/test/pseudo/env.ts +0 -98
  164. package/test/pseudo/eval.ts +0 -98
  165. package/test/pseudo/fs.ts +0 -98
  166. package/test/pseudo/helpers.ts +0 -370
  167. package/test/pseudo/host-context.ts +0 -276
  168. package/test/pseudo/hostname.ts +0 -314
  169. package/test/pseudo/license.ts +0 -265
  170. package/test/pseudo/link.ts +0 -94
  171. package/test/pseudo/malware.ts +0 -184
  172. package/test/pseudo/minified.ts +0 -98
  173. package/test/pseudo/missing.ts +0 -111
  174. package/test/pseudo/native.ts +0 -98
  175. package/test/pseudo/network.ts +0 -98
  176. package/test/pseudo/obfuscated.ts +0 -98
  177. package/test/pseudo/optional.ts +0 -73
  178. package/test/pseudo/outdated.ts +0 -461
  179. package/test/pseudo/overridden.ts +0 -317
  180. package/test/pseudo/path.ts +0 -680
  181. package/test/pseudo/peer.ts +0 -101
  182. package/test/pseudo/prerelease.ts +0 -279
  183. package/test/pseudo/private.ts +0 -108
  184. package/test/pseudo/prod.ts +0 -61
  185. package/test/pseudo/published.ts +0 -557
  186. package/test/pseudo/registry.ts +0 -122
  187. package/test/pseudo/root.ts +0 -66
  188. package/test/pseudo/scanned.ts +0 -144
  189. package/test/pseudo/score.ts +0 -591
  190. package/test/pseudo/scripts.ts +0 -324
  191. package/test/pseudo/semver.ts +0 -822
  192. package/test/pseudo/severity.ts +0 -342
  193. package/test/pseudo/shell.ts +0 -98
  194. package/test/pseudo/shrinkwrap.ts +0 -98
  195. package/test/pseudo/spec.ts +0 -525
  196. package/test/pseudo/squat.ts +0 -565
  197. package/test/pseudo/suspicious.ts +0 -98
  198. package/test/pseudo/tracker.ts +0 -98
  199. package/test/pseudo/trivial.ts +0 -98
  200. package/test/pseudo/type.ts +0 -105
  201. package/test/pseudo/undesirable.ts +0 -98
  202. package/test/pseudo/unknown.ts +0 -98
  203. package/test/pseudo/unmaintained.ts +0 -98
  204. package/test/pseudo/unpopular.ts +0 -98
  205. package/test/pseudo/unstable.ts +0 -98
  206. package/test/pseudo/vuln.ts +0 -625
  207. package/test/pseudo/vulnerable.ts +0 -137
  208. package/test/pseudo/workspace.ts +0 -111
  209. package/test/pseudo.ts +0 -584
  210. package/tsconfig.json +0 -3
  211. package/tsconfig.publish.json +0 -19
  212. package/tsconfig.publish.tsbuildinfo +0 -1
  213. 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
- }