The vlt query syntax engine.
Usage · Examples · Supported Syntax Reference
Usage
import { Query } from '@vltpkg/query'
const query = new Query({ nodes, specOptions, securityArchive })query.search(':root > *')
Examples
Querying nodes from a local node_modules
folder.
import { actual } from '@vltpkg/graph'import { Query } from '@vltpkg/query'
const graph = await actual.load({ projectRoot: process.cwd() })const query = new Query([...graph.nodes.values()])query.search(':root > *')
Supported Syntax Reference
The vlt query syntax enable usage of css-selector-like strings to filter packages.
Many of the common elements of the CSS language are available, notably:
*
Universal selector, matches all selected items.&
Nesting selector, allows for nesting selectors.{}
Curly braces, when querying can be used to nest selectors.
Split by group of selectors below is the complete reference to supported elements.
Attribute selectors
Attribute selectors are used to match a value found in the
package.json
metadata for each of the nodes being queried to a
arbitrary value you choose.
[attr]
Matches elements with anattr
property in itspackage.json
.[attr=value]
Matches elements with a propertyattr
whose value is exactlyvalue
.[attr^=value]
Matches elements with a propertyattr
whose value starts withvalue
.[attr$=value]
Matches elements with a propertyattr
whose value ends withvalue
.[attr~=value]
Matches elements with a propertyattr
whose value is a whitespace-separated list of words, one of which is exactlyvalue
.[attr|=value]
Matches elements with a propertyattr
whose value is eithervalue
or starts withvalue-
.[attr*=value]
Matches elements with a propertyattr
.[attr=value i]
Case-insensitive flag, setting it will cause any comparison to be case-insensitive.[attr=value s]
Case-sensitive flag, setting it will cause comparisons to be case-sensitive, this is the default behavior.
Class selectors
.prod
Matches prod dependencies to your current project..dev
Matches packages that are only used as dev dependencies in your current project..optional
Matches packages that are optional to your current project..peer
Matches peer dependencies to your current project..workspace
Matches the current project worksacpes (listed in yourvlt-workspaces.json
file).
Combinators
>
Child combinator, matches packages that are direct dependencies of the previously selected nodes.~
Sibling combinator, matches packages that are direct dependencies of all dependents of the previously selected nodes.
ID Selectors
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.
e.g: #foo
is the same as [name=foo]
Pseudo class selectors
:attr(key, [attr=value])
The attribute pseudo-class allows for selecting packages based on nested properties of itspackage.json
metadata. As an example, here is a query that filters only packages that declares an optional peer dependency namedfoo
::attr(peerDependenciesMeta, foo, [optional=true])
:empty
Matches packages that have no dependencies installed.: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 onreact
::has(.peer[name=react])
: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 nameda
&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.:not(<selector-list>)
Negation pseudo-class, select packages that do not match a list of selectors.:outdated(<type>)
Matches packages that are outdated, the type parameter is optional and can be one of the following:any
(default) a version exists that is greater than the current onein-range
a version exists that is greater than the current one, and satisfies at least one if its parent’s dependenciesout-of-range
a version exists that is greater than the current one, does not satisfy at least one of its parent’s dependenciesmajor
a version exists that is a semver major greater than the current oneminor
a version exists that is a semver minor greater than the current onepatch
a version exists that is a semver patch greater than the current one
:private
Matches packages that have the propertyprivate
set on theirpackage.json
file.:semver(<value>, <function>, <custom-attribute-selector>)
Matches packages based on a semver value, e.g, to retrieve all packages that have aversion
satisfied by the semver value^1.0.0
::semver(^1.0.0)
. It’s also possible to define the type of semver comparison function to use by defining a second parameter, e.g::semver(^1.0.0, eq)
for an exact match, valid comparison types are:eq
,neq
,gt
,gte
,lt
,lte
,satisfies
(default). A third parameter allows for specifying a differentpackage.json
property to use for the comparison, e.g::semver(^22, satisfies, :attr(engines, [node]))
for comparing the value ofengines.node
.:type(registry|file|git|remote|workspace)
Matches packages based on their type, e.g, to retrieve all git dependencies::type(git)
.
Pseudo Elements
:project
Returns both the root node (as defined below) along with any workspace declared in your project.:root
Returns the root node, that represents the package defined at the top-levelpackage.json
of your project folder.:scope
Returns the current scope of a given selector
Security Selectors
The following pseudo-selectors rely on security data provided by
Socket, the usage of any of these selectors is
going to require a network call to hydrate package report data. Keep
in mind that this is going to slow down end-user query usage since the
security data needs to be fetched prior to a Query
instantiation.
:abandoned
Matches packages that were published by an npm account that no longer exists.:confused
Matches packages affected by manifest confusion. This could be malicious or caused by an error when publishing the package.:cve(<id>)
Matches packages that have a CVE alert with the specified CVE ID. The ID parameter is required and should be a valid CVE identifier (e.g.,CVE-2023-1234
). This selector can be used to find packages affected by specific known vulnerabilities.:cwe(<id>)
Matches packages that have a CWE alert with the specified CWE ID. The ID parameter is required and should be a valid CWE identifier (e.g.,CWE-79
).:debug
Matches packages that use debug, reflection and dynamic code execution features.:deprecated
Matches packages marked as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.:dynamic
Matches packages that uses dynamic imports.:entropic
Matches packages that contains high entropic strings. This could be a sign of encrypted data, leaked secrets or obfuscated code.:env
Matches packages that accesses environment variables, which may be a sign of credential stuffing or data theft.:eval
Matches packages that use dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.:fs
Matches packages that accesses the file system, and could potentially read sensitive data.:license(<type>)
Matches packages based on different potential license issues::license(unlicensed)
Matches packages with no license.:license(misc)
Matches packages with fine-grained problems.:license(restricted)
Matches packages with a license that is not permissive.:license(ambiguous)
Matches packages with ambiguous licensing.:license(copyleft)
Matches packages with a copyleft license.:license(unknown)
Matches packages that have potential license data but its type could not be determined.:license(none)
Matches packages that have no license data.:license(exception)
Matches packages that have SPDX license exception.
:malware(<type>)
Matches packages that may contain malware. The type parameter is required and can be one of the following:critical
or0
high
or1
medium
or2
low
or3
:minified
Matches packages that contain minified code. This may be harmless in some cases where minified code is included in packaged libraries.:native
Matches packages that contain native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.:network
Matches packages that access the network.:obfuscated
Matches packages that use obfuscated files, intentionally packed to hide their behavior. This could be a sign of malware.:scripts
Matches packages that have scripts that are run when the package is installed. The majority of malware in npm is hidden in install scripts.:severity
Matches packages based of the severity level of any attached CVE. The type paremeter is required and can be one of the following:critical
or0
high
or1
medium
or2
low
or3
:shell
Matches packages that accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.:shrinkwrap
Matches packages that contains a shrinkwrap file. This may allow the package to bypass normal install procedures.:squat(<type>)
Matches packages with names similar to other popular packages and may not be the package you want. The type parameter is required and can be one of the following:critical
or0
medium
or2
:suspicious
Matches packages that may have its GitHub repository artificially inflated with stars (from bots, crowdsourcing, etc.).:tracker
Matches packages that contains telemetry which tracks how it is used.:trivial
Matches packages that have less than 10 lines of code. These packages are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.:undesirable
Matches packages that are a joke, parody, or includes undocumented or hidden behavior unrelated to its primary function.:unknown
Matches packages that have a new npm collaborator publishing a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.:unmaintained
Matches packages that have not been updated in more than 5 years and may be unmaintained.:unpopular
Matches packages that are not very popular.:unstable
Matches packages with unstable ownership. This indicates a new collaborator has begun publishing package versions. Package stability and security risk may be elevated.