@vltpkg/query 1.0.0-rc.9 → 1.0.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 (463) hide show
  1. package/dist/{esm/attribute.d.ts → attribute.d.ts} +0 -1
  2. package/dist/{esm/attribute.js → attribute.js} +0 -1
  3. package/dist/{esm/combinator.d.ts → combinator.d.ts} +0 -1
  4. package/dist/{esm/combinator.js → combinator.js} +0 -1
  5. package/dist/{esm/id.d.ts → id.d.ts} +0 -1
  6. package/dist/{esm/id.js → id.js} +0 -1
  7. package/dist/{esm/index.d.ts → index.d.ts} +3 -3
  8. package/dist/{esm/index.js → index.js} +14 -8
  9. package/dist/{esm/parser.d.ts → parser.d.ts} +0 -1
  10. package/dist/{esm/parser.js → parser.js} +2 -2
  11. package/dist/{esm/pseudo → pseudo}/abandoned.d.ts +0 -1
  12. package/dist/{esm/pseudo → pseudo}/abandoned.js +0 -1
  13. package/dist/{esm/pseudo → pseudo}/attr.d.ts +0 -1
  14. package/dist/{esm/pseudo → pseudo}/attr.js +0 -1
  15. package/dist/{esm/pseudo → pseudo}/built.d.ts +0 -1
  16. package/dist/{esm/pseudo → pseudo}/built.js +0 -1
  17. package/dist/{esm/pseudo → pseudo}/confused.d.ts +0 -1
  18. package/dist/{esm/pseudo → pseudo}/confused.js +0 -1
  19. package/dist/{esm/pseudo → pseudo}/cve.d.ts +6 -3
  20. package/dist/pseudo/cve.js +61 -0
  21. package/dist/{esm/pseudo → pseudo}/cwe.d.ts +6 -3
  22. package/dist/pseudo/cwe.js +61 -0
  23. package/dist/{esm/pseudo → pseudo}/debug.d.ts +0 -1
  24. package/dist/{esm/pseudo → pseudo}/debug.js +0 -1
  25. package/dist/{esm/pseudo → pseudo}/deprecated.d.ts +0 -1
  26. package/dist/{esm/pseudo → pseudo}/deprecated.js +0 -1
  27. package/dist/{esm/pseudo → pseudo}/dev.d.ts +0 -1
  28. package/dist/{esm/pseudo → pseudo}/dev.js +0 -1
  29. package/dist/pseudo/diff.d.ts +26 -0
  30. package/dist/pseudo/diff.js +75 -0
  31. package/dist/pseudo/dist.d.ts +22 -0
  32. package/dist/pseudo/dist.js +110 -0
  33. package/dist/{esm/pseudo → pseudo}/dynamic.d.ts +0 -1
  34. package/dist/{esm/pseudo → pseudo}/dynamic.js +0 -1
  35. package/dist/{esm/pseudo → pseudo}/empty.d.ts +0 -1
  36. package/dist/{esm/pseudo → pseudo}/empty.js +0 -1
  37. package/dist/{esm/pseudo → pseudo}/entropic.d.ts +0 -1
  38. package/dist/{esm/pseudo → pseudo}/entropic.js +0 -1
  39. package/dist/{esm/pseudo → pseudo}/env.d.ts +0 -1
  40. package/dist/{esm/pseudo → pseudo}/env.js +0 -1
  41. package/dist/{esm/pseudo → pseudo}/eval.d.ts +0 -1
  42. package/dist/{esm/pseudo → pseudo}/eval.js +0 -1
  43. package/dist/{esm/pseudo → pseudo}/fs.d.ts +0 -1
  44. package/dist/{esm/pseudo → pseudo}/fs.js +0 -1
  45. package/dist/{esm/pseudo → pseudo}/helpers.d.ts +0 -1
  46. package/dist/{esm/pseudo → pseudo}/helpers.js +1 -2
  47. package/dist/{esm/pseudo → pseudo}/host.d.ts +0 -1
  48. package/dist/{esm/pseudo → pseudo}/host.js +0 -1
  49. package/dist/pseudo/hostname.d.ts +11 -0
  50. package/dist/pseudo/hostname.js +140 -0
  51. package/dist/{esm/pseudo → pseudo}/license.d.ts +0 -1
  52. package/dist/{esm/pseudo → pseudo}/license.js +0 -1
  53. package/dist/{esm/pseudo → pseudo}/link.d.ts +0 -1
  54. package/dist/{esm/pseudo → pseudo}/link.js +0 -1
  55. package/dist/pseudo/malware.d.ts +10 -0
  56. package/dist/pseudo/malware.js +26 -0
  57. package/dist/{esm/pseudo → pseudo}/minified.d.ts +0 -1
  58. package/dist/{esm/pseudo → pseudo}/minified.js +0 -1
  59. package/dist/{esm/pseudo → pseudo}/missing.d.ts +0 -1
  60. package/dist/{esm/pseudo → pseudo}/missing.js +0 -1
  61. package/dist/{esm/pseudo → pseudo}/native.d.ts +0 -1
  62. package/dist/{esm/pseudo → pseudo}/native.js +0 -1
  63. package/dist/{esm/pseudo → pseudo}/network.d.ts +0 -1
  64. package/dist/{esm/pseudo → pseudo}/network.js +0 -1
  65. package/dist/{esm/pseudo → pseudo}/obfuscated.d.ts +0 -1
  66. package/dist/{esm/pseudo → pseudo}/obfuscated.js +0 -1
  67. package/dist/{esm/pseudo → pseudo}/optional.d.ts +0 -1
  68. package/dist/{esm/pseudo → pseudo}/optional.js +0 -1
  69. package/dist/{esm/pseudo → pseudo}/outdated.d.ts +0 -1
  70. package/dist/{esm/pseudo → pseudo}/outdated.js +0 -1
  71. package/dist/{esm/pseudo → pseudo}/overridden.d.ts +0 -1
  72. package/dist/{esm/pseudo → pseudo}/overridden.js +0 -1
  73. package/dist/{esm/pseudo → pseudo}/path.d.ts +0 -1
  74. package/dist/{esm/pseudo → pseudo}/path.js +1 -4
  75. package/dist/{esm/pseudo → pseudo}/peer.d.ts +0 -1
  76. package/dist/{esm/pseudo → pseudo}/peer.js +0 -1
  77. package/dist/{esm/pseudo → pseudo}/prerelease.d.ts +0 -1
  78. package/dist/{esm/pseudo → pseudo}/prerelease.js +0 -1
  79. package/dist/{esm/pseudo → pseudo}/private.d.ts +0 -1
  80. package/dist/{esm/pseudo → pseudo}/private.js +0 -1
  81. package/dist/{esm/pseudo → pseudo}/prod.d.ts +0 -1
  82. package/dist/{esm/pseudo → pseudo}/prod.js +0 -1
  83. package/dist/{esm/pseudo → pseudo}/published.d.ts +0 -1
  84. package/dist/{esm/pseudo → pseudo}/published.js +0 -1
  85. package/dist/pseudo/registry.d.ts +10 -0
  86. package/dist/pseudo/registry.js +24 -0
  87. package/dist/{esm/pseudo → pseudo}/root.d.ts +0 -1
  88. package/dist/{esm/pseudo → pseudo}/root.js +0 -1
  89. package/dist/{esm/pseudo → pseudo}/scanned.d.ts +0 -1
  90. package/dist/{esm/pseudo → pseudo}/scanned.js +0 -1
  91. package/dist/{esm/pseudo → pseudo}/score.d.ts +0 -1
  92. package/dist/{esm/pseudo → pseudo}/score.js +0 -1
  93. package/dist/{esm/pseudo → pseudo}/scripts.d.ts +0 -1
  94. package/dist/{esm/pseudo → pseudo}/scripts.js +1 -2
  95. package/dist/{esm/pseudo → pseudo}/semver.d.ts +3 -2
  96. package/dist/{esm/pseudo → pseudo}/semver.js +43 -7
  97. package/dist/{esm/pseudo → pseudo}/severity.d.ts +0 -1
  98. package/dist/{esm/pseudo → pseudo}/severity.js +0 -1
  99. package/dist/{esm/pseudo → pseudo}/shell.d.ts +0 -1
  100. package/dist/{esm/pseudo → pseudo}/shell.js +0 -1
  101. package/dist/{esm/pseudo → pseudo}/shrinkwrap.d.ts +0 -1
  102. package/dist/{esm/pseudo → pseudo}/shrinkwrap.js +0 -1
  103. package/dist/{esm/pseudo → pseudo}/spec.d.ts +0 -1
  104. package/dist/{esm/pseudo → pseudo}/spec.js +0 -1
  105. package/dist/{esm/pseudo → pseudo}/squat.d.ts +0 -1
  106. package/dist/{esm/pseudo → pseudo}/squat.js +0 -1
  107. package/dist/{esm/pseudo → pseudo}/suspicious.d.ts +0 -1
  108. package/dist/{esm/pseudo → pseudo}/suspicious.js +0 -1
  109. package/dist/{esm/pseudo → pseudo}/tracker.d.ts +0 -1
  110. package/dist/{esm/pseudo → pseudo}/tracker.js +0 -1
  111. package/dist/{esm/pseudo → pseudo}/trivial.d.ts +0 -1
  112. package/dist/{esm/pseudo → pseudo}/trivial.js +0 -1
  113. package/dist/{esm/pseudo → pseudo}/type.d.ts +0 -1
  114. package/dist/{esm/pseudo → pseudo}/type.js +0 -1
  115. package/dist/{esm/pseudo → pseudo}/undesirable.d.ts +0 -1
  116. package/dist/{esm/pseudo → pseudo}/undesirable.js +0 -1
  117. package/dist/{esm/pseudo → pseudo}/unknown.d.ts +0 -1
  118. package/dist/{esm/pseudo → pseudo}/unknown.js +0 -1
  119. package/dist/{esm/pseudo → pseudo}/unmaintained.d.ts +0 -1
  120. package/dist/{esm/pseudo → pseudo}/unmaintained.js +0 -1
  121. package/dist/{esm/pseudo → pseudo}/unpopular.d.ts +0 -1
  122. package/dist/{esm/pseudo → pseudo}/unpopular.js +0 -1
  123. package/dist/{esm/pseudo → pseudo}/unstable.d.ts +0 -1
  124. package/dist/{esm/pseudo → pseudo}/unstable.js +0 -1
  125. package/dist/pseudo/vuln.d.ts +22 -0
  126. package/dist/pseudo/vuln.js +220 -0
  127. package/dist/{esm/pseudo → pseudo}/workspace.d.ts +0 -1
  128. package/dist/{esm/pseudo → pseudo}/workspace.js +0 -1
  129. package/dist/{esm/pseudo.d.ts → pseudo.d.ts} +0 -1
  130. package/dist/{esm/pseudo.js → pseudo.js} +16 -1
  131. package/dist/{esm/types.d.ts → types.d.ts} +10 -3
  132. package/dist/types.js +1 -0
  133. package/package.json +46 -47
  134. package/skills/dss-query/REFERENCE.md +123 -0
  135. package/skills/dss-query/SKILL.md +190 -0
  136. package/skills/dss-query/evals/README.md +79 -0
  137. package/skills/dss-query/evals/evals.json +89 -0
  138. package/skills/dss-query/evals/grade.mjs +480 -0
  139. package/src/attribute.ts +186 -0
  140. package/src/combinator.ts +132 -0
  141. package/src/id.ts +46 -0
  142. package/src/index.ts +620 -0
  143. package/src/parser.ts +122 -0
  144. package/src/pseudo/abandoned.ts +9 -0
  145. package/src/pseudo/attr.ts +92 -0
  146. package/src/pseudo/built.ts +19 -0
  147. package/src/pseudo/confused.ts +29 -0
  148. package/src/pseudo/cve.ts +93 -0
  149. package/src/pseudo/cwe.ts +97 -0
  150. package/src/pseudo/debug.ts +9 -0
  151. package/src/pseudo/deprecated.ts +9 -0
  152. package/src/pseudo/dev.ts +18 -0
  153. package/src/pseudo/diff.ts +90 -0
  154. package/src/pseudo/dist.ts +144 -0
  155. package/src/pseudo/dynamic.ts +9 -0
  156. package/src/pseudo/empty.ts +15 -0
  157. package/src/pseudo/entropic.ts +9 -0
  158. package/src/pseudo/env.ts +6 -0
  159. package/src/pseudo/eval.ts +9 -0
  160. package/src/pseudo/fs.ts +9 -0
  161. package/src/pseudo/helpers.ts +106 -0
  162. package/src/pseudo/host.ts +111 -0
  163. package/src/pseudo/hostname.ts +156 -0
  164. package/src/pseudo/license.ts +134 -0
  165. package/src/pseudo/link.ts +30 -0
  166. package/src/pseudo/malware.ts +41 -0
  167. package/src/pseudo/minified.ts +9 -0
  168. package/src/pseudo/missing.ts +16 -0
  169. package/src/pseudo/native.ts +9 -0
  170. package/src/pseudo/network.ts +9 -0
  171. package/src/pseudo/obfuscated.ts +9 -0
  172. package/src/pseudo/optional.ts +18 -0
  173. package/src/pseudo/outdated.ts +305 -0
  174. package/src/pseudo/overridden.ts +20 -0
  175. package/src/pseudo/path.ts +146 -0
  176. package/src/pseudo/peer.ts +18 -0
  177. package/src/pseudo/prerelease.ts +47 -0
  178. package/src/pseudo/private.ts +19 -0
  179. package/src/pseudo/prod.ts +18 -0
  180. package/src/pseudo/published.ts +248 -0
  181. package/src/pseudo/registry.ts +29 -0
  182. package/src/pseudo/root.ts +19 -0
  183. package/src/pseudo/scanned.ts +20 -0
  184. package/src/pseudo/score.ts +186 -0
  185. package/src/pseudo/scripts.ts +54 -0
  186. package/src/pseudo/semver.ts +320 -0
  187. package/src/pseudo/severity.ts +231 -0
  188. package/src/pseudo/shell.ts +9 -0
  189. package/src/pseudo/shrinkwrap.ts +9 -0
  190. package/src/pseudo/spec.ts +131 -0
  191. package/src/pseudo/squat.ts +225 -0
  192. package/src/pseudo/suspicious.ts +9 -0
  193. package/src/pseudo/tracker.ts +9 -0
  194. package/src/pseudo/trivial.ts +9 -0
  195. package/src/pseudo/type.ts +26 -0
  196. package/src/pseudo/undesirable.ts +9 -0
  197. package/src/pseudo/unknown.ts +9 -0
  198. package/src/pseudo/unmaintained.ts +9 -0
  199. package/src/pseudo/unpopular.ts +9 -0
  200. package/src/pseudo/unstable.ts +9 -0
  201. package/src/pseudo/vuln.ts +273 -0
  202. package/src/pseudo/workspace.ts +22 -0
  203. package/src/pseudo.ts +413 -0
  204. package/src/types.ts +165 -0
  205. package/tap-snapshots/test/attribute.ts.test.cjs +304 -0
  206. package/tap-snapshots/test/combinator.ts.test.cjs +333 -0
  207. package/tap-snapshots/test/id.ts.test.cjs +118 -0
  208. package/tap-snapshots/test/parser.ts.test.cjs +344 -0
  209. package/tap-snapshots/test/pseudo/abandoned.ts.test.cjs +18 -0
  210. package/tap-snapshots/test/pseudo/attr.ts.test.cjs +161 -0
  211. package/tap-snapshots/test/pseudo/built.ts.test.cjs +70 -0
  212. package/tap-snapshots/test/pseudo/confused.ts.test.cjs +32 -0
  213. package/tap-snapshots/test/pseudo/cve.ts.test.cjs +49 -0
  214. package/tap-snapshots/test/pseudo/cwe.ts.test.cjs +49 -0
  215. package/tap-snapshots/test/pseudo/debug.ts.test.cjs +18 -0
  216. package/tap-snapshots/test/pseudo/deprecated.ts.test.cjs +18 -0
  217. package/tap-snapshots/test/pseudo/dist.ts.test.cjs +30 -0
  218. package/tap-snapshots/test/pseudo/dynamic.ts.test.cjs +18 -0
  219. package/tap-snapshots/test/pseudo/empty.ts.test.cjs +50 -0
  220. package/tap-snapshots/test/pseudo/entropic.ts.test.cjs +18 -0
  221. package/tap-snapshots/test/pseudo/env.ts.test.cjs +18 -0
  222. package/tap-snapshots/test/pseudo/eval.ts.test.cjs +18 -0
  223. package/tap-snapshots/test/pseudo/fs.ts.test.cjs +18 -0
  224. package/tap-snapshots/test/pseudo/helpers.ts.test.cjs +18 -0
  225. package/tap-snapshots/test/pseudo/hostname.ts.test.cjs +148 -0
  226. package/tap-snapshots/test/pseudo/license.ts.test.cjs +41 -0
  227. package/tap-snapshots/test/pseudo/link.ts.test.cjs +36 -0
  228. package/tap-snapshots/test/pseudo/malware.ts.test.cjs +22 -0
  229. package/tap-snapshots/test/pseudo/minified.ts.test.cjs +18 -0
  230. package/tap-snapshots/test/pseudo/missing.ts.test.cjs +30 -0
  231. package/tap-snapshots/test/pseudo/native.ts.test.cjs +18 -0
  232. package/tap-snapshots/test/pseudo/network.ts.test.cjs +18 -0
  233. package/tap-snapshots/test/pseudo/obfuscated.ts.test.cjs +18 -0
  234. package/tap-snapshots/test/pseudo/outdated.ts.test.cjs +130 -0
  235. package/tap-snapshots/test/pseudo/overridden.ts.test.cjs +75 -0
  236. package/tap-snapshots/test/pseudo/prerelease.ts.test.cjs +101 -0
  237. package/tap-snapshots/test/pseudo/private.ts.test.cjs +38 -0
  238. package/tap-snapshots/test/pseudo/published.ts.test.cjs +171 -0
  239. package/tap-snapshots/test/pseudo/registry.ts.test.cjs +68 -0
  240. package/tap-snapshots/test/pseudo/root.ts.test.cjs +24 -0
  241. package/tap-snapshots/test/pseudo/scanned.ts.test.cjs +18 -0
  242. package/tap-snapshots/test/pseudo/score.ts.test.cjs +239 -0
  243. package/tap-snapshots/test/pseudo/scripts.ts.test.cjs +61 -0
  244. package/tap-snapshots/test/pseudo/semver.ts.test.cjs +575 -0
  245. package/tap-snapshots/test/pseudo/severity.ts.test.cjs +95 -0
  246. package/tap-snapshots/test/pseudo/shell.ts.test.cjs +18 -0
  247. package/tap-snapshots/test/pseudo/shrinkwrap.ts.test.cjs +18 -0
  248. package/tap-snapshots/test/pseudo/spec.ts.test.cjs +148 -0
  249. package/tap-snapshots/test/pseudo/squat.ts.test.cjs +129 -0
  250. package/tap-snapshots/test/pseudo/suspicious.ts.test.cjs +18 -0
  251. package/tap-snapshots/test/pseudo/tracker.ts.test.cjs +18 -0
  252. package/tap-snapshots/test/pseudo/trivial.ts.test.cjs +18 -0
  253. package/tap-snapshots/test/pseudo/type.ts.test.cjs +51 -0
  254. package/tap-snapshots/test/pseudo/undesirable.ts.test.cjs +18 -0
  255. package/tap-snapshots/test/pseudo/unknown.ts.test.cjs +18 -0
  256. package/tap-snapshots/test/pseudo/unmaintained.ts.test.cjs +18 -0
  257. package/tap-snapshots/test/pseudo/unpopular.ts.test.cjs +18 -0
  258. package/tap-snapshots/test/pseudo/unstable.ts.test.cjs +18 -0
  259. package/tap-snapshots/test/pseudo/vuln.ts.test.cjs +208 -0
  260. package/tap-snapshots/test/pseudo/vulnerable.ts.test.cjs +20 -0
  261. package/tap-snapshots/test/pseudo/workspace.ts.test.cjs +19 -0
  262. package/tap-snapshots/test/pseudo.ts.test.cjs +1247 -0
  263. package/test/attribute.ts +266 -0
  264. package/test/combinator.ts +168 -0
  265. package/test/fixtures/graph.ts +999 -0
  266. package/test/fixtures/selector.ts +103 -0
  267. package/test/fixtures/types.ts +7 -0
  268. package/test/id.ts +102 -0
  269. package/test/index.ts +1000 -0
  270. package/test/parser.ts +117 -0
  271. package/test/pseudo/abandoned.ts +98 -0
  272. package/test/pseudo/attr.ts +298 -0
  273. package/test/pseudo/built.ts +214 -0
  274. package/test/pseudo/confused.ts +160 -0
  275. package/test/pseudo/cve.ts +249 -0
  276. package/test/pseudo/cwe.ts +255 -0
  277. package/test/pseudo/debug.ts +98 -0
  278. package/test/pseudo/deprecated.ts +98 -0
  279. package/test/pseudo/dev.ts +61 -0
  280. package/test/pseudo/diff.ts +417 -0
  281. package/test/pseudo/dist.ts +215 -0
  282. package/test/pseudo/dynamic.ts +98 -0
  283. package/test/pseudo/empty.ts +108 -0
  284. package/test/pseudo/entropic.ts +101 -0
  285. package/test/pseudo/env.ts +98 -0
  286. package/test/pseudo/eval.ts +98 -0
  287. package/test/pseudo/fs.ts +98 -0
  288. package/test/pseudo/helpers.ts +370 -0
  289. package/test/pseudo/host-context.ts +276 -0
  290. package/test/pseudo/hostname.ts +314 -0
  291. package/test/pseudo/license.ts +265 -0
  292. package/test/pseudo/link.ts +94 -0
  293. package/test/pseudo/malware.ts +184 -0
  294. package/test/pseudo/minified.ts +98 -0
  295. package/test/pseudo/missing.ts +111 -0
  296. package/test/pseudo/native.ts +98 -0
  297. package/test/pseudo/network.ts +98 -0
  298. package/test/pseudo/obfuscated.ts +98 -0
  299. package/test/pseudo/optional.ts +73 -0
  300. package/test/pseudo/outdated.ts +331 -0
  301. package/test/pseudo/overridden.ts +317 -0
  302. package/test/pseudo/path.ts +680 -0
  303. package/test/pseudo/peer.ts +101 -0
  304. package/test/pseudo/prerelease.ts +279 -0
  305. package/test/pseudo/private.ts +108 -0
  306. package/test/pseudo/prod.ts +61 -0
  307. package/test/pseudo/published.ts +557 -0
  308. package/test/pseudo/registry.ts +122 -0
  309. package/test/pseudo/root.ts +66 -0
  310. package/test/pseudo/scanned.ts +78 -0
  311. package/test/pseudo/score.ts +591 -0
  312. package/test/pseudo/scripts.ts +294 -0
  313. package/test/pseudo/semver.ts +822 -0
  314. package/test/pseudo/severity.ts +310 -0
  315. package/test/pseudo/shell.ts +98 -0
  316. package/test/pseudo/shrinkwrap.ts +98 -0
  317. package/test/pseudo/spec.ts +525 -0
  318. package/test/pseudo/squat.ts +565 -0
  319. package/test/pseudo/suspicious.ts +98 -0
  320. package/test/pseudo/tracker.ts +98 -0
  321. package/test/pseudo/trivial.ts +98 -0
  322. package/test/pseudo/type.ts +105 -0
  323. package/test/pseudo/undesirable.ts +98 -0
  324. package/test/pseudo/unknown.ts +98 -0
  325. package/test/pseudo/unmaintained.ts +98 -0
  326. package/test/pseudo/unpopular.ts +98 -0
  327. package/test/pseudo/unstable.ts +98 -0
  328. package/test/pseudo/vuln.ts +625 -0
  329. package/test/pseudo/vulnerable.ts +137 -0
  330. package/test/pseudo/workspace.ts +111 -0
  331. package/test/pseudo.ts +558 -0
  332. package/tsconfig.json +3 -0
  333. package/tsconfig.publish.json +19 -0
  334. package/tsconfig.publish.tsbuildinfo +1 -0
  335. package/typedoc.mjs +2 -0
  336. package/dist/esm/attribute.d.ts.map +0 -1
  337. package/dist/esm/attribute.js.map +0 -1
  338. package/dist/esm/combinator.d.ts.map +0 -1
  339. package/dist/esm/combinator.js.map +0 -1
  340. package/dist/esm/id.d.ts.map +0 -1
  341. package/dist/esm/id.js.map +0 -1
  342. package/dist/esm/index.d.ts.map +0 -1
  343. package/dist/esm/index.js.map +0 -1
  344. package/dist/esm/package.json +0 -3
  345. package/dist/esm/parser.d.ts.map +0 -1
  346. package/dist/esm/parser.js.map +0 -1
  347. package/dist/esm/pseudo/abandoned.d.ts.map +0 -1
  348. package/dist/esm/pseudo/abandoned.js.map +0 -1
  349. package/dist/esm/pseudo/attr.d.ts.map +0 -1
  350. package/dist/esm/pseudo/attr.js.map +0 -1
  351. package/dist/esm/pseudo/built.d.ts.map +0 -1
  352. package/dist/esm/pseudo/built.js.map +0 -1
  353. package/dist/esm/pseudo/confused.d.ts.map +0 -1
  354. package/dist/esm/pseudo/confused.js.map +0 -1
  355. package/dist/esm/pseudo/cve.d.ts.map +0 -1
  356. package/dist/esm/pseudo/cve.js +0 -44
  357. package/dist/esm/pseudo/cve.js.map +0 -1
  358. package/dist/esm/pseudo/cwe.d.ts.map +0 -1
  359. package/dist/esm/pseudo/cwe.js +0 -43
  360. package/dist/esm/pseudo/cwe.js.map +0 -1
  361. package/dist/esm/pseudo/debug.d.ts.map +0 -1
  362. package/dist/esm/pseudo/debug.js.map +0 -1
  363. package/dist/esm/pseudo/deprecated.d.ts.map +0 -1
  364. package/dist/esm/pseudo/deprecated.js.map +0 -1
  365. package/dist/esm/pseudo/dev.d.ts.map +0 -1
  366. package/dist/esm/pseudo/dev.js.map +0 -1
  367. package/dist/esm/pseudo/dynamic.d.ts.map +0 -1
  368. package/dist/esm/pseudo/dynamic.js.map +0 -1
  369. package/dist/esm/pseudo/empty.d.ts.map +0 -1
  370. package/dist/esm/pseudo/empty.js.map +0 -1
  371. package/dist/esm/pseudo/entropic.d.ts.map +0 -1
  372. package/dist/esm/pseudo/entropic.js.map +0 -1
  373. package/dist/esm/pseudo/env.d.ts.map +0 -1
  374. package/dist/esm/pseudo/env.js.map +0 -1
  375. package/dist/esm/pseudo/eval.d.ts.map +0 -1
  376. package/dist/esm/pseudo/eval.js.map +0 -1
  377. package/dist/esm/pseudo/fs.d.ts.map +0 -1
  378. package/dist/esm/pseudo/fs.js.map +0 -1
  379. package/dist/esm/pseudo/helpers.d.ts.map +0 -1
  380. package/dist/esm/pseudo/helpers.js.map +0 -1
  381. package/dist/esm/pseudo/host.d.ts.map +0 -1
  382. package/dist/esm/pseudo/host.js.map +0 -1
  383. package/dist/esm/pseudo/license.d.ts.map +0 -1
  384. package/dist/esm/pseudo/license.js.map +0 -1
  385. package/dist/esm/pseudo/link.d.ts.map +0 -1
  386. package/dist/esm/pseudo/link.js.map +0 -1
  387. package/dist/esm/pseudo/malware.d.ts +0 -24
  388. package/dist/esm/pseudo/malware.d.ts.map +0 -1
  389. package/dist/esm/pseudo/malware.js +0 -187
  390. package/dist/esm/pseudo/malware.js.map +0 -1
  391. package/dist/esm/pseudo/minified.d.ts.map +0 -1
  392. package/dist/esm/pseudo/minified.js.map +0 -1
  393. package/dist/esm/pseudo/missing.d.ts.map +0 -1
  394. package/dist/esm/pseudo/missing.js.map +0 -1
  395. package/dist/esm/pseudo/native.d.ts.map +0 -1
  396. package/dist/esm/pseudo/native.js.map +0 -1
  397. package/dist/esm/pseudo/network.d.ts.map +0 -1
  398. package/dist/esm/pseudo/network.js.map +0 -1
  399. package/dist/esm/pseudo/obfuscated.d.ts.map +0 -1
  400. package/dist/esm/pseudo/obfuscated.js.map +0 -1
  401. package/dist/esm/pseudo/optional.d.ts.map +0 -1
  402. package/dist/esm/pseudo/optional.js.map +0 -1
  403. package/dist/esm/pseudo/outdated.d.ts.map +0 -1
  404. package/dist/esm/pseudo/outdated.js.map +0 -1
  405. package/dist/esm/pseudo/overridden.d.ts.map +0 -1
  406. package/dist/esm/pseudo/overridden.js.map +0 -1
  407. package/dist/esm/pseudo/path.d.ts.map +0 -1
  408. package/dist/esm/pseudo/path.js.map +0 -1
  409. package/dist/esm/pseudo/peer.d.ts.map +0 -1
  410. package/dist/esm/pseudo/peer.js.map +0 -1
  411. package/dist/esm/pseudo/prerelease.d.ts.map +0 -1
  412. package/dist/esm/pseudo/prerelease.js.map +0 -1
  413. package/dist/esm/pseudo/private.d.ts.map +0 -1
  414. package/dist/esm/pseudo/private.js.map +0 -1
  415. package/dist/esm/pseudo/prod.d.ts.map +0 -1
  416. package/dist/esm/pseudo/prod.js.map +0 -1
  417. package/dist/esm/pseudo/published.d.ts.map +0 -1
  418. package/dist/esm/pseudo/published.js.map +0 -1
  419. package/dist/esm/pseudo/root.d.ts.map +0 -1
  420. package/dist/esm/pseudo/root.js.map +0 -1
  421. package/dist/esm/pseudo/scanned.d.ts.map +0 -1
  422. package/dist/esm/pseudo/scanned.js.map +0 -1
  423. package/dist/esm/pseudo/score.d.ts.map +0 -1
  424. package/dist/esm/pseudo/score.js.map +0 -1
  425. package/dist/esm/pseudo/scripts.d.ts.map +0 -1
  426. package/dist/esm/pseudo/scripts.js.map +0 -1
  427. package/dist/esm/pseudo/semver.d.ts.map +0 -1
  428. package/dist/esm/pseudo/semver.js.map +0 -1
  429. package/dist/esm/pseudo/severity.d.ts.map +0 -1
  430. package/dist/esm/pseudo/severity.js.map +0 -1
  431. package/dist/esm/pseudo/shell.d.ts.map +0 -1
  432. package/dist/esm/pseudo/shell.js.map +0 -1
  433. package/dist/esm/pseudo/shrinkwrap.d.ts.map +0 -1
  434. package/dist/esm/pseudo/shrinkwrap.js.map +0 -1
  435. package/dist/esm/pseudo/spec.d.ts.map +0 -1
  436. package/dist/esm/pseudo/spec.js.map +0 -1
  437. package/dist/esm/pseudo/squat.d.ts.map +0 -1
  438. package/dist/esm/pseudo/squat.js.map +0 -1
  439. package/dist/esm/pseudo/suspicious.d.ts.map +0 -1
  440. package/dist/esm/pseudo/suspicious.js.map +0 -1
  441. package/dist/esm/pseudo/tracker.d.ts.map +0 -1
  442. package/dist/esm/pseudo/tracker.js.map +0 -1
  443. package/dist/esm/pseudo/trivial.d.ts.map +0 -1
  444. package/dist/esm/pseudo/trivial.js.map +0 -1
  445. package/dist/esm/pseudo/type.d.ts.map +0 -1
  446. package/dist/esm/pseudo/type.js.map +0 -1
  447. package/dist/esm/pseudo/undesirable.d.ts.map +0 -1
  448. package/dist/esm/pseudo/undesirable.js.map +0 -1
  449. package/dist/esm/pseudo/unknown.d.ts.map +0 -1
  450. package/dist/esm/pseudo/unknown.js.map +0 -1
  451. package/dist/esm/pseudo/unmaintained.d.ts.map +0 -1
  452. package/dist/esm/pseudo/unmaintained.js.map +0 -1
  453. package/dist/esm/pseudo/unpopular.d.ts.map +0 -1
  454. package/dist/esm/pseudo/unpopular.js.map +0 -1
  455. package/dist/esm/pseudo/unstable.d.ts.map +0 -1
  456. package/dist/esm/pseudo/unstable.js.map +0 -1
  457. package/dist/esm/pseudo/workspace.d.ts.map +0 -1
  458. package/dist/esm/pseudo/workspace.js.map +0 -1
  459. package/dist/esm/pseudo.d.ts.map +0 -1
  460. package/dist/esm/pseudo.js.map +0 -1
  461. package/dist/esm/types.d.ts.map +0 -1
  462. package/dist/esm/types.js +0 -2
  463. package/dist/esm/types.js.map +0 -1
package/src/index.ts ADDED
@@ -0,0 +1,620 @@
1
+ import { error } from '@vltpkg/error-cause'
2
+ import { joinDepIDTuple } from '@vltpkg/dep-id/browser'
3
+ import {
4
+ parse,
5
+ isPostcssNodeWithChildren,
6
+ asPostcssNodeWithChildren,
7
+ isSelectorNode,
8
+ isPseudoNode,
9
+ isIdentifierNode,
10
+ isAttributeNode,
11
+ } from '@vltpkg/dss-parser'
12
+ import { attribute } from './attribute.ts'
13
+ import { combinator } from './combinator.ts'
14
+ import { id } from './id.ts'
15
+ import { pseudo } from './pseudo.ts'
16
+ import type { EdgeLike, NodeLike } from '@vltpkg/types'
17
+ import type { SecurityArchiveLike } from '@vltpkg/security-archive'
18
+ import type {
19
+ PostcssNode,
20
+ PostcssNodeWithChildren,
21
+ } from '@vltpkg/dss-parser'
22
+ import type {
23
+ DiffFilesProvider,
24
+ HostContextsMap,
25
+ ParsedSelectorToken,
26
+ ParserState,
27
+ ParserFn,
28
+ QueryResponse,
29
+ QueryResponseNode,
30
+ QueryResponseEdge,
31
+ } from './types.ts'
32
+ import type { DepID } from '@vltpkg/dep-id'
33
+
34
+ export * from './types.ts'
35
+
36
+ export type SearchOptions = {
37
+ signal: AbortSignal
38
+ scopeIDs?: DepID[]
39
+ }
40
+
41
+ const noopFn = async (state: ParserState) => state
42
+
43
+ const selectors = {
44
+ attribute,
45
+ /* c8 ignore start */
46
+ class: async (state: ParserState) => {
47
+ throw error('Unsupported selector', { found: state.current })
48
+ },
49
+ /* c8 ignore end */
50
+ combinator,
51
+ comment: async (state: ParserState) => {
52
+ if (state.current.value && !state.comment) {
53
+ const commentValue = state.current.value
54
+ const cleanComment = commentValue
55
+ .replace(/^\/\*/, '')
56
+ .replace(/\*\/$/, '')
57
+ .trim()
58
+ state.comment = cleanComment
59
+ }
60
+ return state
61
+ },
62
+ id,
63
+ nesting: noopFn,
64
+ pseudo,
65
+ root: noopFn,
66
+ selector: async (state: ParserState) => {
67
+ state.partial.nodes = new Set(state.initial.nodes)
68
+ state.partial.edges = new Set(state.initial.edges)
69
+ return state
70
+ },
71
+ string: async (state: ParserState) => {
72
+ throw error('Unsupported selector', { found: state.current })
73
+ },
74
+ tag: async (state: ParserState) => {
75
+ if (state.current.value !== '{' && state.current.value !== '}') {
76
+ throw error('Unsupported selector', { found: state.current })
77
+ }
78
+ return state
79
+ },
80
+ universal: noopFn,
81
+ }
82
+ const selectorsMap = new Map<string, ParserFn>(
83
+ Object.entries(selectors),
84
+ )
85
+
86
+ export const walk = async (
87
+ state: ParserState,
88
+ ): Promise<ParserState> => {
89
+ await state.cancellable()
90
+
91
+ const parserFn = selectorsMap.get(state.current.type)
92
+
93
+ if (!parserFn) {
94
+ if (state.loose) {
95
+ return state
96
+ }
97
+
98
+ throw error(
99
+ `Missing parser for query node: ${state.current.type}`,
100
+ {
101
+ found: state.current,
102
+ },
103
+ )
104
+ }
105
+ state = await parserFn(state)
106
+
107
+ // pseudo selectors handle their own sub selectors
108
+ if (
109
+ isPostcssNodeWithChildren(state.current) &&
110
+ state.current.type !== 'pseudo'
111
+ ) {
112
+ const node: PostcssNodeWithChildren = asPostcssNodeWithChildren(
113
+ state.current,
114
+ )
115
+
116
+ if (node.nodes.length) {
117
+ for (let i = 0; i < node.nodes.length; i++) {
118
+ const current = node.nodes[i]
119
+ /* c8 ignore next -- impossible but TS doesn't know that */
120
+ if (!current) continue
121
+
122
+ const childState: ParserState = {
123
+ ...state,
124
+ current,
125
+ next: node.nodes[i + 1],
126
+ prev: node.nodes[i - 1],
127
+ }
128
+ state = await walk(childState)
129
+ }
130
+ }
131
+
132
+ if (isSelectorNode(node)) {
133
+ for (const edge of state.partial.edges) {
134
+ state.collect.edges.add(edge)
135
+ }
136
+ for (const node of state.partial.nodes) {
137
+ state.collect.nodes.add(node)
138
+ }
139
+ }
140
+ }
141
+ return state
142
+ }
143
+
144
+ export type QueryOptions = {
145
+ edges: Set<EdgeLike>
146
+ nodes: Set<NodeLike>
147
+ importers: Set<NodeLike>
148
+ retries?: number
149
+ securityArchive: SecurityArchiveLike | undefined
150
+ hostContexts?: HostContextsMap
151
+ diffFiles?: DiffFilesProvider
152
+ }
153
+
154
+ // A list of known security selectors that rely on
155
+ // data from the security-archive in order to work
156
+ const securitySelectors = new Set([
157
+ ':abandoned',
158
+ ':confused',
159
+ ':cve',
160
+ ':cwe',
161
+ ':debug',
162
+ ':deprecated',
163
+ ':dynamic',
164
+ ':entropic',
165
+ ':env',
166
+ ':eval',
167
+ ':fs',
168
+ ':license',
169
+ ':malware',
170
+ ':minified',
171
+ ':native',
172
+ ':network',
173
+ ':obfuscated',
174
+ ':scanned',
175
+ ':score',
176
+ ':sev',
177
+ ':severity',
178
+ ':shell',
179
+ ':shrinkwrap',
180
+ ':squat',
181
+ ':suspicious',
182
+ ':tracker',
183
+ ':trivial',
184
+ ':undesirable',
185
+ ':unknown',
186
+ ':unmaintained',
187
+ ':unpopular',
188
+ ':unstable',
189
+ ':vuln',
190
+ ':vulnerable',
191
+ ])
192
+
193
+ const setMethodToJSON = (node: QueryResponseNode) => {
194
+ const { toJSON } = node
195
+ const insights = node.insights
196
+ node.toJSON = () => ({
197
+ ...toJSON.call(node),
198
+ insights,
199
+ })
200
+ }
201
+
202
+ /**
203
+ * The Query class is used to search the graph for nodes and edges
204
+ * using the Dependency Selector Syntax (DSS).
205
+ */
206
+ export class Query {
207
+ #cache: Map<string, QueryResponse>
208
+ #diffFiles: DiffFilesProvider | undefined
209
+ #edges: Set<EdgeLike>
210
+ #nodes: Set<NodeLike>
211
+ #importers: Set<NodeLike>
212
+ #retries: number
213
+ #securityArchive: SecurityArchiveLike | undefined
214
+ #hostContexts: HostContextsMap | undefined
215
+
216
+ /**
217
+ * Helper method to determine if a given query string is using any of
218
+ * the known security selectors. This is useful so that operations can
219
+ * skip hydrating the security archive if it's not needed.
220
+ */
221
+ static hasSecuritySelectors(query: string): boolean {
222
+ for (const selector of securitySelectors) {
223
+ if (query.includes(selector)) {
224
+ return true
225
+ }
226
+ }
227
+ return false
228
+ }
229
+
230
+ /**
231
+ * Sorts an array of QueryResponse objects by specificity. Objects with
232
+ * higher idCounter values come first, if idCounter values are equal,
233
+ * then objects with higher commonCounter values come first. Otherwise,
234
+ * the original order is preserved.
235
+ */
236
+ static specificitySort(
237
+ responses: QueryResponse[],
238
+ ): QueryResponse[] {
239
+ return [...responses].sort((a, b) => {
240
+ // First compare by idCounter (higher comes first)
241
+ if (a.specificity.idCounter !== b.specificity.idCounter) {
242
+ return b.specificity.idCounter - a.specificity.idCounter
243
+ }
244
+
245
+ // If idCounter values are equal, compare by commonCounter
246
+ if (
247
+ a.specificity.commonCounter !== b.specificity.commonCounter
248
+ ) {
249
+ return (
250
+ b.specificity.commonCounter - a.specificity.commonCounter
251
+ )
252
+ }
253
+
254
+ // If both counters are equal, preserve original order
255
+ return 0
256
+ })
257
+ }
258
+
259
+ constructor({
260
+ edges,
261
+ nodes,
262
+ importers,
263
+ retries,
264
+ securityArchive,
265
+ hostContexts,
266
+ diffFiles,
267
+ }: QueryOptions) {
268
+ this.#cache = new Map()
269
+ this.#diffFiles = diffFiles
270
+ this.#edges = edges
271
+ this.#nodes = nodes
272
+ this.#importers = importers
273
+ this.#retries = retries ?? 3
274
+ this.#securityArchive = securityArchive
275
+ this.#hostContexts = hostContexts
276
+ }
277
+
278
+ #getQueryResponseEdges(_edges: Set<EdgeLike>): QueryResponseEdge[] {
279
+ return Array.from(_edges) as QueryResponseEdge[]
280
+ }
281
+
282
+ #getQueryResponseNodes(_nodes: Set<NodeLike>): QueryResponseNode[] {
283
+ const nodes = Array.from(_nodes) as QueryResponseNode[]
284
+ for (const node of nodes) {
285
+ const securityArchiveEntry = this.#securityArchive?.get(node.id)
286
+
287
+ // if a security archive entry is not found then the insights object
288
+ // should just be empty with scanned=false
289
+ if (!securityArchiveEntry) {
290
+ node.insights = {
291
+ scanned: false,
292
+ }
293
+
294
+ setMethodToJSON(node)
295
+ continue
296
+ }
297
+
298
+ // if a security archive entry is found then we can populate the insights
299
+ node.insights = {
300
+ scanned: true,
301
+ score: securityArchiveEntry.score,
302
+ abandoned: securityArchiveEntry.alerts.some(
303
+ i => i.type === 'missingAuthor',
304
+ ),
305
+ confused: securityArchiveEntry.alerts.some(
306
+ i => i.type === 'manifestConfusion',
307
+ ),
308
+ cve: securityArchiveEntry.alerts
309
+ .map(i => i.props?.cveId)
310
+ .filter(i => i !== undefined),
311
+ cwe: Array.from(
312
+ new Set(
313
+ securityArchiveEntry.alerts
314
+ .filter(i => i.props?.cveId)
315
+ .flatMap(i => i.props?.cwes?.map(j => j.id)),
316
+ ),
317
+ ) as `CWE-${string}`[],
318
+ debug: securityArchiveEntry.alerts.some(
319
+ i => i.type === 'debugAccess',
320
+ ),
321
+ deprecated: securityArchiveEntry.alerts.some(
322
+ i => i.type === 'deprecated',
323
+ ),
324
+ dynamic: securityArchiveEntry.alerts.some(
325
+ i => i.type === 'dynamicRequire',
326
+ ),
327
+ entropic: securityArchiveEntry.alerts.some(
328
+ i => i.type === 'highEntropyStrings',
329
+ ),
330
+ env: securityArchiveEntry.alerts.some(
331
+ i => i.type === 'envVars',
332
+ ),
333
+ eval: securityArchiveEntry.alerts.some(
334
+ i => i.type === 'usesEval',
335
+ ),
336
+ fs: securityArchiveEntry.alerts.some(
337
+ i => i.type === 'filesystemAccess',
338
+ ),
339
+ license: {
340
+ unlicensed: securityArchiveEntry.alerts.some(
341
+ i => i.type === 'explicitlyUnlicensedItem',
342
+ ),
343
+ misc: securityArchiveEntry.alerts.some(
344
+ i => i.type === 'miscLicenseIssues',
345
+ ),
346
+ restricted: securityArchiveEntry.alerts.some(
347
+ i => i.type === 'nonpermissiveLicense',
348
+ ),
349
+ ambiguous: securityArchiveEntry.alerts.some(
350
+ i => i.type === 'ambiguousClassifier',
351
+ ),
352
+ copyleft: securityArchiveEntry.alerts.some(
353
+ i => i.type === 'copyleftLicense',
354
+ ),
355
+ unknown: securityArchiveEntry.alerts.some(
356
+ i => i.type === 'unidentifiedLicense',
357
+ ),
358
+ none: securityArchiveEntry.alerts.some(
359
+ i => i.type === 'noLicenseFound',
360
+ ),
361
+ exception: securityArchiveEntry.alerts.some(
362
+ i => i.type === 'licenseException',
363
+ ),
364
+ },
365
+ malware: securityArchiveEntry.alerts.some(
366
+ i => i.type === 'malware' || i.type === 'gptMalware',
367
+ ),
368
+ minified: securityArchiveEntry.alerts.some(
369
+ i => i.type === 'minifiedFile',
370
+ ),
371
+ native: securityArchiveEntry.alerts.some(
372
+ i => i.type === 'hasNativeCode',
373
+ ),
374
+ network: securityArchiveEntry.alerts.some(
375
+ i => i.type === 'networkAccess',
376
+ ),
377
+ obfuscated: securityArchiveEntry.alerts.some(
378
+ i => i.type === 'obfuscatedFile',
379
+ ),
380
+ scripts: securityArchiveEntry.alerts.some(
381
+ i => i.type === 'installScripts',
382
+ ),
383
+ severity: {
384
+ low: securityArchiveEntry.alerts.some(
385
+ i => i.type === 'mildCVE',
386
+ ),
387
+ medium: securityArchiveEntry.alerts.some(
388
+ i => i.type === 'potentialVulnerability',
389
+ ),
390
+ high: securityArchiveEntry.alerts.some(
391
+ i => i.type === 'cve',
392
+ ),
393
+ critical: securityArchiveEntry.alerts.some(
394
+ i => i.type === 'criticalCVE',
395
+ ),
396
+ },
397
+ shell: securityArchiveEntry.alerts.some(
398
+ i => i.type === 'shellAccess',
399
+ ),
400
+ shrinkwrap: securityArchiveEntry.alerts.some(
401
+ i => i.type === 'shrinkwrap',
402
+ ),
403
+ squat: {
404
+ medium: securityArchiveEntry.alerts.some(
405
+ i => i.type === 'gptDidYouMean',
406
+ ),
407
+ critical: securityArchiveEntry.alerts.some(
408
+ i => i.type === 'didYouMean',
409
+ ),
410
+ },
411
+ suspicious: securityArchiveEntry.alerts.some(
412
+ i => i.type === 'suspiciousStarActivity',
413
+ ),
414
+ tracker: securityArchiveEntry.alerts.some(
415
+ i => i.type === 'telemetry',
416
+ ),
417
+ trivial: securityArchiveEntry.alerts.some(
418
+ i => i.type === 'trivialPackage',
419
+ ),
420
+ undesirable: securityArchiveEntry.alerts.some(
421
+ i => i.type === 'troll',
422
+ ),
423
+ unknown: securityArchiveEntry.alerts.some(
424
+ i => i.type === 'newAuthor',
425
+ ),
426
+ unmaintained: securityArchiveEntry.alerts.some(
427
+ i => i.type === 'unmaintained',
428
+ ),
429
+ unpopular: securityArchiveEntry.alerts.some(
430
+ i => i.type === 'unpopularPackage',
431
+ ),
432
+ unstable: securityArchiveEntry.alerts.some(
433
+ i => i.type === 'unstableOwnership',
434
+ ),
435
+ vuln: {
436
+ low: securityArchiveEntry.alerts.some(
437
+ i => i.type === 'mildCVE' || i.type === 'gptAnomaly',
438
+ ),
439
+ medium: securityArchiveEntry.alerts.some(
440
+ i =>
441
+ i.type === 'potentialVulnerability' ||
442
+ i.type === 'gptSecurity',
443
+ ),
444
+ high: securityArchiveEntry.alerts.some(
445
+ i => i.type === 'cve',
446
+ ),
447
+ critical: securityArchiveEntry.alerts.some(
448
+ i => i.type === 'criticalCVE',
449
+ ),
450
+ },
451
+ }
452
+
453
+ setMethodToJSON(node)
454
+ }
455
+ return nodes
456
+ }
457
+
458
+ /**
459
+ * Search the graph for nodes and edges that match the given query.
460
+ */
461
+ async search(
462
+ query: string,
463
+ {
464
+ signal,
465
+ scopeIDs = [joinDepIDTuple(['file', '.'])],
466
+ }: SearchOptions,
467
+ ): Promise<QueryResponse> {
468
+ if (!query)
469
+ return {
470
+ edges: [],
471
+ nodes: [],
472
+ importers: [],
473
+ comment: '',
474
+ specificity: { idCounter: 0, commonCounter: 0 },
475
+ }
476
+
477
+ const cachedResult = this.#cache.get(query)
478
+ if (cachedResult) {
479
+ return cachedResult
480
+ }
481
+
482
+ const nodes = this.#nodes
483
+ const edges = this.#edges
484
+ const importers = this.#importers
485
+
486
+ // includes virtual workspace edges in the searched edges
487
+ for (const importer of importers) {
488
+ if (!importer.workspaces) continue
489
+ for (const edge of importer.workspaces.values()) {
490
+ edges.add(edge)
491
+ }
492
+ }
493
+
494
+ // parse the query string into AST
495
+ const current = parse(query)
496
+ // set loose mode for the entire parse in case there are multiple selectors
497
+ // so that using invalid pseudo selectors or other query language parser
498
+ // errors won't throw an error,
499
+ // e.g: `:root > *, #a, :foo` still returns results for `:root > ` and `#a`
500
+ // while :foo is ignored
501
+ const loose = asPostcssNodeWithChildren(current).nodes.length > 1
502
+ // builds initial state and walks over it,
503
+ // retrieving the collected result
504
+ const {
505
+ collect,
506
+ comment,
507
+ importers: stateResultImporters,
508
+ specificity,
509
+ } = await walk({
510
+ cancellable: async () => {
511
+ await new Promise(resolve => {
512
+ setTimeout(resolve, 0)
513
+ })
514
+ signal.throwIfAborted()
515
+ },
516
+ current,
517
+ initial: {
518
+ nodes: new Set(nodes),
519
+ edges: new Set(edges),
520
+ },
521
+ collect: {
522
+ nodes: new Set<NodeLike>(),
523
+ edges: new Set<EdgeLike>(),
524
+ },
525
+ comment: '',
526
+ diffFiles: this.#diffFiles,
527
+ loose,
528
+ importers,
529
+ partial: { nodes, edges },
530
+ retries: this.#retries,
531
+ signal,
532
+ securityArchive: this.#securityArchive,
533
+ scopeIDs,
534
+ walk,
535
+ specificity: { idCounter: 0, commonCounter: 0 },
536
+ hostContexts: this.#hostContexts,
537
+ })
538
+
539
+ const res: QueryResponse = {
540
+ edges: this.#getQueryResponseEdges(collect.edges),
541
+ nodes: this.#getQueryResponseNodes(collect.nodes),
542
+ importers: this.#getQueryResponseNodes(stateResultImporters),
543
+ comment,
544
+ specificity,
545
+ }
546
+ this.#cache.set(query, res)
547
+ return res
548
+ }
549
+
550
+ /**
551
+ * Parses a query string in order to retrieve an array of tokens.
552
+ */
553
+ static getQueryTokens(query: string): ParsedSelectorToken[] {
554
+ if (!query) return []
555
+
556
+ const tokens: ParsedSelectorToken[] = []
557
+
558
+ const ast = (q: string) => {
559
+ try {
560
+ return parse(q)
561
+ } catch (_e) {
562
+ return ast(q.slice(0, -1))
563
+ }
564
+ }
565
+
566
+ const processNode = (node: PostcssNode) => {
567
+ for (const key of selectorsMap.keys()) {
568
+ if (node.type === key && node.type !== 'root') {
569
+ let token = `${node.spaces.before}${node.value}${node.spaces.after}`
570
+
571
+ if (isIdentifierNode(node)) {
572
+ token = `${node.spaces.before}#${node.value}${node.spaces.after}`
573
+ } else if (isSelectorNode(node)) {
574
+ token = `${node.spaces.before},${node.spaces.after}`
575
+ } else if (isAttributeNode(node)) {
576
+ token = String(
577
+ node.source?.start?.column &&
578
+ node.source.end?.column &&
579
+ `${node.spaces.before}${query.slice(node.source.start.column - 1, node.source.end.column)}${node.spaces.after}`,
580
+ )
581
+ }
582
+
583
+ if (
584
+ isPostcssNodeWithChildren(node) &&
585
+ isPseudoNode(node) &&
586
+ node.nodes.length
587
+ ) {
588
+ token = String(token.split('(')[0])
589
+ token += '('
590
+ }
591
+
592
+ if (
593
+ !isSelectorNode(node) ||
594
+ node.parent?.nodes.indexOf(node) !== 0
595
+ ) {
596
+ tokens.push({
597
+ ...node,
598
+ token,
599
+ } as ParsedSelectorToken)
600
+ }
601
+ }
602
+ }
603
+ if (isPostcssNodeWithChildren(node)) {
604
+ for (const child of node.nodes) {
605
+ processNode(child)
606
+ }
607
+ if (isPseudoNode(node) && node.nodes.length) {
608
+ tokens.push({
609
+ ...node,
610
+ token: ')' + node.spaces.after,
611
+ type: 'pseudo',
612
+ } as ParsedSelectorToken)
613
+ }
614
+ }
615
+ }
616
+
617
+ processNode(ast(query))
618
+ return tokens
619
+ }
620
+ }