@vltpkg/query 0.0.0-0.1730239248325 → 0.0.0-10

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 (218) hide show
  1. package/README.md +12 -70
  2. package/dist/esm/attribute.d.ts +1 -1
  3. package/dist/esm/attribute.d.ts.map +1 -1
  4. package/dist/esm/attribute.js +14 -5
  5. package/dist/esm/attribute.js.map +1 -1
  6. package/dist/esm/combinator.d.ts +1 -1
  7. package/dist/esm/combinator.d.ts.map +1 -1
  8. package/dist/esm/combinator.js +6 -2
  9. package/dist/esm/combinator.js.map +1 -1
  10. package/dist/esm/id.d.ts +1 -1
  11. package/dist/esm/id.d.ts.map +1 -1
  12. package/dist/esm/id.js +21 -7
  13. package/dist/esm/id.js.map +1 -1
  14. package/dist/esm/index.d.ts +22 -4
  15. package/dist/esm/index.d.ts.map +1 -1
  16. package/dist/esm/index.js +250 -17
  17. package/dist/esm/index.js.map +1 -1
  18. package/dist/esm/parser.d.ts +15 -0
  19. package/dist/esm/parser.d.ts.map +1 -0
  20. package/dist/esm/parser.js +92 -0
  21. package/dist/esm/parser.js.map +1 -0
  22. package/dist/esm/pseudo/abandoned.d.ts +7 -0
  23. package/dist/esm/pseudo/abandoned.d.ts.map +1 -0
  24. package/dist/esm/pseudo/abandoned.js +6 -0
  25. package/dist/esm/pseudo/abandoned.js.map +1 -0
  26. package/dist/esm/pseudo/attr.d.ts +18 -0
  27. package/dist/esm/pseudo/attr.d.ts.map +1 -0
  28. package/dist/esm/pseudo/attr.js +58 -0
  29. package/dist/esm/pseudo/attr.js.map +1 -0
  30. package/dist/esm/pseudo/confused.d.ts +7 -0
  31. package/dist/esm/pseudo/confused.d.ts.map +1 -0
  32. package/dist/esm/pseudo/confused.js +6 -0
  33. package/dist/esm/pseudo/confused.js.map +1 -0
  34. package/dist/esm/pseudo/cve.d.ts +12 -0
  35. package/dist/esm/pseudo/cve.d.ts.map +1 -0
  36. package/dist/esm/pseudo/cve.js +44 -0
  37. package/dist/esm/pseudo/cve.js.map +1 -0
  38. package/dist/esm/pseudo/cwe.d.ts +12 -0
  39. package/dist/esm/pseudo/cwe.d.ts.map +1 -0
  40. package/dist/esm/pseudo/cwe.js +43 -0
  41. package/dist/esm/pseudo/cwe.js.map +1 -0
  42. package/dist/esm/pseudo/debug.d.ts +7 -0
  43. package/dist/esm/pseudo/debug.d.ts.map +1 -0
  44. package/dist/esm/pseudo/debug.js +6 -0
  45. package/dist/esm/pseudo/debug.js.map +1 -0
  46. package/dist/esm/pseudo/deprecated.d.ts +7 -0
  47. package/dist/esm/pseudo/deprecated.d.ts.map +1 -0
  48. package/dist/esm/pseudo/deprecated.js +6 -0
  49. package/dist/esm/pseudo/deprecated.js.map +1 -0
  50. package/dist/esm/pseudo/dev.d.ts +6 -0
  51. package/dist/esm/pseudo/dev.d.ts.map +1 -0
  52. package/dist/esm/pseudo/dev.js +15 -0
  53. package/dist/esm/pseudo/dev.js.map +1 -0
  54. package/dist/esm/pseudo/dynamic.d.ts +7 -0
  55. package/dist/esm/pseudo/dynamic.d.ts.map +1 -0
  56. package/dist/esm/pseudo/dynamic.js +6 -0
  57. package/dist/esm/pseudo/dynamic.js.map +1 -0
  58. package/dist/esm/pseudo/empty.d.ts +7 -0
  59. package/dist/esm/pseudo/empty.d.ts.map +1 -0
  60. package/dist/esm/pseudo/empty.js +14 -0
  61. package/dist/esm/pseudo/empty.js.map +1 -0
  62. package/dist/esm/pseudo/entropic.d.ts +7 -0
  63. package/dist/esm/pseudo/entropic.d.ts.map +1 -0
  64. package/dist/esm/pseudo/entropic.js +6 -0
  65. package/dist/esm/pseudo/entropic.js.map +1 -0
  66. package/dist/esm/pseudo/env.d.ts +7 -0
  67. package/dist/esm/pseudo/env.d.ts.map +1 -0
  68. package/dist/esm/pseudo/env.js +6 -0
  69. package/dist/esm/pseudo/env.js.map +1 -0
  70. package/dist/esm/pseudo/eval.d.ts +7 -0
  71. package/dist/esm/pseudo/eval.d.ts.map +1 -0
  72. package/dist/esm/pseudo/eval.js +6 -0
  73. package/dist/esm/pseudo/eval.js.map +1 -0
  74. package/dist/esm/pseudo/fs.d.ts +7 -0
  75. package/dist/esm/pseudo/fs.d.ts.map +1 -0
  76. package/dist/esm/pseudo/fs.js +6 -0
  77. package/dist/esm/pseudo/fs.js.map +1 -0
  78. package/dist/esm/pseudo/helpers.d.ts +35 -0
  79. package/dist/esm/pseudo/helpers.d.ts.map +1 -0
  80. package/dist/esm/pseudo/helpers.js +69 -0
  81. package/dist/esm/pseudo/helpers.js.map +1 -0
  82. package/dist/esm/pseudo/license.d.ts +12 -0
  83. package/dist/esm/pseudo/license.d.ts.map +1 -0
  84. package/dist/esm/pseudo/license.js +58 -0
  85. package/dist/esm/pseudo/license.js.map +1 -0
  86. package/dist/esm/pseudo/link.d.ts +9 -0
  87. package/dist/esm/pseudo/link.d.ts.map +1 -0
  88. package/dist/esm/pseudo/link.js +25 -0
  89. package/dist/esm/pseudo/link.js.map +1 -0
  90. package/dist/esm/pseudo/malware.d.ts +14 -0
  91. package/dist/esm/pseudo/malware.d.ts.map +1 -0
  92. package/dist/esm/pseudo/malware.js +165 -0
  93. package/dist/esm/pseudo/malware.js.map +1 -0
  94. package/dist/esm/pseudo/minified.d.ts +7 -0
  95. package/dist/esm/pseudo/minified.d.ts.map +1 -0
  96. package/dist/esm/pseudo/minified.js +6 -0
  97. package/dist/esm/pseudo/minified.js.map +1 -0
  98. package/dist/esm/pseudo/missing.d.ts +8 -0
  99. package/dist/esm/pseudo/missing.d.ts.map +1 -0
  100. package/dist/esm/pseudo/missing.js +15 -0
  101. package/dist/esm/pseudo/missing.js.map +1 -0
  102. package/dist/esm/pseudo/native.d.ts +7 -0
  103. package/dist/esm/pseudo/native.d.ts.map +1 -0
  104. package/dist/esm/pseudo/native.js +6 -0
  105. package/dist/esm/pseudo/native.js.map +1 -0
  106. package/dist/esm/pseudo/network.d.ts +7 -0
  107. package/dist/esm/pseudo/network.d.ts.map +1 -0
  108. package/dist/esm/pseudo/network.js +6 -0
  109. package/dist/esm/pseudo/network.js.map +1 -0
  110. package/dist/esm/pseudo/obfuscated.d.ts +7 -0
  111. package/dist/esm/pseudo/obfuscated.d.ts.map +1 -0
  112. package/dist/esm/pseudo/obfuscated.js +6 -0
  113. package/dist/esm/pseudo/obfuscated.js.map +1 -0
  114. package/dist/esm/pseudo/optional.d.ts +6 -0
  115. package/dist/esm/pseudo/optional.d.ts.map +1 -0
  116. package/dist/esm/pseudo/optional.js +15 -0
  117. package/dist/esm/pseudo/optional.js.map +1 -0
  118. package/dist/esm/pseudo/outdated.d.ts +54 -0
  119. package/dist/esm/pseudo/outdated.d.ts.map +1 -0
  120. package/dist/esm/pseudo/outdated.js +212 -0
  121. package/dist/esm/pseudo/outdated.js.map +1 -0
  122. package/dist/esm/pseudo/peer.d.ts +6 -0
  123. package/dist/esm/pseudo/peer.d.ts.map +1 -0
  124. package/dist/esm/pseudo/peer.js +15 -0
  125. package/dist/esm/pseudo/peer.js.map +1 -0
  126. package/dist/esm/pseudo/private.d.ts +7 -0
  127. package/dist/esm/pseudo/private.d.ts.map +1 -0
  128. package/dist/esm/pseudo/private.js +16 -0
  129. package/dist/esm/pseudo/private.js.map +1 -0
  130. package/dist/esm/pseudo/prod.d.ts +6 -0
  131. package/dist/esm/pseudo/prod.d.ts.map +1 -0
  132. package/dist/esm/pseudo/prod.js +15 -0
  133. package/dist/esm/pseudo/prod.js.map +1 -0
  134. package/dist/esm/pseudo/published.d.ts +40 -0
  135. package/dist/esm/pseudo/published.d.ts.map +1 -0
  136. package/dist/esm/pseudo/published.js +159 -0
  137. package/dist/esm/pseudo/published.js.map +1 -0
  138. package/dist/esm/pseudo/scanned.d.ts +9 -0
  139. package/dist/esm/pseudo/scanned.d.ts.map +1 -0
  140. package/dist/esm/pseudo/scanned.js +17 -0
  141. package/dist/esm/pseudo/scanned.js.map +1 -0
  142. package/dist/esm/pseudo/score.d.ts +15 -0
  143. package/dist/esm/pseudo/score.d.ts.map +1 -0
  144. package/dist/esm/pseudo/score.js +119 -0
  145. package/dist/esm/pseudo/score.js.map +1 -0
  146. package/dist/esm/pseudo/scripts.d.ts +7 -0
  147. package/dist/esm/pseudo/scripts.d.ts.map +1 -0
  148. package/dist/esm/pseudo/scripts.js +6 -0
  149. package/dist/esm/pseudo/scripts.js.map +1 -0
  150. package/dist/esm/pseudo/semver.d.ts +16 -0
  151. package/dist/esm/pseudo/semver.d.ts.map +1 -0
  152. package/dist/esm/pseudo/semver.js +166 -0
  153. package/dist/esm/pseudo/semver.js.map +1 -0
  154. package/dist/esm/pseudo/severity.d.ts +14 -0
  155. package/dist/esm/pseudo/severity.d.ts.map +1 -0
  156. package/dist/esm/pseudo/severity.js +160 -0
  157. package/dist/esm/pseudo/severity.js.map +1 -0
  158. package/dist/esm/pseudo/shell.d.ts +7 -0
  159. package/dist/esm/pseudo/shell.d.ts.map +1 -0
  160. package/dist/esm/pseudo/shell.js +6 -0
  161. package/dist/esm/pseudo/shell.js.map +1 -0
  162. package/dist/esm/pseudo/shrinkwrap.d.ts +7 -0
  163. package/dist/esm/pseudo/shrinkwrap.d.ts.map +1 -0
  164. package/dist/esm/pseudo/shrinkwrap.js +6 -0
  165. package/dist/esm/pseudo/shrinkwrap.js.map +1 -0
  166. package/dist/esm/pseudo/squat.d.ts +14 -0
  167. package/dist/esm/pseudo/squat.d.ts.map +1 -0
  168. package/dist/esm/pseudo/squat.js +161 -0
  169. package/dist/esm/pseudo/squat.js.map +1 -0
  170. package/dist/esm/pseudo/suspicious.d.ts +7 -0
  171. package/dist/esm/pseudo/suspicious.d.ts.map +1 -0
  172. package/dist/esm/pseudo/suspicious.js +6 -0
  173. package/dist/esm/pseudo/suspicious.js.map +1 -0
  174. package/dist/esm/pseudo/tracker.d.ts +7 -0
  175. package/dist/esm/pseudo/tracker.d.ts.map +1 -0
  176. package/dist/esm/pseudo/tracker.js +6 -0
  177. package/dist/esm/pseudo/tracker.js.map +1 -0
  178. package/dist/esm/pseudo/trivial.d.ts +7 -0
  179. package/dist/esm/pseudo/trivial.d.ts.map +1 -0
  180. package/dist/esm/pseudo/trivial.js +6 -0
  181. package/dist/esm/pseudo/trivial.js.map +1 -0
  182. package/dist/esm/pseudo/undesirable.d.ts +7 -0
  183. package/dist/esm/pseudo/undesirable.d.ts.map +1 -0
  184. package/dist/esm/pseudo/undesirable.js +6 -0
  185. package/dist/esm/pseudo/undesirable.js.map +1 -0
  186. package/dist/esm/pseudo/unknown.d.ts +7 -0
  187. package/dist/esm/pseudo/unknown.d.ts.map +1 -0
  188. package/dist/esm/pseudo/unknown.js +6 -0
  189. package/dist/esm/pseudo/unknown.js.map +1 -0
  190. package/dist/esm/pseudo/unmaintained.d.ts +7 -0
  191. package/dist/esm/pseudo/unmaintained.d.ts.map +1 -0
  192. package/dist/esm/pseudo/unmaintained.js +6 -0
  193. package/dist/esm/pseudo/unmaintained.js.map +1 -0
  194. package/dist/esm/pseudo/unpopular.d.ts +7 -0
  195. package/dist/esm/pseudo/unpopular.d.ts.map +1 -0
  196. package/dist/esm/pseudo/unpopular.js +6 -0
  197. package/dist/esm/pseudo/unpopular.js.map +1 -0
  198. package/dist/esm/pseudo/unstable.d.ts +7 -0
  199. package/dist/esm/pseudo/unstable.d.ts.map +1 -0
  200. package/dist/esm/pseudo/unstable.js +6 -0
  201. package/dist/esm/pseudo/unstable.js.map +1 -0
  202. package/dist/esm/pseudo/workspace.d.ts +6 -0
  203. package/dist/esm/pseudo/workspace.d.ts.map +1 -0
  204. package/dist/esm/pseudo/workspace.js +15 -0
  205. package/dist/esm/pseudo/workspace.js.map +1 -0
  206. package/dist/esm/pseudo.d.ts +1 -8
  207. package/dist/esm/pseudo.d.ts.map +1 -1
  208. package/dist/esm/pseudo.js +115 -122
  209. package/dist/esm/pseudo.js.map +1 -1
  210. package/dist/esm/types.d.ts +85 -8
  211. package/dist/esm/types.d.ts.map +1 -1
  212. package/dist/esm/types.js +29 -16
  213. package/dist/esm/types.js.map +1 -1
  214. package/package.json +28 -19
  215. package/dist/esm/class.d.ts +0 -6
  216. package/dist/esm/class.d.ts.map +0 -1
  217. package/dist/esm/class.js +0 -127
  218. package/dist/esm/class.js.map +0 -1
package/README.md CHANGED
@@ -1,14 +1,18 @@
1
- # @vltkpkg/query
1
+ ![query](https://github.com/user-attachments/assets/5b4802b7-7567-4f50-8f77-7ee398f58d43)
2
+
3
+ # @vltpkg/query
2
4
 
3
5
  The **vlt** query syntax engine.
4
6
 
7
+ **[Usage](#usage)** · **[Examples](#examples)**
8
+
5
9
  ## Usage
6
10
 
7
11
  ```js
8
12
  import { Query } from '@vltpkg/query'
9
13
 
10
- const query = new Query({ nodes })
11
- query.search(':root > *')
14
+ const query = new Query({ nodes, specOptions, securityArchive })
15
+ const res = await query.search(':root > *')
12
16
  ```
13
17
 
14
18
  ## Examples
@@ -19,72 +23,10 @@ Querying nodes from a local `node_modules` folder.
19
23
  import { actual } from '@vltpkg/graph'
20
24
  import { Query } from '@vltpkg/query'
21
25
 
26
+ const specOptions = {
27
+ registry: 'https://registry.npmjs.org',
28
+ }
22
29
  const graph = await actual.load({ projectRoot: process.cwd() })
23
- const query = new Query([...graph.nodes.values()])
24
- query.search(':root > *')
30
+ const query = new Query({ graph, specOptions })
31
+ const res = await query.search(':root > *')
25
32
  ```
26
-
27
- ## Supported Syntax Reference
28
-
29
- The vlt query syntax enable usage of css-selector-like strings to filter
30
- packages.
31
-
32
- Many of the common elements of the CSS language are available, notably:
33
-
34
- - `*` Universal selector, matches all selected items.
35
- - `&` Nesting selector, allows for nesting selectors.
36
- - `{}` Curly braces, when querying can be used to nest selectors.
37
-
38
- Split by group of selectors below is the complete reference to supported
39
- elements.
40
-
41
- ### Attribute selectors
42
-
43
- Attribute selectors are used to match a value found in the `package.json`
44
- metadata for each of the nodes being queried to a arbitrary value you choose.
45
-
46
- - `[attr]` Matches elements with an `attr` property in its `package.json`.
47
- - `[attr=value]` Matches elements with a property `attr` whose value is exactly `value`.
48
- - `[attr^=value]` Matches elements with a property `attr` whose value starts with `value`.
49
- - `[attr$=value]` Matches elements with a property `attr` whose value ends with `value`.
50
- - `[attr~=value]` Matches elements with a property `attr` whose value is a whitespace-separated list of words, one of which is exactly `value`.
51
- - `[attr|=value]` Matches elements with a property `attr` whose value is either `value` or starts with `value-`.
52
- - `[attr*=value]` Matches elements with a property `attr`.
53
- - `[attr=value i]` Case-insensitive flag, setting it will cause any comparison to be case-insensitive.
54
- - `[attr=value s]` Case-sensitive flag, setting it will cause comparisons to be case-sensitive, this is the default behavior.
55
-
56
- ### Class selectors
57
-
58
- - `.prod` Matches prod dependencies to your current project.
59
- - `.dev` Matches packages that are only used as dev dependencies in your current project.
60
- - `.optional` Matches packages that are optional to your current project.
61
- - `.peer` Matches peer dependencies to your current project.
62
- - `.workspace` Matches the current project worksacpes (listed in your `vlt-workspaces.json` file).
63
-
64
- ### Combinators
65
-
66
- - `>` Child combinator, matches packages that are direct dependencies of the previously selected nodes.
67
- - ` ` Descendant combinator, matches all packages that are direct & transitive dependencies of the previously selected nodes.
68
- - `~` Sibling combinator, matches packages that are direct dependencies of all dependents of the previously selected nodes.
69
-
70
- ### ID Selectors
71
-
72
- Identifiers are a shortcut to retrieving packages by name, unfortunately this shortcut only works for unscoped packages, with that in mind it's advised to rely on using **Attribute selectors** (showed above) instead.
73
-
74
- e.g: `#foo` is the same as `[name=foo]`
75
-
76
- ### Pseudo class selectors
77
-
78
- - `:attr(key, [attr=value])` The attribute pseudo-class allows for selecting packages based on nested properties of its `package.json` metadata. As an example, here is a query that filters only packages that declares an optional peer dependency named `foo`: `:attr(peerDependenciesMeta, foo, [optional=true])`
79
- - `:empty` Matches packages that have no dependencies installed.
80
- - `:has(<selector-list>)` Matches only packages that have valid results for the selector expression used. As an example, here is a query that matches all packages that have a peer dependency on `react`: `:has(.peer[name=react])`
81
- - `:is(<forgiving-selector-list>)` Useful for writing large selectors in a more compact form, the `:is()` pseudo-class takes a selector list as its arguments and selects any element that can be selected by one of the selectors in that list. As an example, let's say I want to select packages named `a` & `b` that are direct dependencies of my project root: `:root > [name=a], :root > [name=b]` using the `:is()` pseudo-class, that same expression can be shortened to: `:root > :is([name=a], [name=b])`. Similar to the css pseudo-class of the same name, this selector has a forgiving behavior regarding its nested selector list ignoring any usage of non-existing ids, classes, combinators, operators and pseudo-selectors.
82
- - `:not(<selector-list>)` Negation pseudo-class, select packages that do not match a list of selectors.
83
- - `:private` Matches packages that have the property `private` set on their `package.json` file.
84
- - `:type(registry|file|git|remote|workspace)` Matches packages based on their type, e.g, to retrieve all git dependencies: `:type(git)`.
85
-
86
- ### Pseudo Elements
87
-
88
- - `:project` Returns both the root node (as defined below) along with any workspace declared in your project.
89
- - `:root` Returns the root node, that represents the package defined at the top-level `package.json` of your project folder.
90
- - `:scope` Returns the current scope of a given selector
@@ -1,5 +1,5 @@
1
1
  import type { NodeLike } from '@vltpkg/graph';
2
- import { ParserState } from './types.js';
2
+ import type { ParserState } from './types.ts';
3
3
  export type ComparatorFn = (attr: string, value?: string) => boolean;
4
4
  /**
5
5
  * Retrieve the {@link Manifest} values found at the given `properties`
@@ -1 +1 @@
1
- {"version":3,"file":"attribute.d.ts","sourceRoot":"","sources":["../../src/attribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAmB,WAAW,EAAE,MAAM,YAAY,CAAA;AAEzD,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;AAEpE;;;GAGG;AACH,eAAO,MAAM,yBAAyB,SAC9B,QAAQ,cACF,MAAM,EAAE,aACT,MAAM,KAChB,MAAM,EAAE,GAAG,SA+Db,CAAA;AAID,eAAO,MAAM,gBAAgB,UACpB,WAAW,cACN,YAAY,GAAG,SAAS,SAC7B,MAAM,gBACC,MAAM,eACP,OAAO,qBACF,MAAM,EAAE,KACzB,WA8CF,CAAA;AAcD,eAAO,MAAM,qBAAqB,2BAEjC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,UACb,WAAW,KACjB,OAAO,CAAC,WAAW,CAuBrB,CAAA"}
1
+ {"version":3,"file":"attribute.d.ts","sourceRoot":"","sources":["../../src/attribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAG7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;AAOpE;;;GAGG;AACH,eAAO,MAAM,yBAAyB,SAC9B,QAAQ,cACF,MAAM,EAAE,aACT,MAAM,KAChB,MAAM,EAAE,GAAG,SA+Db,CAAA;AAID,eAAO,MAAM,gBAAgB,UACpB,WAAW,cACN,YAAY,GAAG,SAAS,SAC7B,MAAM,gBACC,MAAM,eACP,OAAO,qBACF,MAAM,EAAE,KACzB,WAgDF,CAAA;AAcD,eAAO,MAAM,qBAAqB,2BAEjC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,UACb,WAAW,KACjB,OAAO,CAAC,WAAW,CAyBrB,CAAA"}
@@ -1,5 +1,9 @@
1
1
  import { error } from '@vltpkg/error-cause';
2
- import { asAttributeNode } from './types.js';
2
+ import { asAttributeNode } from "./types.js";
3
+ // JSONField has a mapped type constituent that would coerce to [object Object]
4
+ // when stringified, which is what we want in this case.
5
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
6
+ const jsonFieldToString = (v) => String(v);
3
7
  /**
4
8
  * Retrieve the {@link Manifest} values found at the given `properties`
5
9
  * location for a given {@link Node}.
@@ -55,11 +59,11 @@ export const getManifestPropertyValues = (node, properties, attribute) => {
55
59
  for (const prop of props) {
56
60
  if (Array.isArray(prop)) {
57
61
  for (const p of prop) {
58
- collect.add(p ? String(p) : '');
62
+ collect.add(p ? jsonFieldToString(p) : '');
59
63
  }
60
64
  }
61
65
  else {
62
- collect.add(String(prop));
66
+ collect.add(jsonFieldToString(prop));
63
67
  }
64
68
  }
65
69
  return [...collect];
@@ -67,7 +71,9 @@ export const getManifestPropertyValues = (node, properties, attribute) => {
67
71
  // decorator style of function that will filter `ParserState` results
68
72
  // based on a provided `comparator` function
69
73
  export const filterAttributes = (state, comparator, value, propertyName, insensitive, prefixProperties = []) => {
70
- const check = (attr) => comparator?.(insensitive ? String(attr).toLowerCase() : String(attr), insensitive ? value.toLowerCase() : value);
74
+ const check = (attr) => comparator?.(insensitive ?
75
+ jsonFieldToString(attr).toLowerCase()
76
+ : jsonFieldToString(attr), insensitive ? value.toLowerCase() : value);
71
77
  const deleteNode = (node) => {
72
78
  for (const edge of node.edgesIn) {
73
79
  state.partial.edges.delete(edge);
@@ -115,13 +121,16 @@ export const attributeSelectorsMap = new Map(Object.entries(attributeSelectors))
115
121
  * Parse attributes selectors, e.g: `[name]`, `[name=value]`, etc
116
122
  */
117
123
  export const attribute = async (state) => {
124
+ await state.cancellable();
118
125
  const curr = asAttributeNode(state.current);
119
126
  const operatorFn = attributeSelectorsMap.get(String(curr.operator));
120
127
  if (!operatorFn) {
121
128
  if (state.loose) {
122
129
  return state;
123
130
  }
124
- throw new Error(`Unsupported attribute operator: ${curr.operator}`);
131
+ throw error(`Unsupported attribute operator: ${curr.operator}`, {
132
+ found: state.current,
133
+ });
125
134
  }
126
135
  const value = curr.value || '';
127
136
  const propertyName = curr.attribute;
@@ -1 +1 @@
1
- {"version":3,"file":"attribute.js","sourceRoot":"","sources":["../../src/attribute.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { NodeLike } from '@vltpkg/graph'\nimport type { JSONField } from '@vltpkg/types'\nimport { asAttributeNode, ParserState } from './types.js'\n\nexport type ComparatorFn = (attr: string, value?: string) => boolean\n\n/**\n * Retrieve the {@link Manifest} values found at the given `properties`\n * location for a given {@link Node}.\n */\nexport const getManifestPropertyValues = (\n node: NodeLike,\n properties: string[],\n attribute: string,\n): string[] | undefined => {\n if (!node.manifest) return\n\n const traverse = new Set<JSONField>([node.manifest as JSONField])\n const props = new Set<JSONField>()\n for (const key of properties) {\n for (const prop of traverse) {\n /* c8 ignore start - should be impossible */\n if (!prop) {\n throw error('failed to find nested property in :attr', {\n found: properties,\n })\n }\n /* c8 ignore stop */\n\n // expand the result list to include nested array values\n if (Array.isArray(prop)) {\n for (const p of prop) {\n traverse.add(p)\n }\n continue\n }\n\n // guard for inspecting keys of objects next\n if (\n typeof prop === 'string' ||\n typeof prop === 'number' ||\n typeof prop === 'boolean'\n ) {\n continue\n }\n\n // assign next value when found\n if (key in prop) {\n const nextValue = prop[key]\n if (nextValue) {\n if (key === attribute) {\n props.add(nextValue)\n } else {\n traverse.delete(prop)\n traverse.add(nextValue)\n }\n }\n }\n }\n }\n // if no value was found after trying a given key\n // then there's nothing to be collected\n if (!props.size) return\n\n // expand the result to include array values\n const collect = new Set<string>()\n for (const prop of props) {\n if (Array.isArray(prop)) {\n for (const p of prop) {\n collect.add(p ? String(p) : '')\n }\n } else {\n collect.add(String(prop))\n }\n }\n\n return [...collect]\n}\n\n// decorator style of function that will filter `ParserState` results\n// based on a provided `comparator` function\nexport const filterAttributes = (\n state: ParserState,\n comparator: ComparatorFn | undefined,\n value: string,\n propertyName: string,\n insensitive: boolean,\n prefixProperties: string[] = [],\n): ParserState => {\n const check = (attr: JSONField) =>\n comparator?.(\n insensitive ? String(attr).toLowerCase() : String(attr),\n insensitive ? value.toLowerCase() : value,\n )\n const deleteNode = (node: NodeLike) => {\n for (const edge of node.edgesIn) {\n state.partial.edges.delete(edge)\n }\n state.partial.nodes.delete(node)\n }\n\n for (const node of state.partial.nodes) {\n const prefixes =\n prefixProperties.length ? prefixProperties : [propertyName]\n const attrs = getManifestPropertyValues(\n node,\n prefixes,\n propertyName,\n )\n\n // if no attribute value was found, that means the attribute won't match\n if (!attrs?.length) {\n deleteNode(node)\n continue\n }\n\n // if the node attribute value won't match, then remove the node\n if (comparator && !attrs.some(check)) {\n deleteNode(node)\n }\n }\n\n for (const edge of state.partial.edges) {\n // edge.name is a special case in order\n // to be able to match missing nodes by name\n if (propertyName === 'name' && check(edge.name)) {\n continue\n }\n // remove any remaining dangling edge\n if (!edge.to) {\n state.partial.edges.delete(edge)\n }\n }\n return state\n}\n\n// ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors\nconst attributeSelectors: Record<string, ComparatorFn> = {\n '=': (attr: string, value = '') => attr === value,\n '^=': (attr: string, value = '') => attr.startsWith(value),\n '$=': (attr: string, value = '') => attr.endsWith(value),\n '~=': (attr: string, value = '') =>\n new Set<string>(attr.match(/\\w+/g)).has(value),\n '*=': (attr: string, value = '') => attr.includes(value),\n '|=': (attr: string, value = '') =>\n attr === value || attr.startsWith(`${value}-`),\n undefined: (attr: string) => !!attr,\n}\nexport const attributeSelectorsMap = new Map<string, ComparatorFn>(\n Object.entries(attributeSelectors),\n)\n\n/**\n * Parse attributes selectors, e.g: `[name]`, `[name=value]`, etc\n */\nexport const attribute = async (\n state: ParserState,\n): Promise<ParserState> => {\n const curr = asAttributeNode(state.current)\n const operatorFn = attributeSelectorsMap.get(String(curr.operator))\n if (!operatorFn) {\n if (state.loose) {\n return state\n }\n\n throw new Error(\n `Unsupported attribute operator: ${curr.operator}`,\n )\n }\n\n const value = curr.value || ''\n const propertyName = curr.attribute\n const insensitive = !!curr.insensitive\n return filterAttributes(\n state,\n operatorFn,\n value,\n propertyName,\n insensitive,\n )\n}\n"]}
1
+ {"version":3,"file":"attribute.js","sourceRoot":"","sources":["../../src/attribute.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { NodeLike } from '@vltpkg/graph'\nimport type { JSONField, Manifest } from '@vltpkg/types'\nimport { asAttributeNode } from './types.ts'\nimport type { ParserState } from './types.ts'\n\nexport type ComparatorFn = (attr: string, value?: string) => boolean\n\n// JSONField has a mapped type constituent that would coerce to [object Object]\n// when stringified, which is what we want in this case.\n// eslint-disable-next-line @typescript-eslint/no-base-to-string\nconst jsonFieldToString = (v: JSONField) => String(v)\n\n/**\n * Retrieve the {@link Manifest} values found at the given `properties`\n * location for a given {@link Node}.\n */\nexport const getManifestPropertyValues = (\n node: NodeLike,\n properties: string[],\n attribute: string,\n): string[] | undefined => {\n if (!node.manifest) return\n\n const traverse = new Set<JSONField>([node.manifest as JSONField])\n const props = new Set<JSONField>()\n for (const key of properties) {\n for (const prop of traverse) {\n /* c8 ignore start - should be impossible */\n if (!prop) {\n throw error('failed to find nested property in :attr', {\n found: properties,\n })\n }\n /* c8 ignore stop */\n\n // expand the result list to include nested array values\n if (Array.isArray(prop)) {\n for (const p of prop) {\n traverse.add(p)\n }\n continue\n }\n\n // guard for inspecting keys of objects next\n if (\n typeof prop === 'string' ||\n typeof prop === 'number' ||\n typeof prop === 'boolean'\n ) {\n continue\n }\n\n // assign next value when found\n if (key in prop) {\n const nextValue = prop[key]\n if (nextValue) {\n if (key === attribute) {\n props.add(nextValue)\n } else {\n traverse.delete(prop)\n traverse.add(nextValue)\n }\n }\n }\n }\n }\n // if no value was found after trying a given key\n // then there's nothing to be collected\n if (!props.size) return\n\n // expand the result to include array values\n const collect = new Set<string>()\n for (const prop of props) {\n if (Array.isArray(prop)) {\n for (const p of prop) {\n collect.add(p ? jsonFieldToString(p) : '')\n }\n } else {\n collect.add(jsonFieldToString(prop))\n }\n }\n\n return [...collect]\n}\n\n// decorator style of function that will filter `ParserState` results\n// based on a provided `comparator` function\nexport const filterAttributes = (\n state: ParserState,\n comparator: ComparatorFn | undefined,\n value: string,\n propertyName: string,\n insensitive: boolean,\n prefixProperties: string[] = [],\n): ParserState => {\n const check = (attr: JSONField) =>\n comparator?.(\n insensitive ?\n jsonFieldToString(attr).toLowerCase()\n : jsonFieldToString(attr),\n insensitive ? value.toLowerCase() : value,\n )\n const deleteNode = (node: NodeLike) => {\n for (const edge of node.edgesIn) {\n state.partial.edges.delete(edge)\n }\n state.partial.nodes.delete(node)\n }\n\n for (const node of state.partial.nodes) {\n const prefixes =\n prefixProperties.length ? prefixProperties : [propertyName]\n const attrs = getManifestPropertyValues(\n node,\n prefixes,\n propertyName,\n )\n\n // if no attribute value was found, that means the attribute won't match\n if (!attrs?.length) {\n deleteNode(node)\n continue\n }\n\n // if the node attribute value won't match, then remove the node\n if (comparator && !attrs.some(check)) {\n deleteNode(node)\n }\n }\n\n for (const edge of state.partial.edges) {\n // edge.name is a special case in order\n // to be able to match missing nodes by name\n if (propertyName === 'name' && check(edge.name)) {\n continue\n }\n // remove any remaining dangling edge\n if (!edge.to) {\n state.partial.edges.delete(edge)\n }\n }\n return state\n}\n\n// ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors\nconst attributeSelectors: Record<string, ComparatorFn> = {\n '=': (attr: string, value = '') => attr === value,\n '^=': (attr: string, value = '') => attr.startsWith(value),\n '$=': (attr: string, value = '') => attr.endsWith(value),\n '~=': (attr: string, value = '') =>\n new Set<string>(attr.match(/\\w+/g)).has(value),\n '*=': (attr: string, value = '') => attr.includes(value),\n '|=': (attr: string, value = '') =>\n attr === value || attr.startsWith(`${value}-`),\n undefined: (attr: string) => !!attr,\n}\nexport const attributeSelectorsMap = new Map<string, ComparatorFn>(\n Object.entries(attributeSelectors),\n)\n\n/**\n * Parse attributes selectors, e.g: `[name]`, `[name=value]`, etc\n */\nexport const attribute = async (\n state: ParserState,\n): Promise<ParserState> => {\n await state.cancellable()\n\n const curr = asAttributeNode(state.current)\n const operatorFn = attributeSelectorsMap.get(String(curr.operator))\n if (!operatorFn) {\n if (state.loose) {\n return state\n }\n\n throw error(`Unsupported attribute operator: ${curr.operator}`, {\n found: state.current,\n })\n }\n\n const value = curr.value || ''\n const propertyName = curr.attribute\n const insensitive = !!curr.insensitive\n return filterAttributes(\n state,\n operatorFn,\n value,\n propertyName,\n insensitive,\n )\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type ParserState } from './types.js';
1
+ import type { ParserState } from './types.ts';
2
2
  /**
3
3
  * Parse css-style combinators, e.g: `>`, `~` and ` `
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"combinator.d.ts","sourceRoot":"","sources":["../../src/combinator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,YAAY,CAAA;AA6GnB;;GAEG;AACH,eAAO,MAAM,UAAU,UAAiB,WAAW,yBAYlD,CAAA"}
1
+ {"version":3,"file":"combinator.d.ts","sourceRoot":"","sources":["../../src/combinator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,YAAY,CAAA;AA8GvD;;GAEG;AACH,eAAO,MAAM,UAAU,UAAiB,WAAW,yBAgBlD,CAAA"}
@@ -1,4 +1,5 @@
1
- import { asCombinatorNode, } from './types.js';
1
+ import { asCombinatorNode } from "./types.js";
2
+ import { error } from '@vltpkg/error-cause';
2
3
  /**
3
4
  * Returns a new set of nodes, containing all direct dependencies
4
5
  * of the current list of nodes used.
@@ -95,13 +96,16 @@ const combinatorSelectorsMap = new Map(Object.entries(combinatorSelectors));
95
96
  * Parse css-style combinators, e.g: `>`, `~` and ` `
96
97
  */
97
98
  export const combinator = async (state) => {
99
+ await state.cancellable();
98
100
  const curr = asCombinatorNode(state.current);
99
101
  const parserFn = curr.value && combinatorSelectorsMap.get(curr.value);
100
102
  if (!parserFn) {
101
103
  if (state.loose) {
102
104
  return state;
103
105
  }
104
- throw new Error(`Unsupported combinator: ${state.current.value}`);
106
+ throw error(`Unsupported combinator: ${state.current.value}`, {
107
+ found: state.current,
108
+ });
105
109
  }
106
110
  return parserFn(state);
107
111
  };
@@ -1 +1 @@
1
- {"version":3,"file":"combinator.js","sourceRoot":"","sources":["../../src/combinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EdgeLike, NodeLike } from '@vltpkg/graph'\nimport {\n type ParserState,\n type ParserFn,\n asCombinatorNode,\n} from './types.js'\n\n/**\n * Returns a new set of nodes, containing all direct dependencies\n * of the current list of nodes used.\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator\n */\nconst childCombinator = async (state: ParserState) => {\n const traverse = new Set(state.partial.nodes)\n state.partial.edges.clear()\n state.partial.nodes.clear()\n\n // visit direct children of the current list of nodes\n // collecting refs to these children and the edges that\n // connected them.\n for (const node of traverse) {\n for (const edge of node.edgesOut.values()) {\n if (edge.to) {\n state.partial.edges.add(edge)\n state.partial.nodes.add(edge.to)\n }\n }\n }\n\n return state\n}\n\n/**\n * Returns a new set of nodes, containing nodes that are also children\n * of all parent nodes to the current list of nodes used.\n *\n * Note: The subsequent-sibling comparator has a behavior that is\n * somehow approximative of that of its css counterpart, given that\n * in the context of dependency graphs the order of appearance is\n * not necessarily controlled by the end user. The approach for\n * this comparator is to match all siblings of a node.\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Subsequent-sibling_combinator\n */\nconst subsequentSiblingCombinator = async (state: ParserState) => {\n const traverse = new Set(state.partial.nodes)\n state.partial.edges.clear()\n state.partial.nodes.clear()\n\n // visits direct parents of the current list of node and then\n // visit their children, collecting refs to all children and edges\n // that are not in the original list of nodes.\n for (const node of traverse) {\n for (const edge of node.edgesIn) {\n const parents: IterableIterator<EdgeLike> =\n edge.from.edgesOut.values()\n for (const edge of parents) {\n if (edge.to && edge.to !== node) {\n state.partial.edges.add(edge)\n state.partial.nodes.add(edge.to)\n }\n }\n }\n }\n\n return state\n}\n\n/**\n * Returns a new set of nodes containing all nodes that are descendents\n * to items in the current list of nodes.\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_combinator\n */\nconst descendentCombinator = async (state: ParserState) => {\n // spaces between tags selectors are a noop\n if (state.prev?.type === 'tag' || state.next?.type === 'tag') {\n return state\n }\n\n const traverse = new Set<NodeLike>(state.partial.nodes)\n state.partial.edges.clear()\n state.partial.nodes.clear()\n\n // breadth-first traversal of the graph, starting from the current\n // list of nodes, collecting all nodes and edges along the way\n for (const node of traverse) {\n const children = new Set<NodeLike>()\n for (const edge of node.edgesOut.values()) {\n if (edge.to) {\n children.add(edge.to)\n state.partial.edges.add(edge)\n state.partial.nodes.add(edge.to)\n }\n }\n for (const child of children) {\n traverse.add(child)\n }\n }\n\n return state\n}\n\nconst combinatorSelectors = {\n '>': childCombinator,\n '~': subsequentSiblingCombinator,\n ' ': descendentCombinator,\n}\n\nconst combinatorSelectorsMap = new Map<string, ParserFn>(\n Object.entries(combinatorSelectors),\n)\n\n/**\n * Parse css-style combinators, e.g: `>`, `~` and ` `\n */\nexport const combinator = async (state: ParserState) => {\n const curr = asCombinatorNode(state.current)\n const parserFn =\n curr.value && combinatorSelectorsMap.get(curr.value)\n if (!parserFn) {\n if (state.loose) {\n return state\n }\n\n throw new Error(`Unsupported combinator: ${state.current.value}`)\n }\n return parserFn(state)\n}\n"]}
1
+ {"version":3,"file":"combinator.js","sourceRoot":"","sources":["../../src/combinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EdgeLike, NodeLike } from '@vltpkg/graph'\nimport { asCombinatorNode } from './types.ts'\nimport type { ParserState, ParserFn } from './types.ts'\nimport { error } from '@vltpkg/error-cause'\n\n/**\n * Returns a new set of nodes, containing all direct dependencies\n * of the current list of nodes used.\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator\n */\nconst childCombinator = async (state: ParserState) => {\n const traverse = new Set(state.partial.nodes)\n state.partial.edges.clear()\n state.partial.nodes.clear()\n\n // visit direct children of the current list of nodes\n // collecting refs to these children and the edges that\n // connected them.\n for (const node of traverse) {\n for (const edge of node.edgesOut.values()) {\n if (edge.to) {\n state.partial.edges.add(edge)\n state.partial.nodes.add(edge.to)\n }\n }\n }\n\n return state\n}\n\n/**\n * Returns a new set of nodes, containing nodes that are also children\n * of all parent nodes to the current list of nodes used.\n *\n * Note: The subsequent-sibling comparator has a behavior that is\n * somehow approximative of that of its css counterpart, given that\n * in the context of dependency graphs the order of appearance is\n * not necessarily controlled by the end user. The approach for\n * this comparator is to match all siblings of a node.\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Subsequent-sibling_combinator\n */\nconst subsequentSiblingCombinator = async (state: ParserState) => {\n const traverse = new Set(state.partial.nodes)\n state.partial.edges.clear()\n state.partial.nodes.clear()\n\n // visits direct parents of the current list of node and then\n // visit their children, collecting refs to all children and edges\n // that are not in the original list of nodes.\n for (const node of traverse) {\n for (const edge of node.edgesIn) {\n const parents: IterableIterator<EdgeLike> =\n edge.from.edgesOut.values()\n for (const edge of parents) {\n if (edge.to && edge.to !== node) {\n state.partial.edges.add(edge)\n state.partial.nodes.add(edge.to)\n }\n }\n }\n }\n\n return state\n}\n\n/**\n * Returns a new set of nodes containing all nodes that are descendents\n * to items in the current list of nodes.\n *\n * ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_combinator\n */\nconst descendentCombinator = async (state: ParserState) => {\n // spaces between tags selectors are a noop\n if (state.prev?.type === 'tag' || state.next?.type === 'tag') {\n return state\n }\n\n const traverse = new Set<NodeLike>(state.partial.nodes)\n state.partial.edges.clear()\n state.partial.nodes.clear()\n\n // breadth-first traversal of the graph, starting from the current\n // list of nodes, collecting all nodes and edges along the way\n for (const node of traverse) {\n const children = new Set<NodeLike>()\n for (const edge of node.edgesOut.values()) {\n if (edge.to) {\n children.add(edge.to)\n state.partial.edges.add(edge)\n state.partial.nodes.add(edge.to)\n }\n }\n for (const child of children) {\n traverse.add(child)\n }\n }\n\n return state\n}\n\nconst combinatorSelectors = {\n '>': childCombinator,\n '~': subsequentSiblingCombinator,\n ' ': descendentCombinator,\n}\n\nconst combinatorSelectorsMap = new Map<string, ParserFn>(\n Object.entries(combinatorSelectors),\n)\n\n/**\n * Parse css-style combinators, e.g: `>`, `~` and ` `\n */\nexport const combinator = async (state: ParserState) => {\n await state.cancellable()\n\n const curr = asCombinatorNode(state.current)\n const parserFn =\n curr.value && combinatorSelectorsMap.get(curr.value)\n if (!parserFn) {\n if (state.loose) {\n return state\n }\n\n throw error(`Unsupported combinator: ${state.current.value}`, {\n found: state.current,\n })\n }\n return parserFn(state)\n}\n"]}
package/dist/esm/id.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type ParserState } from './types.js';
1
+ import type { ParserState } from './types.ts';
2
2
  /**
3
3
  * Parse ids, e.g: `#foo`
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/id.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAM/D;;GAEG;AACH,eAAO,MAAM,EAAE,UAAiB,WAAW,yBAc1C,CAAA"}
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;GAEG;AACH,eAAO,MAAM,EAAE,UACN,WAAW,KACjB,OAAO,CAAC,WAAW,CAiCrB,CAAA"}
package/dist/esm/id.js CHANGED
@@ -1,20 +1,34 @@
1
1
  import { error } from '@vltpkg/error-cause';
2
- import { asIdentifierNode } from './types.js';
3
- import { attributeSelectorsMap, filterAttributes, } from './attribute.js';
2
+ import { asIdentifierNode } from "./types.js";
4
3
  /**
5
4
  * Parse ids, e.g: `#foo`
6
5
  */
7
6
  export const id = async (state) => {
8
7
  const { value } = asIdentifierNode(state.current);
9
- const comparator = attributeSelectorsMap.get('=');
10
8
  /* c8 ignore start - should not be possible */
11
9
  if (!value) {
12
10
  throw error('Missing identifier name');
13
11
  }
14
- if (!comparator) {
15
- throw error('Could not find attribute selector comparator');
16
- }
17
12
  /* c8 ignore stop */
18
- return filterAttributes(state, comparator, value, 'name', true);
13
+ // Filter out any edges and their linked
14
+ // nodes if they don't match the id value
15
+ for (const edge of state.partial.edges) {
16
+ if (edge.name !== value) {
17
+ state.partial.edges.delete(edge);
18
+ if (edge.to) {
19
+ state.partial.nodes.delete(edge.to);
20
+ }
21
+ }
22
+ }
23
+ // Filter out importer nodes, this extra step is needed
24
+ // to filter out nodes that have no edges linking to them
25
+ for (const node of state.partial.nodes) {
26
+ if (node.edgesIn.size === 0 &&
27
+ node.name !== value &&
28
+ state.partial.nodes.has(node)) {
29
+ state.partial.nodes.delete(node);
30
+ }
31
+ }
32
+ return state;
19
33
  };
20
34
  //# sourceMappingURL=id.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAoB,MAAM,YAAY,CAAA;AAC/D,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,gBAAgB,CAAA;AAEvB;;GAEG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,KAAkB,EAAE,EAAE;IAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACjD,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAEjD,8CAA8C;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAA;IACxC,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,KAAK,CAAC,8CAA8C,CAAC,CAAA;IAC7D,CAAC;IACD,oBAAoB;IAEpB,OAAO,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;AACjE,CAAC,CAAA","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { asIdentifierNode, type ParserState } from './types.js'\nimport {\n attributeSelectorsMap,\n filterAttributes,\n} from './attribute.js'\n\n/**\n * Parse ids, e.g: `#foo`\n */\nexport const id = async (state: ParserState) => {\n const { value } = asIdentifierNode(state.current)\n const comparator = attributeSelectorsMap.get('=')\n\n /* c8 ignore start - should not be possible */\n if (!value) {\n throw error('Missing identifier name')\n }\n if (!comparator) {\n throw error('Could not find attribute selector comparator')\n }\n /* c8 ignore stop */\n\n return filterAttributes(state, comparator, value, 'name', true)\n}\n"]}
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAG7C;;GAEG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,EACrB,KAAkB,EACI,EAAE;IACxB,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEjD,8CAA8C;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAA;IACxC,CAAC;IACD,oBAAoB;IAEpB,wCAAwC;IACxC,yCAAyC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACxB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAChC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACZ,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,yDAAyD;IACzD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvC,IACE,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;YACvB,IAAI,CAAC,IAAI,KAAK,KAAK;YACnB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAC7B,CAAC;YACD,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { asIdentifierNode } from './types.ts'\nimport type { ParserState } from './types.ts'\n\n/**\n * Parse ids, e.g: `#foo`\n */\nexport const id = async (\n state: ParserState,\n): Promise<ParserState> => {\n const { value } = asIdentifierNode(state.current)\n\n /* c8 ignore start - should not be possible */\n if (!value) {\n throw error('Missing identifier name')\n }\n /* c8 ignore stop */\n\n // Filter out any edges and their linked\n // nodes if they don't match the id value\n for (const edge of state.partial.edges) {\n if (edge.name !== value) {\n state.partial.edges.delete(edge)\n if (edge.to) {\n state.partial.nodes.delete(edge.to)\n }\n }\n }\n\n // Filter out importer nodes, this extra step is needed\n // to filter out nodes that have no edges linking to them\n for (const node of state.partial.nodes) {\n if (\n node.edgesIn.size === 0 &&\n node.name !== value &&\n state.partial.nodes.has(node)\n ) {\n state.partial.nodes.delete(node)\n }\n }\n\n return state\n}\n"]}
@@ -1,13 +1,31 @@
1
1
  import type { GraphLike } from '@vltpkg/graph';
2
- import { type ParserState, QueryResponse } from './types.js';
3
- export * from './types.js';
2
+ import type { SpecOptions } from '@vltpkg/spec/browser';
3
+ import type { SecurityArchiveLike } from '@vltpkg/security-archive';
4
+ import type { ParsedSelectorToken, ParserState, QueryResponse } from './types.ts';
5
+ export * from './types.ts';
4
6
  export declare const walk: (state: ParserState) => Promise<ParserState>;
5
7
  export type QueryOptions = {
6
8
  graph: GraphLike;
9
+ retries?: number;
10
+ specOptions: SpecOptions;
11
+ securityArchive: SecurityArchiveLike | undefined;
7
12
  };
8
13
  export declare class Query {
9
14
  #private;
10
- constructor({ graph }: QueryOptions);
11
- search(query: string): Promise<QueryResponse>;
15
+ /**
16
+ * Helper method to determine if a given query string is using any of
17
+ * the known security selectors. This is useful so that operations can
18
+ * skip hydrating the security archive if it's not needed.
19
+ */
20
+ static hasSecuritySelectors(query: string): boolean;
21
+ constructor({ graph, retries, specOptions, securityArchive, }: QueryOptions);
22
+ /**
23
+ * Search the graph for nodes and edges that match the given query.
24
+ */
25
+ search(query: string, signal?: AbortSignal): Promise<QueryResponse>;
26
+ /**
27
+ * Parses a query string in order to retrieve an array of tokens.
28
+ */
29
+ static getQueryTokens(query: string): ParsedSelectorToken[];
12
30
  }
13
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAY,SAAS,EAAY,MAAM,eAAe,CAAA;AAOlE,OAAO,EAEL,KAAK,WAAW,EAKhB,aAAa,EACd,MAAM,YAAY,CAAA;AAEnB,cAAc,YAAY,CAAA;AAiC1B,eAAO,MAAM,IAAI,UACR,WAAW,KACjB,OAAO,CAAC,WAAW,CAiDrB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,SAAS,CAAA;CACjB,CAAA;AAED,qBAAa,KAAK;;gBAIJ,EAAE,KAAK,EAAE,EAAE,YAAY;IAK7B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;CA0CpD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAY,SAAS,EAAY,MAAM,eAAe,CAAA;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAcnE,OAAO,KAAK,EAEV,mBAAmB,EAEnB,WAAW,EAEX,aAAa,EAGd,MAAM,YAAY,CAAA;AAEnB,cAAc,YAAY,CAAA;AAqC1B,eAAO,MAAM,IAAI,UACR,WAAW,KACjB,OAAO,CAAC,WAAW,CAsDrB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,WAAW,CAAA;IACxB,eAAe,EAAE,mBAAmB,GAAG,SAAS,CAAA;CACjD,CAAA;AAiDD,qBAAa,KAAK;;IAOhB;;;;OAIG;IACH,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;gBASvC,EACV,KAAK,EACL,OAAO,EACP,WAAW,EACX,eAAe,GAChB,EAAE,YAAY;IAyLf;;OAEG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,aAAa,CAAC;IAwDzB;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,EAAE;CAmE5D"}