Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorRuy Adorno <ruyadorno@hotmail.com>2022-08-01 21:29:56 +0300
committerGitHub <noreply@github.com>2022-08-01 21:29:56 +0300
commit3c024ace60904c69e61da00e1fb56c0c1735804a (patch)
tree20455ad5af7395f9a25943127d6d4ed36421eab7 /docs
parent050284d2abb6aa91a0f9ffad5b0c4f074e5dbf6d (diff)
feat: add npm query cmd (#5000)
Co-authored-by: Gar <gar+gh@danger.computer>
Diffstat (limited to 'docs')
-rw-r--r--docs/content/commands/npm-query.md236
-rw-r--r--docs/content/using-npm/dependency-selectors.md168
-rw-r--r--docs/nav.yml6
3 files changed, 410 insertions, 0 deletions
diff --git a/docs/content/commands/npm-query.md b/docs/content/commands/npm-query.md
new file mode 100644
index 000000000..424b9e7e4
--- /dev/null
+++ b/docs/content/commands/npm-query.md
@@ -0,0 +1,236 @@
+---
+title: npm-query
+section: 1
+description: Dependency selector query
+---
+
+### Synopsis
+
+<!-- AUTOGENERATED USAGE DESCRIPTIONS START -->
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/commands/query.js -->
+
+```bash
+npm query <selector>
+```
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/commands/query.js -->
+
+<!-- AUTOGENERATED USAGE DESCRIPTIONS END -->
+
+### Description
+
+The `npm query` command allows for usage of css selectors in order to retrieve
+an array of dependency objects.
+
+### Piping npm query to other commands
+
+```bash
+# find all dependencies with postinstall scripts & uninstall them
+npm query ":attr(scripts, [postinstall])" | jq 'map(.name)|join("\n")' -r | xargs -I {} npm uninstall {}
+
+# find all git dependencies & explain who requires them
+npm query ":type(git)" | jq 'map(.name)' | xargs -I {} npm why {}
+```
+
+### Extended Use Cases & Queries
+
+```stylus
+// all deps
+*
+
+// all direct deps
+:root > *
+
+// direct production deps
+:root > .prod
+
+// direct development deps
+:root > .dev
+
+// any peer dep of a direct deps
+:root > * > .peer
+
+// any workspace dep
+.workspace
+
+// all workspaces that depend on another workspace
+.workspace > .workspace
+
+// all workspaces that have peer deps
+.workspace:has(.peer)
+
+// any dep named "lodash"
+// equivalent to [name="lodash"]
+#lodash
+
+// any deps named "lodash" & within semver range ^"1.2.3"
+#lodash@^1.2.3
+// equivalent to...
+[name="lodash"]:semver(^1.2.3)
+
+// get the hoisted node for a given semver range
+#lodash@^1.2.3:not(:deduped)
+
+// querying deps with a specific version
+#lodash@2.1.5
+// equivalent to...
+[name="lodash"][version="2.1.5"]
+
+// has any deps
+:has(*)
+
+// deps with no other deps (ie. "leaf" nodes)
+:empty
+
+// manually querying git dependencies
+[repository^=github:],
+[repository^=git:],
+[repository^=https://github.com],
+[repository^=http://github.com],
+[repository^=https://github.com],
+[repository^=+git:...]
+
+// querying for all git dependencies
+:type(git)
+
+// get production dependencies that aren't also dev deps
+.prod:not(.dev)
+
+// get dependencies with specific licenses
+[license=MIT], [license=ISC]
+
+// find all packages that have @ruyadorno as a contributor
+:attr(contributors, [email=ruyadorno@github.com])
+```
+
+### Example Response Output
+
+- an array of dependency objects is returned which can contain multiple copies of the same package which may or may not have been linked or deduped
+
+```json
+[
+ {
+ "name": "",
+ "version": "",
+ "description": "",
+ "homepage": "",
+ "bugs": {},
+ "author": {},
+ "license": {},
+ "funding": {},
+ "files": [],
+ "main": "",
+ "browser": "",
+ "bin": {},
+ "man": [],
+ "directories": {},
+ "repository": {},
+ "scripts": {},
+ "config": {},
+ "dependencies": {},
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "bundledDependencies": {},
+ "peerDependencies": {},
+ "peerDependenciesMeta": {},
+ "engines": {},
+ "os": [],
+ "cpu": [],
+ "workspaces": {},
+ "keywords": [],
+ ...
+ },
+ ...
+```
+
+### Configuration
+
+<!-- AUTOGENERATED CONFIG DESCRIPTIONS START -->
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+#### `global`
+
+* Default: false
+* Type: Boolean
+
+Operates in "global" mode, so that packages are installed into the `prefix`
+folder instead of the current working directory. See
+[folders](/configuring-npm/folders) for more on the differences in behavior.
+
+* packages are installed into the `{prefix}/lib/node_modules` folder, instead
+ of the current working directory.
+* bin files are linked to `{prefix}/bin`
+* man pages are linked to `{prefix}/share/man`
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+
+#### `workspace`
+
+* Default:
+* Type: String (can be set multiple times)
+
+Enable running a command in the context of the configured workspaces of the
+current project while filtering by running only the workspaces defined by
+this configuration option.
+
+Valid values for the `workspace` config are either:
+
+* Workspace names
+* Path to a workspace directory
+* Path to a parent workspace directory (will result in selecting all
+ workspaces within that folder)
+
+When set for the `npm init` command, this may be set to the folder of a
+workspace which does not yet exist, to create the folder and set it up as a
+brand new workspace within the project.
+
+This value is not exported to the environment for child processes.
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+
+#### `workspaces`
+
+* Default: null
+* Type: null or Boolean
+
+Set to true to run the command in the context of **all** configured
+workspaces.
+
+Explicitly setting this to false will cause commands like `install` to
+ignore workspaces altogether. When not set explicitly:
+
+- Commands that operate on the `node_modules` tree (install, update, etc.)
+will link workspaces into the `node_modules` folder. - Commands that do
+other things (test, exec, publish, etc.) will operate on the root project,
+_unless_ one or more workspaces are specified in the `workspace` config.
+
+This value is not exported to the environment for child processes.
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+
+#### `include-workspace-root`
+
+* Default: false
+* Type: Boolean
+
+Include the workspace root when workspaces are enabled for a command.
+
+When false, specifying individual workspaces via the `workspace` config, or
+all workspaces via the `workspaces` flag, will cause npm to operate only on
+the specified workspaces, and not on the root project.
+
+This value is not exported to the environment for child processes.
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+
+<!-- AUTOGENERATED CONFIG DESCRIPTIONS END -->
+## See Also
+
+* [dependency selector](/using-npm/dependency-selector)
+
diff --git a/docs/content/using-npm/dependency-selectors.md b/docs/content/using-npm/dependency-selectors.md
new file mode 100644
index 000000000..9d65baf63
--- /dev/null
+++ b/docs/content/using-npm/dependency-selectors.md
@@ -0,0 +1,168 @@
+---
+title: Dependency Selector Syntax & Querying
+section: 7
+description: Dependency Selector Syntax & Querying
+---
+
+### Description
+
+The [`npm query`](/commands/npm-query) commmand exposes a new dependency selector syntax (informed by & respecting many aspects of the [CSS Selectors 4 Spec](https://dev.w3.org/csswg/selectors4/#relational)) which:
+
+- Standardizes the shape of, & querying of, dependency graphs with a robust object model, metadata & selector syntax
+- Leverages existing, known language syntax & operators from CSS to make disparate package information broadly accessible
+- Unlocks the ability to answer complex, multi-faceted questions about dependencies, their relationships & associative metadata
+- Consolidates redundant logic of similar query commands in `npm` (ex. `npm fund`, `npm ls`, `npm outdated`, `npm audit` ...)
+
+### Dependency Selector Syntax `v1.0.0`
+
+#### Overview:
+
+- there is no "type" or "tag" selectors (ex. `div, h1, a`) as a dependency/target is the only type of `Node` that can be queried
+- the term "dependencies" is in reference to any `Node` found in a `tree` returned by `Arborist`
+
+#### Combinators
+
+- `>` direct descendant/child
+- ` ` any descendant/child
+- `~` sibling
+
+#### Selectors
+
+- `*` universal selector
+- `#<name>` dependency selector (equivalent to `[name="..."]`)
+- `#<name>@<version>` (equivalent to `[name=<name>]:semver(<version>)`)
+- `,` selector list delimiter
+- `.` dependency type selector
+- `:` pseudo selector
+
+#### Dependency Type Selectors
+
+- `.prod` dependency found in the `dependencies` section of `package.json`, or is a child of said dependency
+- `.dev` dependency found in the `devDependencies` section of `package.json`, or is a child of said dependency
+- `.optional` dependency found in the `optionalDependencies` section of `package.json`, or has `"optional": true` set in its entry in the `peerDependenciesMeta` section of `package.json`, or a child of said dependency
+- `.peer` dependency found in the `peerDependencies` section of `package.json`
+- `.workspace` dependency found in the [`workspaces`](https://docs.npmjs.com/cli/v8/using-npm/workspaces) section of `package.json`
+- `.bundled` dependency found in the `bundleDependencies` section of `package.json`, or is a child of said dependency
+
+#### Pseudo Selectors
+- [`:not(<selector>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:not)
+- [`:has(<selector>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has)
+- [`:is(<selector list>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:is)
+- [`:root`](https://developer.mozilla.org/en-US/docs/Web/CSS/:root) matches the root node/dependency
+- [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) matches node/dependency it was queried against
+- [`:empty`](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty) when a dependency has no dependencies
+- [`:private`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#private) when a dependency is private
+- `:link` when a dependency is linked (for instance, workspaces or packages manually [`linked`](https://docs.npmjs.com/cli/v8/commands/npm-link)
+- `:deduped` when a dependency has been deduped (note that this does *not* always mean the dependency has been hoisted to the root of node_modules)
+- `:override` when a dependency is an override (not implemented yet)
+- `:extraneous` when a dependency exists but is not defined as a dependency of any node
+- `:invalid` when a dependency version is out of its ancestors specified range
+- `:missing` when a dependency is not found on disk
+- `:semver(<spec>)` matching a valid [`node-semver`](https://github.com/npm/node-semver) spec
+- `:path(<path>)` [glob](https://www.npmjs.com/package/glob) matching based on dependencies path relative to the project
+- `:type(<type>)` [based on currently recognized types](https://github.com/npm/npm-package-arg#result-object)
+
+#### [Attribute Selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)
+
+The attribute selector evaluates the key/value pairs in `package.json` if they are `String`s.
+
+- `[]` attribute selector (ie. existence of attribute)
+- `[attribute=value]` attribute value is equivalant...
+- `[attribute~=value]` attribute value contains word...
+- `[attribute*=value]` attribute value contains string...
+- `[attribute|=value]` attribute value is equal to or starts with...
+- `[attribute^=value]` attribute value starts with...
+- `[attribute$=value]` attribute value ends with...
+
+#### `Array` & `Object` Attribute Selectors
+
+The generic `:attr()` pseudo selector standardizes a pattern which can be used for attribute selection of `Object`s, `Array`s or `Arrays` of `Object`s accessible via `Arborist`'s `Node.package` metadata. This allows for iterative attribute selection beyond top-level `String` evaluation. The last argument passed to `:attr()` must be an `attribute` selector or a nested `:attr()`. See examples below:
+
+#### `Objects`
+
+```css
+/* return dependencies that have a `scripts.test` containing `"tap"` */
+*:attr(scripts, [test~=tap])
+```
+
+#### Nested `Objects`
+
+Nested objects are expressed as sequential arguments to `:attr()`.
+
+```css
+/* return dependencies that have a testling config for opera browsers */
+*:attr(testling, browsers, [~=opera])
+```
+
+#### `Arrays`
+
+`Array`s specifically uses a special/reserved `.` character in place of a typical attribute name. `Arrays` also support exact `value` matching when a `String` is passed to the selector.
+
+##### Example of an `Array` Attribute Selection:
+```css
+/* removes the distinction between properties & arrays */
+/* ie. we'd have to check the property & iterate to match selection */
+*:attr([keywords^=react])
+*:attr(contributors, :attr([name~=Jordan]))
+```
+
+##### Example of an `Array` matching directly to a value:
+```css
+/* return dependencies that have the exact keyword "react" */
+/* this is equivalent to `*:keywords([value="react"])` */
+*:attr([keywords=react])
+```
+
+##### Example of an `Array` of `Object`s:
+```css
+/* returns */
+*:attr(contributors, [email=ruyadorno@github.com])
+```
+
+### Groups
+
+Dependency groups are defined by the package relationships to their ancestors (ie. the dependency types that are defined in `package.json`). This approach is user-centric as the ecosystem has been taught to think about dependencies in these groups first-and-foremost. Dependencies are allowed to be included in multiple groups (ex. a `prod` dependency may also be a `dev` dependency (in that it's also required by another `dev` dependency) & may also be `bundled` - a selector for that type of dependency would look like: `*.prod.dev.bundled`).
+
+- `.prod`
+- `.dev`
+- `.optional`
+- `.peer`
+- `.bundled`
+- `.workspace`
+
+Please note that currently `workspace` deps are always `prod` dependencies. Additionally the `.root` dependency is also considered a `prod` dependency.
+
+### Programmatic Usage
+
+- `Arborist`'s `Node` Class has a `.querySelectorAll()` method
+ - this method will return a filtered, flattened dependency Arborist `Node` list based on a valid query selector
+
+```js
+const Arborist = require('@npmcli/arborist')
+const arb = new Arborist({})
+```
+
+```js
+// root-level
+arb.loadActual((tree) => {
+ // query all production dependencies
+ const results = await tree.querySelectorAll('.prod')
+ console.log(results)
+})
+```
+
+```js
+// iterative
+arb.loadActual((tree) => {
+ // query for the deduped version of react
+ const results = await tree.querySelectorAll('#react:not(:deduped)')
+ // query the deduped react for git deps
+ const deps = await results[0].querySelectorAll(':type(git)')
+ console.log(deps)
+})
+```
+
+## See Also
+
+* [npm query](/commands/npm-query)
+* [@npmcli/arborist](https://npm.im/@npmcli/arborist]
diff --git a/docs/nav.yml b/docs/nav.yml
index bc39b969e..565537054 100644
--- a/docs/nav.yml
+++ b/docs/nav.yml
@@ -132,6 +132,9 @@
- title: npm publish
url: /commands/npm-publish
description: Publish a package
+ - title: npm query
+ url: /commands/npm-query
+ description: Retrieve a filtered list of packages
- title: npm rebuild
url: /commands/npm-rebuild
description: Rebuild a package
@@ -253,6 +256,9 @@
- title: Organizations
url: /using-npm/orgs
description: Working with teams & organizations
+ - title: Dependency Selectors
+ url: /using-npm/dependency-selectors
+ description: Dependency Selector Syntax & Querying
- title: Developers
url: /using-npm/developers
description: Developer guide