@vltpkg/query 0.0.0-7 → 0.0.0-9
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.
- package/README.md +25 -0
- package/dist/esm/attribute.js +3 -1
- package/dist/esm/attribute.js.map +1 -1
- package/dist/esm/combinator.d.ts.map +1 -1
- package/dist/esm/combinator.js +4 -1
- package/dist/esm/combinator.js.map +1 -1
- package/dist/esm/id.d.ts.map +1 -1
- package/dist/esm/id.js +20 -6
- package/dist/esm/id.js.map +1 -1
- package/dist/esm/index.d.ts +7 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +172 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/parser.d.ts +15 -0
- package/dist/esm/parser.d.ts.map +1 -0
- package/dist/esm/parser.js +92 -0
- package/dist/esm/parser.js.map +1 -0
- package/dist/esm/pseudo/abandoned.d.ts +3 -1
- package/dist/esm/pseudo/abandoned.d.ts.map +1 -1
- package/dist/esm/pseudo/attr.d.ts.map +1 -1
- package/dist/esm/pseudo/attr.js +10 -2
- package/dist/esm/pseudo/attr.js.map +1 -1
- package/dist/esm/pseudo/confused.d.ts +3 -1
- package/dist/esm/pseudo/confused.d.ts.map +1 -1
- package/dist/esm/pseudo/cve.d.ts +3 -1
- package/dist/esm/pseudo/cve.d.ts.map +1 -1
- package/dist/esm/pseudo/cve.js +3 -6
- package/dist/esm/pseudo/cve.js.map +1 -1
- package/dist/esm/pseudo/cwe.d.ts +3 -1
- package/dist/esm/pseudo/cwe.d.ts.map +1 -1
- package/dist/esm/pseudo/cwe.js +3 -6
- package/dist/esm/pseudo/cwe.js.map +1 -1
- package/dist/esm/pseudo/debug.d.ts +3 -1
- package/dist/esm/pseudo/debug.d.ts.map +1 -1
- package/dist/esm/pseudo/deprecated.d.ts +3 -1
- package/dist/esm/pseudo/deprecated.d.ts.map +1 -1
- package/dist/esm/pseudo/dev.d.ts +6 -0
- package/dist/esm/pseudo/dev.d.ts.map +1 -0
- package/dist/esm/pseudo/dev.js +15 -0
- package/dist/esm/pseudo/dev.js.map +1 -0
- package/dist/esm/pseudo/dynamic.d.ts +3 -1
- package/dist/esm/pseudo/dynamic.d.ts.map +1 -1
- package/dist/esm/pseudo/empty.d.ts +7 -0
- package/dist/esm/pseudo/empty.d.ts.map +1 -0
- package/dist/esm/pseudo/empty.js +14 -0
- package/dist/esm/pseudo/empty.js.map +1 -0
- package/dist/esm/pseudo/entropic.d.ts +3 -1
- package/dist/esm/pseudo/entropic.d.ts.map +1 -1
- package/dist/esm/pseudo/env.d.ts +3 -1
- package/dist/esm/pseudo/env.d.ts.map +1 -1
- package/dist/esm/pseudo/eval.d.ts +3 -1
- package/dist/esm/pseudo/eval.d.ts.map +1 -1
- package/dist/esm/pseudo/fs.d.ts +3 -1
- package/dist/esm/pseudo/fs.d.ts.map +1 -1
- package/dist/esm/pseudo/helpers.d.ts +18 -2
- package/dist/esm/pseudo/helpers.d.ts.map +1 -1
- package/dist/esm/pseudo/helpers.js +29 -3
- package/dist/esm/pseudo/helpers.js.map +1 -1
- package/dist/esm/pseudo/license.d.ts +3 -1
- package/dist/esm/pseudo/license.d.ts.map +1 -1
- package/dist/esm/pseudo/license.js +2 -5
- package/dist/esm/pseudo/license.js.map +1 -1
- package/dist/esm/pseudo/link.d.ts +9 -0
- package/dist/esm/pseudo/link.d.ts.map +1 -0
- package/dist/esm/pseudo/link.js +25 -0
- package/dist/esm/pseudo/link.js.map +1 -0
- package/dist/esm/pseudo/malware.d.ts +5 -1
- package/dist/esm/pseudo/malware.d.ts.map +1 -1
- package/dist/esm/pseudo/malware.js +117 -12
- package/dist/esm/pseudo/malware.js.map +1 -1
- package/dist/esm/pseudo/minified.d.ts +3 -1
- package/dist/esm/pseudo/minified.d.ts.map +1 -1
- package/dist/esm/pseudo/missing.d.ts +8 -0
- package/dist/esm/pseudo/missing.d.ts.map +1 -0
- package/dist/esm/pseudo/missing.js +15 -0
- package/dist/esm/pseudo/missing.js.map +1 -0
- package/dist/esm/pseudo/native.d.ts +3 -1
- package/dist/esm/pseudo/native.d.ts.map +1 -1
- package/dist/esm/pseudo/network.d.ts +3 -1
- package/dist/esm/pseudo/network.d.ts.map +1 -1
- package/dist/esm/pseudo/obfuscated.d.ts +3 -1
- package/dist/esm/pseudo/obfuscated.d.ts.map +1 -1
- package/dist/esm/pseudo/optional.d.ts +6 -0
- package/dist/esm/pseudo/optional.d.ts.map +1 -0
- package/dist/esm/pseudo/optional.js +15 -0
- package/dist/esm/pseudo/optional.js.map +1 -0
- package/dist/esm/pseudo/outdated.d.ts +1 -1
- package/dist/esm/pseudo/outdated.d.ts.map +1 -1
- package/dist/esm/pseudo/outdated.js +33 -27
- package/dist/esm/pseudo/outdated.js.map +1 -1
- package/dist/esm/pseudo/peer.d.ts +6 -0
- package/dist/esm/pseudo/peer.d.ts.map +1 -0
- package/dist/esm/pseudo/peer.js +15 -0
- package/dist/esm/pseudo/peer.js.map +1 -0
- package/dist/esm/pseudo/private.d.ts +7 -0
- package/dist/esm/pseudo/private.d.ts.map +1 -0
- package/dist/esm/pseudo/private.js +16 -0
- package/dist/esm/pseudo/private.js.map +1 -0
- package/dist/esm/pseudo/prod.d.ts +6 -0
- package/dist/esm/pseudo/prod.d.ts.map +1 -0
- package/dist/esm/pseudo/prod.js +15 -0
- package/dist/esm/pseudo/prod.js.map +1 -0
- package/dist/esm/pseudo/published.d.ts +40 -0
- package/dist/esm/pseudo/published.d.ts.map +1 -0
- package/dist/esm/pseudo/published.js +159 -0
- package/dist/esm/pseudo/published.js.map +1 -0
- package/dist/esm/pseudo/scanned.d.ts +9 -0
- package/dist/esm/pseudo/scanned.d.ts.map +1 -0
- package/dist/esm/pseudo/scanned.js +17 -0
- package/dist/esm/pseudo/scanned.js.map +1 -0
- package/dist/esm/pseudo/score.d.ts +15 -0
- package/dist/esm/pseudo/score.d.ts.map +1 -0
- package/dist/esm/pseudo/score.js +119 -0
- package/dist/esm/pseudo/score.js.map +1 -0
- package/dist/esm/pseudo/scripts.d.ts +3 -1
- package/dist/esm/pseudo/scripts.d.ts.map +1 -1
- package/dist/esm/pseudo/semver.d.ts.map +1 -1
- package/dist/esm/pseudo/semver.js +11 -25
- package/dist/esm/pseudo/semver.js.map +1 -1
- package/dist/esm/pseudo/severity.d.ts +5 -1
- package/dist/esm/pseudo/severity.d.ts.map +1 -1
- package/dist/esm/pseudo/severity.js +112 -12
- package/dist/esm/pseudo/severity.js.map +1 -1
- package/dist/esm/pseudo/shell.d.ts +3 -1
- package/dist/esm/pseudo/shell.d.ts.map +1 -1
- package/dist/esm/pseudo/shrinkwrap.d.ts +3 -1
- package/dist/esm/pseudo/shrinkwrap.d.ts.map +1 -1
- package/dist/esm/pseudo/squat.d.ts +5 -1
- package/dist/esm/pseudo/squat.d.ts.map +1 -1
- package/dist/esm/pseudo/squat.js +116 -12
- package/dist/esm/pseudo/squat.js.map +1 -1
- package/dist/esm/pseudo/suspicious.d.ts +3 -1
- package/dist/esm/pseudo/suspicious.d.ts.map +1 -1
- package/dist/esm/pseudo/tracker.d.ts +3 -1
- package/dist/esm/pseudo/tracker.d.ts.map +1 -1
- package/dist/esm/pseudo/trivial.d.ts +3 -1
- package/dist/esm/pseudo/trivial.d.ts.map +1 -1
- package/dist/esm/pseudo/undesirable.d.ts +3 -1
- package/dist/esm/pseudo/undesirable.d.ts.map +1 -1
- package/dist/esm/pseudo/unknown.d.ts +3 -1
- package/dist/esm/pseudo/unknown.d.ts.map +1 -1
- package/dist/esm/pseudo/unmaintained.d.ts +3 -1
- package/dist/esm/pseudo/unmaintained.d.ts.map +1 -1
- package/dist/esm/pseudo/unpopular.d.ts +3 -1
- package/dist/esm/pseudo/unpopular.d.ts.map +1 -1
- package/dist/esm/pseudo/unstable.d.ts +3 -1
- package/dist/esm/pseudo/unstable.d.ts.map +1 -1
- package/dist/esm/pseudo/workspace.d.ts +6 -0
- package/dist/esm/pseudo/workspace.d.ts.map +1 -0
- package/dist/esm/pseudo/workspace.js +15 -0
- package/dist/esm/pseudo/workspace.js.map +1 -0
- package/dist/esm/pseudo.d.ts.map +1 -1
- package/dist/esm/pseudo.js +29 -41
- package/dist/esm/pseudo.js.map +1 -1
- package/dist/esm/types.d.ts +74 -5
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +12 -13
- package/dist/esm/types.js.map +1 -1
- package/package.json +9 -8
- package/dist/esm/class.d.ts +0 -6
- package/dist/esm/class.d.ts.map +0 -1
- package/dist/esm/class.js +0 -128
- package/dist/esm/class.js.map +0 -1
package/README.md
CHANGED
|
@@ -121,6 +121,7 @@ e.g: `#foo` is the same as `[name=foo]`
|
|
|
121
121
|
of the same name, this selector has a forgiving behavior regarding
|
|
122
122
|
its nested selector list ignoring any usage of non-existing ids,
|
|
123
123
|
classes, combinators, operators and pseudo-selectors.
|
|
124
|
+
- `:link` Matches linked packages only.
|
|
124
125
|
- `:not(<selector-list>)` Negation pseudo-class, select packages that
|
|
125
126
|
do not match a list of selectors.
|
|
126
127
|
- `:outdated(<type>)` Matches packages that are outdated, the type
|
|
@@ -139,6 +140,17 @@ e.g: `#foo` is the same as `[name=foo]`
|
|
|
139
140
|
current one
|
|
140
141
|
- `:private` Matches packages that have the property `private` set on
|
|
141
142
|
their `package.json` file.
|
|
143
|
+
- `:published(<date>)` Matches packages based on their publication
|
|
144
|
+
date. The date parameter can be prefixed with a comparator (`>`,
|
|
145
|
+
`<`, `>=`, `<=`). If no comparator is provided, it will match exact
|
|
146
|
+
dates. Please note that the value parameter needs to be quoted if
|
|
147
|
+
using a comparator. Examples:
|
|
148
|
+
- `:published(2024-01-01)` - Matches packages published exactly on
|
|
149
|
+
January 1st, 2024
|
|
150
|
+
- `:published(">2024-01-01")` - Matches packages published after
|
|
151
|
+
January 1st, 2024
|
|
152
|
+
- `:published("<=2023-12-31")` - Matches packages published on or
|
|
153
|
+
before December 31st, 2023
|
|
142
154
|
- `:semver(<value>, <function>, <custom-attribute-selector>)` Matches
|
|
143
155
|
packages based on a semver value, e.g, to retrieve all packages that
|
|
144
156
|
have a `version` satisfied by the semver value `^1.0.0`:
|
|
@@ -228,6 +240,19 @@ security data needs to be fetched prior to a `Query` instantiation.
|
|
|
228
240
|
- `:obfuscated` Matches packages that use obfuscated files,
|
|
229
241
|
intentionally packed to hide their behavior. This could be a sign of
|
|
230
242
|
malware.
|
|
243
|
+
- `:scanned` Matches packages that have insight security metadata.
|
|
244
|
+
- `:score(<rate>, <kind>)` Matches packages based on their security
|
|
245
|
+
score. The rate parameter is required and should be a value between
|
|
246
|
+
0 and 100 (or 0 and 1). The rate parameter can be prefixed with a
|
|
247
|
+
comparator (`>`, `<`, `>=`, `<=`). If no comparator is provided, it
|
|
248
|
+
will match exact scores. The kind parameter is optional and defaults
|
|
249
|
+
to 'overall'. Valid kinds are: 'overall', 'license', 'maintenance',
|
|
250
|
+
'quality', 'supplyChain', and 'vulnerability'. Examples:
|
|
251
|
+
- `:score(80)` - Matches packages with exactly 0.8 overall score
|
|
252
|
+
- `:score(">0.8")` - Matches packages with overall score greater
|
|
253
|
+
than 0.8
|
|
254
|
+
- `:score("<=0.5", "maintenance")` - Matches packages with
|
|
255
|
+
maintenance score less than or equal to 0.5
|
|
231
256
|
- `:scripts` Matches packages that have scripts that are run when the
|
|
232
257
|
package is installed. The majority of malware in npm is hidden in
|
|
233
258
|
install scripts.
|
package/dist/esm/attribute.js
CHANGED
|
@@ -128,7 +128,9 @@ export const attribute = async (state) => {
|
|
|
128
128
|
if (state.loose) {
|
|
129
129
|
return state;
|
|
130
130
|
}
|
|
131
|
-
throw
|
|
131
|
+
throw error(`Unsupported attribute operator: ${curr.operator}`, {
|
|
132
|
+
found: state.current,
|
|
133
|
+
});
|
|
132
134
|
}
|
|
133
135
|
const value = curr.value || '';
|
|
134
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, 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 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combinator.d.ts","sourceRoot":"","sources":["../../src/combinator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,YAAY,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"}
|
package/dist/esm/combinator.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
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.
|
|
@@ -102,7 +103,9 @@ export const combinator = async (state) => {
|
|
|
102
103
|
if (state.loose) {
|
|
103
104
|
return state;
|
|
104
105
|
}
|
|
105
|
-
throw
|
|
106
|
+
throw error(`Unsupported combinator: ${state.current.value}`, {
|
|
107
|
+
found: state.current,
|
|
108
|
+
});
|
|
106
109
|
}
|
|
107
110
|
return parserFn(state);
|
|
108
111
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combinator.js","sourceRoot":"","sources":["../../src/combinator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;
|
|
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.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,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
2
|
import { asIdentifierNode } from "./types.js";
|
|
3
|
-
import { attributeSelectorsMap, filterAttributes, } from "./attribute.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
|
-
|
|
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
|
package/dist/esm/id.js.map
CHANGED
|
@@ -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,EAAE,MAAM,YAAY,CAAA;
|
|
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"]}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { GraphLike } from '@vltpkg/graph';
|
|
2
2
|
import type { SpecOptions } from '@vltpkg/spec/browser';
|
|
3
3
|
import type { SecurityArchiveLike } from '@vltpkg/security-archive';
|
|
4
|
-
import type { ParserState, QueryResponse } from './types.ts';
|
|
4
|
+
import type { ParsedSelectorToken, ParserState, QueryResponse } from './types.ts';
|
|
5
5
|
export * from './types.ts';
|
|
6
6
|
export declare const walk: (state: ParserState) => Promise<ParserState>;
|
|
7
7
|
export type QueryOptions = {
|
|
8
8
|
graph: GraphLike;
|
|
9
|
+
retries?: number;
|
|
9
10
|
specOptions: SpecOptions;
|
|
10
11
|
securityArchive: SecurityArchiveLike | undefined;
|
|
11
12
|
};
|
|
@@ -17,10 +18,14 @@ export declare class Query {
|
|
|
17
18
|
* skip hydrating the security archive if it's not needed.
|
|
18
19
|
*/
|
|
19
20
|
static hasSecuritySelectors(query: string): boolean;
|
|
20
|
-
constructor({ graph, specOptions, securityArchive }: QueryOptions);
|
|
21
|
+
constructor({ graph, retries, specOptions, securityArchive, }: QueryOptions);
|
|
21
22
|
/**
|
|
22
23
|
* Search the graph for nodes and edges that match the given query.
|
|
23
24
|
*/
|
|
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[];
|
|
25
30
|
}
|
|
26
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -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;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;
|
|
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;IA+CzB;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,EAAE;CAmE5D"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { error } from '@vltpkg/error-cause';
|
|
2
|
-
import
|
|
2
|
+
import { parse } from "./parser.js";
|
|
3
3
|
import { attribute } from "./attribute.js";
|
|
4
|
-
import { classFn } from "./class.js";
|
|
5
4
|
import { combinator } from "./combinator.js";
|
|
6
5
|
import { id } from "./id.js";
|
|
7
6
|
import { pseudo } from "./pseudo.js";
|
|
8
|
-
import { isPostcssNodeWithChildren, asPostcssNodeWithChildren, isSelectorNode, } from "./types.js";
|
|
7
|
+
import { isPostcssNodeWithChildren, asPostcssNodeWithChildren, isSelectorNode, isPseudoNode, isIdentifierNode, isAttributeNode, } from "./types.js";
|
|
9
8
|
export * from "./types.js";
|
|
10
9
|
const noopFn = async (state) => state;
|
|
11
10
|
const selectors = {
|
|
12
11
|
attribute,
|
|
13
|
-
|
|
12
|
+
/* c8 ignore start */
|
|
13
|
+
class: async (state) => {
|
|
14
|
+
throw error('Unsupported selector', { found: state.current });
|
|
15
|
+
},
|
|
16
|
+
/* c8 ignore end */
|
|
14
17
|
combinator,
|
|
15
18
|
comment: noopFn,
|
|
16
19
|
id,
|
|
@@ -41,7 +44,9 @@ export const walk = async (state) => {
|
|
|
41
44
|
if (state.loose) {
|
|
42
45
|
return state;
|
|
43
46
|
}
|
|
44
|
-
throw
|
|
47
|
+
throw error(`Missing parser for query node: ${state.current.type}`, {
|
|
48
|
+
found: state.current,
|
|
49
|
+
});
|
|
45
50
|
}
|
|
46
51
|
state = await parserFn(state);
|
|
47
52
|
// pseudo selectors handle their own sub selectors
|
|
@@ -80,6 +85,7 @@ const securitySelectors = new Set([
|
|
|
80
85
|
':abandoned',
|
|
81
86
|
':confused',
|
|
82
87
|
':cve',
|
|
88
|
+
':cwe',
|
|
83
89
|
':debug',
|
|
84
90
|
':deprecated',
|
|
85
91
|
':dynamic',
|
|
@@ -93,6 +99,8 @@ const securitySelectors = new Set([
|
|
|
93
99
|
':native',
|
|
94
100
|
':network',
|
|
95
101
|
':obfuscated',
|
|
102
|
+
':scanned',
|
|
103
|
+
':score',
|
|
96
104
|
':scripts',
|
|
97
105
|
':sev',
|
|
98
106
|
':severity',
|
|
@@ -108,9 +116,18 @@ const securitySelectors = new Set([
|
|
|
108
116
|
':unpopular',
|
|
109
117
|
':unstable',
|
|
110
118
|
]);
|
|
119
|
+
const setMethodToJSON = (node) => {
|
|
120
|
+
const { toJSON } = node;
|
|
121
|
+
const insights = node.insights;
|
|
122
|
+
node.toJSON = () => ({
|
|
123
|
+
...toJSON.call(node),
|
|
124
|
+
insights,
|
|
125
|
+
});
|
|
126
|
+
};
|
|
111
127
|
export class Query {
|
|
112
128
|
#cache;
|
|
113
129
|
#graph;
|
|
130
|
+
#retries;
|
|
114
131
|
#specOptions;
|
|
115
132
|
#securityArchive;
|
|
116
133
|
/**
|
|
@@ -126,19 +143,100 @@ export class Query {
|
|
|
126
143
|
}
|
|
127
144
|
return false;
|
|
128
145
|
}
|
|
129
|
-
constructor({ graph, specOptions, securityArchive }) {
|
|
146
|
+
constructor({ graph, retries, specOptions, securityArchive, }) {
|
|
130
147
|
this.#cache = new Map();
|
|
131
148
|
this.#graph = graph;
|
|
149
|
+
this.#retries = retries ?? 3;
|
|
132
150
|
this.#specOptions = specOptions;
|
|
133
151
|
this.#securityArchive = securityArchive;
|
|
134
152
|
}
|
|
153
|
+
#getQueryResponseEdges(_edges) {
|
|
154
|
+
return Array.from(_edges);
|
|
155
|
+
}
|
|
156
|
+
#getQueryResponseNodes(_nodes) {
|
|
157
|
+
const nodes = Array.from(_nodes);
|
|
158
|
+
for (const node of nodes) {
|
|
159
|
+
const securityArchiveEntry = this.#securityArchive?.get(node.id);
|
|
160
|
+
// if a security archive entry is not found then the insights object
|
|
161
|
+
// should just be empty with scanned=false
|
|
162
|
+
if (!securityArchiveEntry) {
|
|
163
|
+
node.insights = {
|
|
164
|
+
scanned: false,
|
|
165
|
+
};
|
|
166
|
+
setMethodToJSON(node);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
// if a security archive entry is found then we can populate the insights
|
|
170
|
+
node.insights = {
|
|
171
|
+
scanned: true,
|
|
172
|
+
score: securityArchiveEntry.score,
|
|
173
|
+
abandoned: securityArchiveEntry.alerts.some(i => i.type === 'missingAuthor'),
|
|
174
|
+
confused: securityArchiveEntry.alerts.some(i => i.type === 'manifestConfusion'),
|
|
175
|
+
cve: securityArchiveEntry.alerts
|
|
176
|
+
.filter(i => i.props?.cveId)
|
|
177
|
+
// can not be undefined because of the filter above but TS doesn't know that
|
|
178
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
|
|
179
|
+
.map(i => i.props?.cveId),
|
|
180
|
+
cwe: Array.from(new Set(securityArchiveEntry.alerts
|
|
181
|
+
.filter(i => i.props?.cveId)
|
|
182
|
+
.flatMap(i => i.props?.cwes?.map(j => j.id)))),
|
|
183
|
+
debug: securityArchiveEntry.alerts.some(i => i.type === 'debugAccess'),
|
|
184
|
+
deprecated: securityArchiveEntry.alerts.some(i => i.type === 'deprecated'),
|
|
185
|
+
dynamic: securityArchiveEntry.alerts.some(i => i.type === 'dynamicRequire'),
|
|
186
|
+
entropic: securityArchiveEntry.alerts.some(i => i.type === 'highEntropyStrings'),
|
|
187
|
+
env: securityArchiveEntry.alerts.some(i => i.type === 'envVars'),
|
|
188
|
+
eval: securityArchiveEntry.alerts.some(i => i.type === 'usesEval'),
|
|
189
|
+
fs: securityArchiveEntry.alerts.some(i => i.type === 'filesystemAccess'),
|
|
190
|
+
license: {
|
|
191
|
+
unlicensed: securityArchiveEntry.alerts.some(i => i.type === 'explicitlyUnlicensedItem'),
|
|
192
|
+
misc: securityArchiveEntry.alerts.some(i => i.type === 'miscLicenseIssues'),
|
|
193
|
+
restricted: securityArchiveEntry.alerts.some(i => i.type === 'nonpermissiveLicense'),
|
|
194
|
+
ambiguous: securityArchiveEntry.alerts.some(i => i.type === 'ambiguousClassifier'),
|
|
195
|
+
copyleft: securityArchiveEntry.alerts.some(i => i.type === 'copyleftLicense'),
|
|
196
|
+
unknown: securityArchiveEntry.alerts.some(i => i.type === 'unidentifiedLicense'),
|
|
197
|
+
none: securityArchiveEntry.alerts.some(i => i.type === 'noLicenseFound'),
|
|
198
|
+
exception: securityArchiveEntry.alerts.some(i => i.type === 'licenseException'),
|
|
199
|
+
},
|
|
200
|
+
malware: {
|
|
201
|
+
low: securityArchiveEntry.alerts.some(i => i.type === 'gptAnomaly'),
|
|
202
|
+
medium: securityArchiveEntry.alerts.some(i => i.type === 'gptSecurity'),
|
|
203
|
+
high: securityArchiveEntry.alerts.some(i => i.type === 'gptMalware'),
|
|
204
|
+
critical: securityArchiveEntry.alerts.some(i => i.type === 'malware'),
|
|
205
|
+
},
|
|
206
|
+
minified: securityArchiveEntry.alerts.some(i => i.type === 'minifiedFile'),
|
|
207
|
+
native: securityArchiveEntry.alerts.some(i => i.type === 'hasNativeCode'),
|
|
208
|
+
network: securityArchiveEntry.alerts.some(i => i.type === 'networkAccess'),
|
|
209
|
+
obfuscated: securityArchiveEntry.alerts.some(i => i.type === 'obfuscatedFile'),
|
|
210
|
+
scripts: securityArchiveEntry.alerts.some(i => i.type === 'installScripts'),
|
|
211
|
+
severity: {
|
|
212
|
+
low: securityArchiveEntry.alerts.some(i => i.type === 'mildCVE'),
|
|
213
|
+
medium: securityArchiveEntry.alerts.some(i => i.type === 'potentialVulnerability'),
|
|
214
|
+
high: securityArchiveEntry.alerts.some(i => i.type === 'cve'),
|
|
215
|
+
critical: securityArchiveEntry.alerts.some(i => i.type === 'criticalCVE'),
|
|
216
|
+
},
|
|
217
|
+
shell: securityArchiveEntry.alerts.some(i => i.type === 'shellAccess'),
|
|
218
|
+
shrinkwrap: securityArchiveEntry.alerts.some(i => i.type === 'shrinkwrap'),
|
|
219
|
+
squat: {
|
|
220
|
+
medium: securityArchiveEntry.alerts.some(i => i.type === 'gptDidYouMean'),
|
|
221
|
+
critical: securityArchiveEntry.alerts.some(i => i.type === 'didYouMean'),
|
|
222
|
+
},
|
|
223
|
+
suspicious: securityArchiveEntry.alerts.some(i => i.type === 'suspiciousStarActivity'),
|
|
224
|
+
tracker: securityArchiveEntry.alerts.some(i => i.type === 'telemetry'),
|
|
225
|
+
trivial: securityArchiveEntry.alerts.some(i => i.type === 'trivialPackage'),
|
|
226
|
+
undesirable: securityArchiveEntry.alerts.some(i => i.type === 'troll'),
|
|
227
|
+
unknown: securityArchiveEntry.alerts.some(i => i.type === 'newAuthor'),
|
|
228
|
+
unmaintained: securityArchiveEntry.alerts.some(i => i.type === 'unmaintained'),
|
|
229
|
+
unpopular: securityArchiveEntry.alerts.some(i => i.type === 'unpopularPackage'),
|
|
230
|
+
unstable: securityArchiveEntry.alerts.some(i => i.type === 'unstableOwnership'),
|
|
231
|
+
};
|
|
232
|
+
setMethodToJSON(node);
|
|
233
|
+
}
|
|
234
|
+
return nodes;
|
|
235
|
+
}
|
|
135
236
|
/**
|
|
136
237
|
* Search the graph for nodes and edges that match the given query.
|
|
137
238
|
*/
|
|
138
239
|
async search(query, signal) {
|
|
139
|
-
if (typeof query !== 'string') {
|
|
140
|
-
throw new TypeError('Query search argument needs to be a string');
|
|
141
|
-
}
|
|
142
240
|
if (!query)
|
|
143
241
|
return { edges: [], nodes: [] };
|
|
144
242
|
const cachedResult = this.#cache.get(query);
|
|
@@ -156,7 +254,7 @@ export class Query {
|
|
|
156
254
|
});
|
|
157
255
|
signal?.throwIfAborted();
|
|
158
256
|
},
|
|
159
|
-
current:
|
|
257
|
+
current: parse(query),
|
|
160
258
|
initial: {
|
|
161
259
|
nodes: new Set(nodes),
|
|
162
260
|
edges: new Set(edges),
|
|
@@ -166,17 +264,79 @@ export class Query {
|
|
|
166
264
|
edges: new Set(),
|
|
167
265
|
},
|
|
168
266
|
partial: { nodes, edges },
|
|
267
|
+
retries: this.#retries,
|
|
169
268
|
signal,
|
|
170
269
|
securityArchive: this.#securityArchive,
|
|
171
270
|
specOptions: this.#specOptions,
|
|
172
271
|
walk,
|
|
173
272
|
});
|
|
174
273
|
const res = {
|
|
175
|
-
edges:
|
|
176
|
-
nodes:
|
|
274
|
+
edges: this.#getQueryResponseEdges(collect.edges),
|
|
275
|
+
nodes: this.#getQueryResponseNodes(collect.nodes),
|
|
177
276
|
};
|
|
178
277
|
this.#cache.set(query, res);
|
|
179
278
|
return res;
|
|
180
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Parses a query string in order to retrieve an array of tokens.
|
|
282
|
+
*/
|
|
283
|
+
static getQueryTokens(query) {
|
|
284
|
+
if (!query)
|
|
285
|
+
return [];
|
|
286
|
+
const tokens = [];
|
|
287
|
+
const ast = (q) => {
|
|
288
|
+
try {
|
|
289
|
+
return parse(q);
|
|
290
|
+
}
|
|
291
|
+
catch (_e) {
|
|
292
|
+
return ast(q.slice(0, -1));
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
const processNode = (node) => {
|
|
296
|
+
for (const key of selectorsMap.keys()) {
|
|
297
|
+
if (node.type === key && node.type !== 'root') {
|
|
298
|
+
let token = `${node.spaces.before}${node.value}${node.spaces.after}`;
|
|
299
|
+
if (isIdentifierNode(node)) {
|
|
300
|
+
token = `${node.spaces.before}#${node.value}${node.spaces.after}`;
|
|
301
|
+
}
|
|
302
|
+
else if (isSelectorNode(node)) {
|
|
303
|
+
token = `${node.spaces.before},${node.spaces.after}`;
|
|
304
|
+
}
|
|
305
|
+
else if (isAttributeNode(node)) {
|
|
306
|
+
token = String(node.source?.start?.column &&
|
|
307
|
+
node.source.end?.column &&
|
|
308
|
+
`${node.spaces.before}${query.slice(node.source.start.column - 1, node.source.end.column)}${node.spaces.after}`);
|
|
309
|
+
}
|
|
310
|
+
if (isPostcssNodeWithChildren(node) &&
|
|
311
|
+
isPseudoNode(node) &&
|
|
312
|
+
node.nodes.length) {
|
|
313
|
+
token = String(token.split('(')[0]);
|
|
314
|
+
token += '(';
|
|
315
|
+
}
|
|
316
|
+
if (!isSelectorNode(node) ||
|
|
317
|
+
node.parent?.nodes.indexOf(node) !== 0) {
|
|
318
|
+
tokens.push({
|
|
319
|
+
...node,
|
|
320
|
+
token,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (isPostcssNodeWithChildren(node)) {
|
|
326
|
+
for (const child of node.nodes) {
|
|
327
|
+
processNode(child);
|
|
328
|
+
}
|
|
329
|
+
if (isPseudoNode(node) && node.nodes.length) {
|
|
330
|
+
tokens.push({
|
|
331
|
+
...node,
|
|
332
|
+
token: ')' + node.spaces.after,
|
|
333
|
+
type: 'pseudo',
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
processNode(ast(query));
|
|
339
|
+
return tokens;
|
|
340
|
+
}
|
|
181
341
|
}
|
|
182
342
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { EdgeLike, GraphLike, NodeLike } from '@vltpkg/graph'\nimport type { SpecOptions } from '@vltpkg/spec/browser'\nimport type { SecurityArchiveLike } from '@vltpkg/security-archive'\nimport postcssSelectorParser from 'postcss-selector-parser'\nimport { attribute } from './attribute.ts'\nimport { classFn } from './class.ts'\nimport { combinator } from './combinator.ts'\nimport { id } from './id.ts'\nimport { pseudo } from './pseudo.ts'\nimport {\n isPostcssNodeWithChildren,\n asPostcssNodeWithChildren,\n isSelectorNode,\n} from './types.ts'\nimport type {\n PostcssNodeWithChildren,\n ParserState,\n ParserFn,\n QueryResponse,\n} from './types.ts'\n\nexport * from './types.ts'\n\nconst noopFn = async (state: ParserState) => state\n\nconst selectors = {\n attribute,\n class: classFn,\n combinator,\n comment: noopFn,\n id,\n nesting: noopFn,\n pseudo,\n root: noopFn,\n selector: async (state: ParserState) => {\n state.partial.nodes = new Set(state.initial.nodes)\n state.partial.edges = new Set(state.initial.edges)\n return state\n },\n string: async (state: ParserState) => {\n throw error('Unsupported selector', { found: state.current })\n },\n tag: async (state: ParserState) => {\n if (state.current.value !== '{' && state.current.value !== '}') {\n throw error('Unsupported selector', { found: state.current })\n }\n return state\n },\n universal: noopFn,\n}\nconst selectorsMap = new Map<string, ParserFn>(\n Object.entries(selectors),\n)\n\nexport const walk = async (\n state: ParserState,\n): Promise<ParserState> => {\n await state.cancellable()\n\n const parserFn = selectorsMap.get(state.current.type)\n\n if (!parserFn) {\n if (state.loose) {\n return state\n }\n\n throw new Error(\n `Missing parser for query node: ${state.current.type}`,\n )\n }\n state = await parserFn(state)\n\n // pseudo selectors handle their own sub selectors\n if (\n isPostcssNodeWithChildren(state.current) &&\n state.current.type !== 'pseudo'\n ) {\n const node: PostcssNodeWithChildren = asPostcssNodeWithChildren(\n state.current,\n )\n\n if (node.nodes.length) {\n for (let i = 0; i < node.nodes.length; i++) {\n const current = node.nodes[i]\n /* c8 ignore next -- impossible but TS doesn't know that */\n if (!current) continue\n\n const childState: ParserState = {\n ...state,\n current,\n next: node.nodes[i + 1],\n prev: node.nodes[i - 1],\n }\n state = await walk(childState)\n }\n }\n\n if (isSelectorNode(node)) {\n for (const edge of state.partial.edges) {\n state.collect.edges.add(edge)\n }\n for (const node of state.partial.nodes) {\n state.collect.nodes.add(node)\n }\n }\n }\n return state\n}\n\nexport type QueryOptions = {\n graph: GraphLike\n specOptions: SpecOptions\n securityArchive: SecurityArchiveLike | undefined\n}\n\n// A list of known security selectors that rely on\n// data from the security-archive in order to work\nconst securitySelectors = new Set([\n ':abandoned',\n ':confused',\n ':cve',\n ':debug',\n ':deprecated',\n ':dynamic',\n ':entropic',\n ':env',\n ':eval',\n ':fs',\n ':license',\n ':malware',\n ':minified',\n ':native',\n ':network',\n ':obfuscated',\n ':scripts',\n ':sev',\n ':severity',\n ':shell',\n ':shrinkwrap',\n ':squat',\n ':suspicious',\n ':tracker',\n ':trivial',\n ':undesirable',\n ':unknown',\n ':unmaintained',\n ':unpopular',\n ':unstable',\n])\n\nexport class Query {\n #cache: Map<string, QueryResponse>\n #graph: GraphLike\n #specOptions: SpecOptions\n #securityArchive: SecurityArchiveLike | undefined\n\n /**\n * Helper method to determine if a given query string is using any of\n * the known security selectors. This is useful so that operations can\n * skip hydrating the security archive if it's not needed.\n */\n static hasSecuritySelectors(query: string): boolean {\n for (const selector of securitySelectors) {\n if (query.includes(selector)) {\n return true\n }\n }\n return false\n }\n\n constructor({ graph, specOptions, securityArchive }: QueryOptions) {\n this.#cache = new Map()\n this.#graph = graph\n this.#specOptions = specOptions\n this.#securityArchive = securityArchive\n }\n\n /**\n * Search the graph for nodes and edges that match the given query.\n */\n async search(\n query: string,\n signal?: AbortSignal,\n ): Promise<QueryResponse> {\n if (typeof query !== 'string') {\n throw new TypeError(\n 'Query search argument needs to be a string',\n )\n }\n\n if (!query) return { edges: [], nodes: [] }\n\n const cachedResult = this.#cache.get(query)\n if (cachedResult) {\n return cachedResult\n }\n\n const nodes = new Set<NodeLike>(\n Array.from(this.#graph.nodes.values()),\n )\n const edges = new Set<EdgeLike>(Array.from(this.#graph.edges))\n\n // builds initial state and walks over it,\n // retrieving the collected result\n const { collect } = await walk({\n cancellable: async () => {\n await new Promise(resolve => {\n setTimeout(resolve, 0)\n })\n signal?.throwIfAborted()\n },\n current: postcssSelectorParser().astSync(query),\n initial: {\n nodes: new Set(nodes),\n edges: new Set(edges),\n },\n collect: {\n nodes: new Set<NodeLike>(),\n edges: new Set<EdgeLike>(),\n },\n partial: { nodes, edges },\n signal,\n securityArchive: this.#securityArchive,\n specOptions: this.#specOptions,\n walk,\n })\n\n const res: QueryResponse = {\n edges: Array.from(collect.edges),\n nodes: Array.from(collect.nodes),\n }\n this.#cache.set(query, res)\n return res\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAI3C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,YAAY,CAAA;AAYnB,cAAc,YAAY,CAAA;AAE1B,MAAM,MAAM,GAAG,KAAK,EAAE,KAAkB,EAAE,EAAE,CAAC,KAAK,CAAA;AAElD,MAAM,SAAS,GAAG;IAChB,SAAS;IACT,qBAAqB;IACrB,KAAK,EAAE,KAAK,EAAE,KAAkB,EAAE,EAAE;QAClC,MAAM,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IAC/D,CAAC;IACD,mBAAmB;IACnB,UAAU;IACV,OAAO,EAAE,MAAM;IACf,EAAE;IACF,OAAO,EAAE,MAAM;IACf,MAAM;IACN,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,KAAK,EAAE,KAAkB,EAAE,EAAE;QACrC,KAAK,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAClD,KAAK,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAClD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,KAAkB,EAAE,EAAE;QACnC,MAAM,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IAC/D,CAAC;IACD,GAAG,EAAE,KAAK,EAAE,KAAkB,EAAE,EAAE;QAChC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC;YAC/D,MAAM,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAC/D,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,SAAS,EAAE,MAAM;CAClB,CAAA;AACD,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAC1B,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EACvB,KAAkB,EACI,EAAE;IACxB,MAAM,KAAK,CAAC,WAAW,EAAE,CAAA;IAEzB,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAErD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,KAAK,CACT,kCAAkC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EACtD;YACE,KAAK,EAAE,KAAK,CAAC,OAAO;SACrB,CACF,CAAA;IACH,CAAC;IACD,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE7B,kDAAkD;IAClD,IACE,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC;QACxC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,EAC/B,CAAC;QACD,MAAM,IAAI,GAA4B,yBAAyB,CAC7D,KAAK,CAAC,OAAO,CACd,CAAA;QAED,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;gBAC7B,2DAA2D;gBAC3D,IAAI,CAAC,OAAO;oBAAE,SAAQ;gBAEtB,MAAM,UAAU,GAAgB;oBAC9B,GAAG,KAAK;oBACR,OAAO;oBACP,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;oBACvB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;iBACxB,CAAA;gBACD,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAA;YAChC,CAAC;QACH,CAAC;QAED,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACvC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC/B,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACvC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AASD,kDAAkD;AAClD,kDAAkD;AAClD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,YAAY;IACZ,WAAW;IACX,MAAM;IACN,MAAM;IACN,QAAQ;IACR,aAAa;IACb,UAAU;IACV,WAAW;IACX,MAAM;IACN,OAAO;IACP,KAAK;IACL,UAAU;IACV,UAAU;IACV,WAAW;IACX,SAAS;IACT,UAAU;IACV,aAAa;IACb,UAAU;IACV,QAAQ;IACR,UAAU;IACV,MAAM;IACN,WAAW;IACX,QAAQ;IACR,aAAa;IACb,QAAQ;IACR,aAAa;IACb,UAAU;IACV,UAAU;IACV,cAAc;IACd,UAAU;IACV,eAAe;IACf,YAAY;IACZ,WAAW;CACZ,CAAC,CAAA;AAEF,MAAM,eAAe,GAAG,CAAC,IAAuB,EAAE,EAAE;IAClD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC9B,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC;QACnB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACpB,QAAQ;KACT,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,OAAO,KAAK;IAChB,MAAM,CAA4B;IAClC,MAAM,CAAW;IACjB,QAAQ,CAAQ;IAChB,YAAY,CAAa;IACzB,gBAAgB,CAAiC;IAEjD;;;;OAIG;IACH,MAAM,CAAC,oBAAoB,CAAC,KAAa;QACvC,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,YAAY,EACV,KAAK,EACL,OAAO,EACP,WAAW,EACX,eAAe,GACF;QACb,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAA;QACvB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,QAAQ,GAAG,OAAO,IAAI,CAAC,CAAA;QAC5B,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;QAC/B,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAA;IACzC,CAAC;IAED,sBAAsB,CAAC,MAAqB;QAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAwB,CAAA;IAClD,CAAC;IAED,sBAAsB,CAAC,MAAqB;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAwB,CAAA;QACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAEhE,oEAAoE;YACpE,0CAA0C;YAC1C,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,GAAG;oBACd,OAAO,EAAE,KAAK;iBACf,CAAA;gBAED,eAAe,CAAC,IAAI,CAAC,CAAA;gBACrB,SAAQ;YACV,CAAC;YAED,yEAAyE;YACzE,IAAI,CAAC,QAAQ,GAAG;gBACd,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,oBAAoB,CAAC,KAAK;gBACjC,SAAS,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACzC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAChC;gBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CACpC;gBACD,GAAG,EAAE,oBAAoB,CAAC,MAAM;qBAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC;oBAC5B,4EAA4E;oBAC5E,4HAA4H;qBAC3H,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,KAAM,CAAC;gBAC5B,GAAG,EAAE,KAAK,CAAC,IAAI,CACb,IAAI,GAAG,CACL,oBAAoB,CAAC,MAAM;qBACxB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC;qBAC3B,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC/C,CACmB;gBACtB,KAAK,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACrC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAC9B;gBACD,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAC7B;gBACD,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CACjC;gBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,oBAAoB,CACrC;gBACD,GAAG,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAC1B;gBACD,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAC3B;gBACD,EAAE,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAClC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CACnC;gBACD,OAAO,EAAE;oBACP,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,0BAA0B,CAC3C;oBACD,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CACpC;oBACD,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,sBAAsB,CACvC;oBACD,SAAS,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACzC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CACtC;oBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAClC;oBACD,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CACtC;oBACD,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CACjC;oBACD,SAAS,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACzC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CACnC;iBACF;gBACD,OAAO,EAAE;oBACP,GAAG,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAC7B;oBACD,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAC9B;oBACD,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAC7B;oBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAC1B;iBACF;gBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAC/B;gBACD,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAChC;gBACD,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAChC;gBACD,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CACjC;gBACD,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CACjC;gBACD,QAAQ,EAAE;oBACR,GAAG,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAC1B;oBACD,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAwB,CACzC;oBACD,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CACtB;oBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAC9B;iBACF;gBACD,KAAK,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACrC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAC9B;gBACD,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAC7B;gBACD,KAAK,EAAE;oBACL,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAChC;oBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAC7B;iBACF;gBACD,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAwB,CACzC;gBACD,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAC5B;gBACD,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CACjC;gBACD,WAAW,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CACxB;gBACD,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAC5B;gBACD,YAAY,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAC5C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAC/B;gBACD,SAAS,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACzC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CACnC;gBACD,QAAQ,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CACpC;aACF,CAAA;YAED,eAAe,CAAC,IAAI,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,KAAa,EACb,MAAoB;QAEpB,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QAE3C,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC3C,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,YAAY,CAAA;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,GAAG,CACnB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CACvC,CAAA;QACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QAE9D,0CAA0C;QAC1C,kCAAkC;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC;YAC7B,WAAW,EAAE,KAAK,IAAI,EAAE;gBACtB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC1B,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;gBACxB,CAAC,CAAC,CAAA;gBACF,MAAM,EAAE,cAAc,EAAE,CAAA;YAC1B,CAAC;YACD,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;YACrB,OAAO,EAAE;gBACP,KAAK,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC;gBACrB,KAAK,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC;aACtB;YACD,OAAO,EAAE;gBACP,KAAK,EAAE,IAAI,GAAG,EAAY;gBAC1B,KAAK,EAAE,IAAI,GAAG,EAAY;aAC3B;YACD,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;YACzB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,MAAM;YACN,eAAe,EAAE,IAAI,CAAC,gBAAgB;YACtC,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,IAAI;SACL,CAAC,CAAA;QAEF,MAAM,GAAG,GAAkB;YACzB,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC;YACjD,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC;SAClD,CAAA;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAC3B,OAAO,GAAG,CAAA;IACZ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAa;QACjC,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAA;QAErB,MAAM,MAAM,GAA0B,EAAE,CAAA;QAExC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE;YACxB,IAAI,CAAC;gBACH,OAAO,KAAK,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC,CAAA;QAED,MAAM,WAAW,GAAG,CAAC,IAAiB,EAAE,EAAE;YACxC,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;gBACtC,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC9C,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;oBAEpE,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC3B,KAAK,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;oBACnE,CAAC;yBAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;wBAChC,KAAK,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;oBACtD,CAAC;yBAAM,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;wBACjC,KAAK,GAAG,MAAM,CACZ,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM;4BACxB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM;4BACvB,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAClH,CAAA;oBACH,CAAC;oBAED,IACE,yBAAyB,CAAC,IAAI,CAAC;wBAC/B,YAAY,CAAC,IAAI,CAAC;wBAClB,IAAI,CAAC,KAAK,CAAC,MAAM,EACjB,CAAC;wBACD,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;wBACnC,KAAK,IAAI,GAAG,CAAA;oBACd,CAAC;oBAED,IACE,CAAC,cAAc,CAAC,IAAI,CAAC;wBACrB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EACtC,CAAC;wBACD,MAAM,CAAC,IAAI,CAAC;4BACV,GAAG,IAAI;4BACP,KAAK;yBACiB,CAAC,CAAA;oBAC3B,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBAC/B,WAAW,CAAC,KAAK,CAAC,CAAA;gBACpB,CAAC;gBACD,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBAC5C,MAAM,CAAC,IAAI,CAAC;wBACV,GAAG,IAAI;wBACP,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK;wBAC9B,IAAI,EAAE,QAAQ;qBACQ,CAAC,CAAA;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC,CAAA;QAED,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QACvB,OAAO,MAAM,CAAA;IACf,CAAC;CACF","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { EdgeLike, GraphLike, NodeLike } from '@vltpkg/graph'\nimport type { SpecOptions } from '@vltpkg/spec/browser'\nimport type { SecurityArchiveLike } from '@vltpkg/security-archive'\nimport { parse } from './parser.ts'\nimport { attribute } from './attribute.ts'\nimport { combinator } from './combinator.ts'\nimport { id } from './id.ts'\nimport { pseudo } from './pseudo.ts'\nimport {\n isPostcssNodeWithChildren,\n asPostcssNodeWithChildren,\n isSelectorNode,\n isPseudoNode,\n isIdentifierNode,\n isAttributeNode,\n} from './types.ts'\nimport type {\n PostcssNode,\n ParsedSelectorToken,\n PostcssNodeWithChildren,\n ParserState,\n ParserFn,\n QueryResponse,\n QueryResponseNode,\n QueryResponseEdge,\n} from './types.ts'\n\nexport * from './types.ts'\n\nconst noopFn = async (state: ParserState) => state\n\nconst selectors = {\n attribute,\n /* c8 ignore start */\n class: async (state: ParserState) => {\n throw error('Unsupported selector', { found: state.current })\n },\n /* c8 ignore end */\n combinator,\n comment: noopFn,\n id,\n nesting: noopFn,\n pseudo,\n root: noopFn,\n selector: async (state: ParserState) => {\n state.partial.nodes = new Set(state.initial.nodes)\n state.partial.edges = new Set(state.initial.edges)\n return state\n },\n string: async (state: ParserState) => {\n throw error('Unsupported selector', { found: state.current })\n },\n tag: async (state: ParserState) => {\n if (state.current.value !== '{' && state.current.value !== '}') {\n throw error('Unsupported selector', { found: state.current })\n }\n return state\n },\n universal: noopFn,\n}\nconst selectorsMap = new Map<string, ParserFn>(\n Object.entries(selectors),\n)\n\nexport const walk = async (\n state: ParserState,\n): Promise<ParserState> => {\n await state.cancellable()\n\n const parserFn = selectorsMap.get(state.current.type)\n\n if (!parserFn) {\n if (state.loose) {\n return state\n }\n\n throw error(\n `Missing parser for query node: ${state.current.type}`,\n {\n found: state.current,\n },\n )\n }\n state = await parserFn(state)\n\n // pseudo selectors handle their own sub selectors\n if (\n isPostcssNodeWithChildren(state.current) &&\n state.current.type !== 'pseudo'\n ) {\n const node: PostcssNodeWithChildren = asPostcssNodeWithChildren(\n state.current,\n )\n\n if (node.nodes.length) {\n for (let i = 0; i < node.nodes.length; i++) {\n const current = node.nodes[i]\n /* c8 ignore next -- impossible but TS doesn't know that */\n if (!current) continue\n\n const childState: ParserState = {\n ...state,\n current,\n next: node.nodes[i + 1],\n prev: node.nodes[i - 1],\n }\n state = await walk(childState)\n }\n }\n\n if (isSelectorNode(node)) {\n for (const edge of state.partial.edges) {\n state.collect.edges.add(edge)\n }\n for (const node of state.partial.nodes) {\n state.collect.nodes.add(node)\n }\n }\n }\n return state\n}\n\nexport type QueryOptions = {\n graph: GraphLike\n retries?: number\n specOptions: SpecOptions\n securityArchive: SecurityArchiveLike | undefined\n}\n\n// A list of known security selectors that rely on\n// data from the security-archive in order to work\nconst securitySelectors = new Set([\n ':abandoned',\n ':confused',\n ':cve',\n ':cwe',\n ':debug',\n ':deprecated',\n ':dynamic',\n ':entropic',\n ':env',\n ':eval',\n ':fs',\n ':license',\n ':malware',\n ':minified',\n ':native',\n ':network',\n ':obfuscated',\n ':scanned',\n ':score',\n ':scripts',\n ':sev',\n ':severity',\n ':shell',\n ':shrinkwrap',\n ':squat',\n ':suspicious',\n ':tracker',\n ':trivial',\n ':undesirable',\n ':unknown',\n ':unmaintained',\n ':unpopular',\n ':unstable',\n])\n\nconst setMethodToJSON = (node: QueryResponseNode) => {\n const { toJSON } = node\n const insights = node.insights\n node.toJSON = () => ({\n ...toJSON.call(node),\n insights,\n })\n}\n\nexport class Query {\n #cache: Map<string, QueryResponse>\n #graph: GraphLike\n #retries: number\n #specOptions: SpecOptions\n #securityArchive: SecurityArchiveLike | undefined\n\n /**\n * Helper method to determine if a given query string is using any of\n * the known security selectors. This is useful so that operations can\n * skip hydrating the security archive if it's not needed.\n */\n static hasSecuritySelectors(query: string): boolean {\n for (const selector of securitySelectors) {\n if (query.includes(selector)) {\n return true\n }\n }\n return false\n }\n\n constructor({\n graph,\n retries,\n specOptions,\n securityArchive,\n }: QueryOptions) {\n this.#cache = new Map()\n this.#graph = graph\n this.#retries = retries ?? 3\n this.#specOptions = specOptions\n this.#securityArchive = securityArchive\n }\n\n #getQueryResponseEdges(_edges: Set<EdgeLike>): QueryResponseEdge[] {\n return Array.from(_edges) as QueryResponseEdge[]\n }\n\n #getQueryResponseNodes(_nodes: Set<NodeLike>): QueryResponseNode[] {\n const nodes = Array.from(_nodes) as QueryResponseNode[]\n for (const node of nodes) {\n const securityArchiveEntry = this.#securityArchive?.get(node.id)\n\n // if a security archive entry is not found then the insights object\n // should just be empty with scanned=false\n if (!securityArchiveEntry) {\n node.insights = {\n scanned: false,\n }\n\n setMethodToJSON(node)\n continue\n }\n\n // if a security archive entry is found then we can populate the insights\n node.insights = {\n scanned: true,\n score: securityArchiveEntry.score,\n abandoned: securityArchiveEntry.alerts.some(\n i => i.type === 'missingAuthor',\n ),\n confused: securityArchiveEntry.alerts.some(\n i => i.type === 'manifestConfusion',\n ),\n cve: securityArchiveEntry.alerts\n .filter(i => i.props?.cveId)\n // can not be undefined because of the filter above but TS doesn't know that\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain\n .map(i => i.props?.cveId!),\n cwe: Array.from(\n new Set(\n securityArchiveEntry.alerts\n .filter(i => i.props?.cveId)\n .flatMap(i => i.props?.cwes?.map(j => j.id)),\n ),\n ) as `CWE-${string}`[],\n debug: securityArchiveEntry.alerts.some(\n i => i.type === 'debugAccess',\n ),\n deprecated: securityArchiveEntry.alerts.some(\n i => i.type === 'deprecated',\n ),\n dynamic: securityArchiveEntry.alerts.some(\n i => i.type === 'dynamicRequire',\n ),\n entropic: securityArchiveEntry.alerts.some(\n i => i.type === 'highEntropyStrings',\n ),\n env: securityArchiveEntry.alerts.some(\n i => i.type === 'envVars',\n ),\n eval: securityArchiveEntry.alerts.some(\n i => i.type === 'usesEval',\n ),\n fs: securityArchiveEntry.alerts.some(\n i => i.type === 'filesystemAccess',\n ),\n license: {\n unlicensed: securityArchiveEntry.alerts.some(\n i => i.type === 'explicitlyUnlicensedItem',\n ),\n misc: securityArchiveEntry.alerts.some(\n i => i.type === 'miscLicenseIssues',\n ),\n restricted: securityArchiveEntry.alerts.some(\n i => i.type === 'nonpermissiveLicense',\n ),\n ambiguous: securityArchiveEntry.alerts.some(\n i => i.type === 'ambiguousClassifier',\n ),\n copyleft: securityArchiveEntry.alerts.some(\n i => i.type === 'copyleftLicense',\n ),\n unknown: securityArchiveEntry.alerts.some(\n i => i.type === 'unidentifiedLicense',\n ),\n none: securityArchiveEntry.alerts.some(\n i => i.type === 'noLicenseFound',\n ),\n exception: securityArchiveEntry.alerts.some(\n i => i.type === 'licenseException',\n ),\n },\n malware: {\n low: securityArchiveEntry.alerts.some(\n i => i.type === 'gptAnomaly',\n ),\n medium: securityArchiveEntry.alerts.some(\n i => i.type === 'gptSecurity',\n ),\n high: securityArchiveEntry.alerts.some(\n i => i.type === 'gptMalware',\n ),\n critical: securityArchiveEntry.alerts.some(\n i => i.type === 'malware',\n ),\n },\n minified: securityArchiveEntry.alerts.some(\n i => i.type === 'minifiedFile',\n ),\n native: securityArchiveEntry.alerts.some(\n i => i.type === 'hasNativeCode',\n ),\n network: securityArchiveEntry.alerts.some(\n i => i.type === 'networkAccess',\n ),\n obfuscated: securityArchiveEntry.alerts.some(\n i => i.type === 'obfuscatedFile',\n ),\n scripts: securityArchiveEntry.alerts.some(\n i => i.type === 'installScripts',\n ),\n severity: {\n low: securityArchiveEntry.alerts.some(\n i => i.type === 'mildCVE',\n ),\n medium: securityArchiveEntry.alerts.some(\n i => i.type === 'potentialVulnerability',\n ),\n high: securityArchiveEntry.alerts.some(\n i => i.type === 'cve',\n ),\n critical: securityArchiveEntry.alerts.some(\n i => i.type === 'criticalCVE',\n ),\n },\n shell: securityArchiveEntry.alerts.some(\n i => i.type === 'shellAccess',\n ),\n shrinkwrap: securityArchiveEntry.alerts.some(\n i => i.type === 'shrinkwrap',\n ),\n squat: {\n medium: securityArchiveEntry.alerts.some(\n i => i.type === 'gptDidYouMean',\n ),\n critical: securityArchiveEntry.alerts.some(\n i => i.type === 'didYouMean',\n ),\n },\n suspicious: securityArchiveEntry.alerts.some(\n i => i.type === 'suspiciousStarActivity',\n ),\n tracker: securityArchiveEntry.alerts.some(\n i => i.type === 'telemetry',\n ),\n trivial: securityArchiveEntry.alerts.some(\n i => i.type === 'trivialPackage',\n ),\n undesirable: securityArchiveEntry.alerts.some(\n i => i.type === 'troll',\n ),\n unknown: securityArchiveEntry.alerts.some(\n i => i.type === 'newAuthor',\n ),\n unmaintained: securityArchiveEntry.alerts.some(\n i => i.type === 'unmaintained',\n ),\n unpopular: securityArchiveEntry.alerts.some(\n i => i.type === 'unpopularPackage',\n ),\n unstable: securityArchiveEntry.alerts.some(\n i => i.type === 'unstableOwnership',\n ),\n }\n\n setMethodToJSON(node)\n }\n return nodes\n }\n\n /**\n * Search the graph for nodes and edges that match the given query.\n */\n async search(\n query: string,\n signal?: AbortSignal,\n ): Promise<QueryResponse> {\n if (!query) return { edges: [], nodes: [] }\n\n const cachedResult = this.#cache.get(query)\n if (cachedResult) {\n return cachedResult\n }\n\n const nodes = new Set<NodeLike>(\n Array.from(this.#graph.nodes.values()),\n )\n const edges = new Set<EdgeLike>(Array.from(this.#graph.edges))\n\n // builds initial state and walks over it,\n // retrieving the collected result\n const { collect } = await walk({\n cancellable: async () => {\n await new Promise(resolve => {\n setTimeout(resolve, 0)\n })\n signal?.throwIfAborted()\n },\n current: parse(query),\n initial: {\n nodes: new Set(nodes),\n edges: new Set(edges),\n },\n collect: {\n nodes: new Set<NodeLike>(),\n edges: new Set<EdgeLike>(),\n },\n partial: { nodes, edges },\n retries: this.#retries,\n signal,\n securityArchive: this.#securityArchive,\n specOptions: this.#specOptions,\n walk,\n })\n\n const res: QueryResponse = {\n edges: this.#getQueryResponseEdges(collect.edges),\n nodes: this.#getQueryResponseNodes(collect.nodes),\n }\n this.#cache.set(query, res)\n return res\n }\n\n /**\n * Parses a query string in order to retrieve an array of tokens.\n */\n static getQueryTokens(query: string): ParsedSelectorToken[] {\n if (!query) return []\n\n const tokens: ParsedSelectorToken[] = []\n\n const ast = (q: string) => {\n try {\n return parse(q)\n } catch (_e) {\n return ast(q.slice(0, -1))\n }\n }\n\n const processNode = (node: PostcssNode) => {\n for (const key of selectorsMap.keys()) {\n if (node.type === key && node.type !== 'root') {\n let token = `${node.spaces.before}${node.value}${node.spaces.after}`\n\n if (isIdentifierNode(node)) {\n token = `${node.spaces.before}#${node.value}${node.spaces.after}`\n } else if (isSelectorNode(node)) {\n token = `${node.spaces.before},${node.spaces.after}`\n } else if (isAttributeNode(node)) {\n token = String(\n node.source?.start?.column &&\n node.source.end?.column &&\n `${node.spaces.before}${query.slice(node.source.start.column - 1, node.source.end.column)}${node.spaces.after}`,\n )\n }\n\n if (\n isPostcssNodeWithChildren(node) &&\n isPseudoNode(node) &&\n node.nodes.length\n ) {\n token = String(token.split('(')[0])\n token += '('\n }\n\n if (\n !isSelectorNode(node) ||\n node.parent?.nodes.indexOf(node) !== 0\n ) {\n tokens.push({\n ...node,\n token,\n } as ParsedSelectorToken)\n }\n }\n }\n if (isPostcssNodeWithChildren(node)) {\n for (const child of node.nodes) {\n processNode(child)\n }\n if (isPseudoNode(node) && node.nodes.length) {\n tokens.push({\n ...node,\n token: ')' + node.spaces.after,\n type: 'pseudo',\n } as ParsedSelectorToken)\n }\n }\n }\n\n processNode(ast(query))\n return tokens\n }\n}\n"]}
|