@vltpkg/query 1.5.0 → 1.6.1

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