diff --git a/deps/npm/docs/content/commands/npm-access.md b/deps/npm/docs/content/commands/npm-access.md index 84421e88096180..9e9f385fe386de 100644 --- a/deps/npm/docs/content/commands/npm-access.md +++ b/deps/npm/docs/content/commands/npm-access.md @@ -90,6 +90,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `otp` * Default: null @@ -101,6 +103,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + #### `registry` * Default: "https://registry.npmjs.org/" @@ -108,6 +112,8 @@ password, npm will prompt on the command line for one. The base URL of the npm registry. + + ### See Also * [`libnpmaccess`](https://npm.im/libnpmaccess) diff --git a/deps/npm/docs/content/commands/npm-adduser.md b/deps/npm/docs/content/commands/npm-adduser.md index bc7d888a2f3d2d..e19b3e3a3f85d9 100644 --- a/deps/npm/docs/content/commands/npm-adduser.md +++ b/deps/npm/docs/content/commands/npm-adduser.md @@ -32,6 +32,8 @@ email are read in from prompts. The base URL of the npm registry. + + #### `scope` * Default: the scope of the current project, if any, or "" @@ -62,6 +64,7 @@ npm init --scope=@foo --yes ``` + #### `auth-type` * Default: "web" @@ -70,6 +73,8 @@ npm init --scope=@foo --yes What authentication strategy to use with `login`. Note that if an `otp` config is given, this value will always be set to `legacy`. + + ### See Also * [npm registry](/using-npm/registry) diff --git a/deps/npm/docs/content/commands/npm-audit.md b/deps/npm/docs/content/commands/npm-audit.md index 7358d878980a88..62f93448c2457b 100644 --- a/deps/npm/docs/content/commands/npm-audit.md +++ b/deps/npm/docs/content/commands/npm-audit.md @@ -246,6 +246,8 @@ $ npm audit --audit-level=moderate The minimum level of vulnerability for `npm audit` to exit with a non-zero exit code. + + #### `dry-run` * Default: false @@ -259,6 +261,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `force` * Default: false @@ -285,6 +289,8 @@ mistakes, unnecessary performance degradation, and malicious input. If you don't have a clear idea of what you want to do, it is strongly recommended that you do not use this option! + + #### `json` * Default: false @@ -297,6 +303,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `package-lock-only` * Default: false @@ -311,6 +319,8 @@ instead of checking `node_modules` and downloading dependencies. For `list` this means the output will be based on the tree described by the `package-lock.json`, rather than the contents of `node_modules`. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -329,6 +339,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `foreground-scripts` * Default: false @@ -341,6 +353,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -353,6 +367,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `workspace` * Default: @@ -415,6 +431,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm install](/commands/npm-install) diff --git a/deps/npm/docs/content/commands/npm-bugs.md b/deps/npm/docs/content/commands/npm-bugs.md index 1f135fc6c933a9..4fb660a3ecb566 100644 --- a/deps/npm/docs/content/commands/npm-bugs.md +++ b/deps/npm/docs/content/commands/npm-bugs.md @@ -34,6 +34,8 @@ terminal. Set to `true` to use default system URL opener. + + #### `registry` * Default: "https://registry.npmjs.org/" @@ -41,6 +43,8 @@ Set to `true` to use default system URL opener. The base URL of the npm registry. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-cache.md b/deps/npm/docs/content/commands/npm-cache.md index a9d76179e81162..1697be92adb7f1 100644 --- a/deps/npm/docs/content/commands/npm-cache.md +++ b/deps/npm/docs/content/commands/npm-cache.md @@ -77,6 +77,8 @@ verify`. The location of npm's cache directory. + + ### See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-ci.md b/deps/npm/docs/content/commands/npm-ci.md index 5757bf1b29431c..2a1f39a00f9c81 100644 --- a/deps/npm/docs/content/commands/npm-ci.md +++ b/deps/npm/docs/content/commands/npm-ci.md @@ -84,6 +84,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -96,6 +98,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -106,6 +110,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -124,6 +130,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `strict-peer-deps` * Default: false @@ -143,15 +151,7 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. #### `foreground-scripts` @@ -165,6 +165,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -177,6 +179,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -187,6 +191,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -199,6 +205,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -208,6 +216,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `dry-run` * Default: false @@ -221,6 +231,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `workspace` * Default: @@ -283,6 +295,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm install](/commands/npm-install) diff --git a/deps/npm/docs/content/commands/npm-config.md b/deps/npm/docs/content/commands/npm-config.md index 69370fd5deba2d..80f44b27d12f90 100644 --- a/deps/npm/docs/content/commands/npm-config.md +++ b/deps/npm/docs/content/commands/npm-config.md @@ -116,6 +116,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `global` * Default: false @@ -130,6 +132,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `editor` * Default: The EDITOR or VISUAL environment variables, or @@ -138,6 +142,8 @@ folder instead of the current working directory. See The command to run for `npm edit` and `npm config edit`. + + #### `location` * Default: "user" unless `--global` is passed, which will also set this value @@ -155,6 +161,8 @@ instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `long` * Default: false @@ -162,6 +170,8 @@ instead of the current working directory. See Show extended information in `ls`, `search`, and `help-search`. + + ### See Also * [npm folders](/configuring-npm/folders) diff --git a/deps/npm/docs/content/commands/npm-dedupe.md b/deps/npm/docs/content/commands/npm-dedupe.md index d9c614d519eba4..592d76973cff08 100644 --- a/deps/npm/docs/content/commands/npm-dedupe.md +++ b/deps/npm/docs/content/commands/npm-dedupe.md @@ -89,6 +89,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -101,6 +103,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -111,6 +115,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `strict-peer-deps` * Default: false @@ -130,6 +136,8 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. + + #### `package-lock` * Default: true @@ -138,7 +146,7 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. + #### `omit` @@ -158,6 +166,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `ignore-scripts` * Default: false @@ -170,6 +180,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -180,6 +192,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -192,6 +206,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -201,6 +217,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `dry-run` * Default: false @@ -214,6 +232,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `workspace` * Default: @@ -276,6 +296,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm find-dupes](/commands/npm-find-dupes) diff --git a/deps/npm/docs/content/commands/npm-deprecate.md b/deps/npm/docs/content/commands/npm-deprecate.md index 146aab88c5bf74..706ecf3135c41b 100644 --- a/deps/npm/docs/content/commands/npm-deprecate.md +++ b/deps/npm/docs/content/commands/npm-deprecate.md @@ -49,6 +49,8 @@ format an empty string. The base URL of the npm registry. + + #### `otp` * Default: null @@ -60,6 +62,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + ### See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-diff.md b/deps/npm/docs/content/commands/npm-diff.md index 852fcf3d066148..e93aef383c3f27 100644 --- a/deps/npm/docs/content/commands/npm-diff.md +++ b/deps/npm/docs/content/commands/npm-diff.md @@ -156,6 +156,8 @@ located within the folder `./lib/` and changed lines of code within the Define arguments to compare in `npm diff`. + + #### `diff-name-only` * Default: false @@ -163,6 +165,8 @@ Define arguments to compare in `npm diff`. Prints only filenames when using `npm diff`. + + #### `diff-unified` * Default: 3 @@ -170,6 +174,8 @@ Prints only filenames when using `npm diff`. The number of lines of context to print in `npm diff`. + + #### `diff-ignore-all-space` * Default: false @@ -177,6 +183,8 @@ The number of lines of context to print in `npm diff`. Ignore whitespace when comparing lines in `npm diff`. + + #### `diff-no-prefix` * Default: false @@ -187,6 +195,8 @@ Do not show any source or destination prefix in `npm diff` output. Note: this causes `npm diff` to ignore the `--diff-src-prefix` and `--diff-dst-prefix` configs. + + #### `diff-src-prefix` * Default: "a/" @@ -194,6 +204,8 @@ Note: this causes `npm diff` to ignore the `--diff-src-prefix` and Source prefix to be used in `npm diff` output. + + #### `diff-dst-prefix` * Default: "b/" @@ -201,6 +213,8 @@ Source prefix to be used in `npm diff` output. Destination prefix to be used in `npm diff` output. + + #### `diff-text` * Default: false @@ -208,6 +222,8 @@ Destination prefix to be used in `npm diff` output. Treat all files as text in `npm diff`. + + #### `global` * Default: false @@ -222,6 +238,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `tag` * Default: "latest" @@ -236,6 +254,8 @@ command, if no explicit tag is given. When used by the `npm diff` command, this is the tag used to fetch the tarball that will be compared with the local files by default. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-docs.md b/deps/npm/docs/content/commands/npm-docs.md index 027a101d121e6b..582fc55eef3f6c 100644 --- a/deps/npm/docs/content/commands/npm-docs.md +++ b/deps/npm/docs/content/commands/npm-docs.md @@ -34,6 +34,8 @@ terminal. Set to `true` to use default system URL opener. + + #### `registry` * Default: "https://registry.npmjs.org/" @@ -41,6 +43,8 @@ Set to `true` to use default system URL opener. The base URL of the npm registry. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-doctor.md b/deps/npm/docs/content/commands/npm-doctor.md index bd399ce494a6c4..e72d273ac8172e 100644 --- a/deps/npm/docs/content/commands/npm-doctor.md +++ b/deps/npm/docs/content/commands/npm-doctor.md @@ -113,6 +113,8 @@ reset the cache. The base URL of the npm registry. + + ### See Also * [npm bugs](/commands/npm-bugs) diff --git a/deps/npm/docs/content/commands/npm-edit.md b/deps/npm/docs/content/commands/npm-edit.md index 04a4d15b5afcd9..a26df11b5dd07e 100644 --- a/deps/npm/docs/content/commands/npm-edit.md +++ b/deps/npm/docs/content/commands/npm-edit.md @@ -35,6 +35,8 @@ changes to your locally installed copy. The command to run for `npm edit` and `npm config edit`. + + ### See Also * [npm folders](/configuring-npm/folders) diff --git a/deps/npm/docs/content/commands/npm-exec.md b/deps/npm/docs/content/commands/npm-exec.md index af19ec5f077838..fa8d80cffc9713 100644 --- a/deps/npm/docs/content/commands/npm-exec.md +++ b/deps/npm/docs/content/commands/npm-exec.md @@ -118,6 +118,8 @@ $ npm exec -- foo@latest bar --package=@npmcli/foo The package or packages to install for [`npm exec`](/commands/npm-exec) + + #### `call` * Default: "" @@ -131,6 +133,7 @@ npm exec --package yo --package generator-node --call "yo node" ``` + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-explain.md b/deps/npm/docs/content/commands/npm-explain.md index 382429ad7e978f..b0f0ebcb680831 100644 --- a/deps/npm/docs/content/commands/npm-explain.md +++ b/deps/npm/docs/content/commands/npm-explain.md @@ -67,6 +67,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-explore.md b/deps/npm/docs/content/commands/npm-explore.md index cc312a0d28c67a..e25e760d08d70a 100644 --- a/deps/npm/docs/content/commands/npm-explore.md +++ b/deps/npm/docs/content/commands/npm-explore.md @@ -39,6 +39,8 @@ sure to use `npm rebuild ` if you make any changes. The shell to run for the `npm explore` command. + + ### See Also * [npm folders](/configuring-npm/folders) diff --git a/deps/npm/docs/content/commands/npm-find-dupes.md b/deps/npm/docs/content/commands/npm-find-dupes.md index bfdff61cbb4ee7..b326b9236153d1 100644 --- a/deps/npm/docs/content/commands/npm-find-dupes.md +++ b/deps/npm/docs/content/commands/npm-find-dupes.md @@ -29,6 +29,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -41,6 +43,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -51,6 +55,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `strict-peer-deps` * Default: false @@ -70,6 +76,8 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. + + #### `package-lock` * Default: true @@ -78,7 +86,7 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. + #### `omit` @@ -98,6 +106,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `ignore-scripts` * Default: false @@ -110,6 +120,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -120,6 +132,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -132,6 +146,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -141,6 +157,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `workspace` * Default: @@ -203,6 +221,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm dedupe](/commands/npm-dedupe) diff --git a/deps/npm/docs/content/commands/npm-fund.md b/deps/npm/docs/content/commands/npm-fund.md index 0db66f49ad65b1..cd12e1b40bc402 100644 --- a/deps/npm/docs/content/commands/npm-fund.md +++ b/deps/npm/docs/content/commands/npm-fund.md @@ -77,6 +77,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `browser` * Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` @@ -89,6 +91,8 @@ terminal. Set to `true` to use default system URL opener. + + #### `unicode` * Default: false on windows, true on mac/unix systems with a unicode locale, @@ -98,6 +102,8 @@ Set to `true` to use default system URL opener. When set to true, npm uses unicode characters in the tree output. When false, it uses ascii characters instead of unicode glyphs. + + #### `workspace` * Default: @@ -127,6 +133,8 @@ This value is not exported to the environment for child processes. If there are multiple funding sources, which 1-indexed source URL to open. + + ## See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-help-search.md b/deps/npm/docs/content/commands/npm-help-search.md index d92ea03aefb1dd..5bc4602ef9811f 100644 --- a/deps/npm/docs/content/commands/npm-help-search.md +++ b/deps/npm/docs/content/commands/npm-help-search.md @@ -32,6 +32,8 @@ directly. Show extended information in `ls`, `search`, and `help-search`. + + ### See Also * [npm](/commands/npm) diff --git a/deps/npm/docs/content/commands/npm-help.md b/deps/npm/docs/content/commands/npm-help.md index 48af6da7fa08d2..bc2c8762eefdae 100644 --- a/deps/npm/docs/content/commands/npm-help.md +++ b/deps/npm/docs/content/commands/npm-help.md @@ -34,6 +34,8 @@ The program to use to view help content. Set to `"browser"` to view html help content in the default web browser. + + ### See Also * [npm](/commands/npm) diff --git a/deps/npm/docs/content/commands/npm-hook.md b/deps/npm/docs/content/commands/npm-hook.md index 1304512e33a674..581e78661d6c2f 100644 --- a/deps/npm/docs/content/commands/npm-hook.md +++ b/deps/npm/docs/content/commands/npm-hook.md @@ -92,6 +92,8 @@ $ npm hook rm id-deadbeef The base URL of the npm registry. + + #### `otp` * Default: null @@ -103,6 +105,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + ### See Also * ["Introducing Hooks" blog post](https://blog.npmjs.org/post/145260155635/introducing-hooks-get-notifications-of-npm) diff --git a/deps/npm/docs/content/commands/npm-init.md b/deps/npm/docs/content/commands/npm-init.md index d8d7acee77f018..b0efecdb7e6798 100644 --- a/deps/npm/docs/content/commands/npm-init.md +++ b/deps/npm/docs/content/commands/npm-init.md @@ -164,6 +164,8 @@ dot to represent the current directory in that context, e.g: `react-app .`: Automatically answer "yes" to any prompts that npm might print on the command line. + + #### `force` * Default: false @@ -190,6 +192,8 @@ mistakes, unnecessary performance degradation, and malicious input. If you don't have a clear idea of what you want to do, it is strongly recommended that you do not use this option! + + #### `scope` * Default: the scope of the current project, if any, or "" @@ -220,6 +224,7 @@ npm init --scope=@foo --yes ``` + #### `workspace` * Default: @@ -268,6 +273,8 @@ This value is not exported to the environment for child processes. If set to true, the npm cli will run an update after operations that may possibly change the workspaces installed to the `node_modules` folder. + + #### `include-workspace-root` * Default: false diff --git a/deps/npm/docs/content/commands/npm-install-ci-test.md b/deps/npm/docs/content/commands/npm-install-ci-test.md index c5fe98be705fcc..b38f4917708326 100644 --- a/deps/npm/docs/content/commands/npm-install-ci-test.md +++ b/deps/npm/docs/content/commands/npm-install-ci-test.md @@ -30,6 +30,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -42,6 +44,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -52,6 +56,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -70,6 +76,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `strict-peer-deps` * Default: false @@ -89,15 +97,7 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. #### `foreground-scripts` @@ -111,6 +111,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -123,6 +125,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -133,6 +137,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -145,6 +151,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -154,6 +162,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `dry-run` * Default: false @@ -167,6 +177,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `workspace` * Default: @@ -229,6 +241,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm install-test](/commands/npm-install-test) diff --git a/deps/npm/docs/content/commands/npm-install-test.md b/deps/npm/docs/content/commands/npm-install-test.md index b864051ca138c1..a2136fd52f3974 100644 --- a/deps/npm/docs/content/commands/npm-install-test.md +++ b/deps/npm/docs/content/commands/npm-install-test.md @@ -31,6 +31,8 @@ When used with the `npm rm` command, removes the dependency from Will also prevent writing to `package-lock.json` if set to `false`. + + #### `save-exact` * Default: false @@ -39,6 +41,8 @@ Will also prevent writing to `package-lock.json` if set to `false`. Dependencies saved to package.json will be configured with an exact version rather than using npm's default semver range operator. + + #### `global` * Default: false @@ -53,6 +57,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `install-strategy` * Default: "hoisted" @@ -65,6 +71,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -77,6 +85,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -87,6 +97,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -105,6 +117,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `strict-peer-deps` * Default: false @@ -124,6 +138,18 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. + + +#### `prefer-dedupe` + +* Default: false +* Type: Boolean + +Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency. + + + #### `package-lock` * Default: true @@ -132,7 +158,7 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. + #### `foreground-scripts` @@ -146,6 +172,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -158,6 +186,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -168,6 +198,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -180,6 +212,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -189,6 +223,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `dry-run` * Default: false @@ -202,6 +238,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `workspace` * Default: @@ -264,6 +302,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm install](/commands/npm-install) diff --git a/deps/npm/docs/content/commands/npm-install.md b/deps/npm/docs/content/commands/npm-install.md index a2225b9f3897d2..627d016fe1c193 100644 --- a/deps/npm/docs/content/commands/npm-install.md +++ b/deps/npm/docs/content/commands/npm-install.md @@ -421,6 +421,8 @@ When used with the `npm rm` command, removes the dependency from Will also prevent writing to `package-lock.json` if set to `false`. + + #### `save-exact` * Default: false @@ -429,6 +431,8 @@ Will also prevent writing to `package-lock.json` if set to `false`. Dependencies saved to package.json will be configured with an exact version rather than using npm's default semver range operator. + + #### `global` * Default: false @@ -443,6 +447,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `install-strategy` * Default: "hoisted" @@ -455,6 +461,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -467,6 +475,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -477,6 +487,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -495,6 +507,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `strict-peer-deps` * Default: false @@ -514,6 +528,18 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. + + +#### `prefer-dedupe` + +* Default: false +* Type: Boolean + +Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency. + + + #### `package-lock` * Default: true @@ -522,7 +548,7 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. + #### `foreground-scripts` @@ -536,6 +562,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -548,6 +576,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -558,6 +588,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -570,6 +602,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -579,6 +613,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `dry-run` * Default: false @@ -592,6 +628,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `workspace` * Default: @@ -654,6 +692,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### Algorithm Given a `package{dep}` structure: `A{B,C}, B{C}, C{D}`, diff --git a/deps/npm/docs/content/commands/npm-link.md b/deps/npm/docs/content/commands/npm-link.md index 9c4c61a6fb04d5..607dc60b190dc5 100644 --- a/deps/npm/docs/content/commands/npm-link.md +++ b/deps/npm/docs/content/commands/npm-link.md @@ -122,6 +122,8 @@ When used with the `npm rm` command, removes the dependency from Will also prevent writing to `package-lock.json` if set to `false`. + + #### `save-exact` * Default: false @@ -130,6 +132,8 @@ Will also prevent writing to `package-lock.json` if set to `false`. Dependencies saved to package.json will be configured with an exact version rather than using npm's default semver range operator. + + #### `global` * Default: false @@ -144,6 +148,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `install-strategy` * Default: "hoisted" @@ -156,6 +162,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -168,6 +176,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -178,6 +188,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `strict-peer-deps` * Default: false @@ -197,6 +209,8 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. + + #### `package-lock` * Default: true @@ -205,7 +219,7 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. + #### `omit` @@ -225,6 +239,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `ignore-scripts` * Default: false @@ -237,6 +253,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -247,6 +265,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -259,6 +279,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -268,6 +290,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `dry-run` * Default: false @@ -281,6 +305,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `workspace` * Default: @@ -343,6 +369,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-login.md b/deps/npm/docs/content/commands/npm-login.md index 00f10ad95eeb52..531dc71ae3926a 100644 --- a/deps/npm/docs/content/commands/npm-login.md +++ b/deps/npm/docs/content/commands/npm-login.md @@ -39,6 +39,8 @@ your existing record. The base URL of the npm registry. + + #### `scope` * Default: the scope of the current project, if any, or "" @@ -69,6 +71,7 @@ npm init --scope=@foo --yes ``` + #### `auth-type` * Default: "web" @@ -77,6 +80,8 @@ npm init --scope=@foo --yes What authentication strategy to use with `login`. Note that if an `otp` config is given, this value will always be set to `legacy`. + + ### See Also * [npm registry](/using-npm/registry) diff --git a/deps/npm/docs/content/commands/npm-logout.md b/deps/npm/docs/content/commands/npm-logout.md index 8ac3948f116d8a..2d5aa3e5827f74 100644 --- a/deps/npm/docs/content/commands/npm-logout.md +++ b/deps/npm/docs/content/commands/npm-logout.md @@ -34,6 +34,8 @@ connected to that scope, if set. The base URL of the npm registry. + + #### `scope` * Default: the scope of the current project, if any, or "" @@ -64,6 +66,7 @@ npm init --scope=@foo --yes ``` + ### See Also * [npm adduser](/commands/npm-adduser) diff --git a/deps/npm/docs/content/commands/npm-ls.md b/deps/npm/docs/content/commands/npm-ls.md index 1ba7a4b73d5000..3091ebfdeca70a 100644 --- a/deps/npm/docs/content/commands/npm-ls.md +++ b/deps/npm/docs/content/commands/npm-ls.md @@ -27,7 +27,7 @@ packages will *also* show the paths to the specified packages. For example, running `npm ls promzard` in npm's source tree will show: ```bash -npm@9.6.7 /path/to/npm +npm@9.7.1 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 ``` @@ -82,6 +82,8 @@ When running `npm outdated` and `npm ls`, setting `--all` will show all outdated or installed packages, rather than only those directly depended upon by the current project. + + #### `json` * Default: false @@ -94,6 +96,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `long` * Default: false @@ -101,6 +105,8 @@ Not supported by all npm commands. Show extended information in `ls`, `search`, and `help-search`. + + #### `parseable` * Default: false @@ -109,6 +115,8 @@ Show extended information in `ls`, `search`, and `help-search`. Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. + + #### `global` * Default: false @@ -123,6 +131,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `depth` * Default: `Infinity` if `--all` is set, otherwise `1` @@ -133,6 +143,8 @@ The depth to go when recursing packages for `npm ls`. If not set, `npm ls` will show only the immediate dependencies of the root project. If `--all` is set, then npm will show all dependencies by default. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -151,6 +163,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `link` * Default: false @@ -158,6 +172,8 @@ variable will be set to `'production'` for all lifecycle scripts. Used with `npm ls`, limiting output to only those packages that are linked. + + #### `package-lock-only` * Default: false @@ -172,6 +188,8 @@ instead of checking `node_modules` and downloading dependencies. For `list` this means the output will be based on the tree described by the `package-lock.json`, rather than the contents of `node_modules`. + + #### `unicode` * Default: false on windows, true on mac/unix systems with a unicode locale, @@ -181,6 +199,8 @@ For `list` this means the output will be based on the tree described by the When set to true, npm uses unicode characters in the tree output. When false, it uses ascii characters instead of unicode glyphs. + + #### `workspace` * Default: @@ -243,6 +263,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-org.md b/deps/npm/docs/content/commands/npm-org.md index ca788b01fcb966..f06524731df51d 100644 --- a/deps/npm/docs/content/commands/npm-org.md +++ b/deps/npm/docs/content/commands/npm-org.md @@ -69,6 +69,8 @@ listing them, and finding specific ones and their roles. The base URL of the npm registry. + + #### `otp` * Default: null @@ -80,6 +82,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + #### `json` * Default: false @@ -92,6 +96,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `parseable` * Default: false @@ -100,6 +106,8 @@ Not supported by all npm commands. Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. + + ### See Also * [using orgs](/using-npm/orgs) diff --git a/deps/npm/docs/content/commands/npm-outdated.md b/deps/npm/docs/content/commands/npm-outdated.md index 0e1061ab168aea..b1a1c62688e650 100644 --- a/deps/npm/docs/content/commands/npm-outdated.md +++ b/deps/npm/docs/content/commands/npm-outdated.md @@ -95,6 +95,8 @@ When running `npm outdated` and `npm ls`, setting `--all` will show all outdated or installed packages, rather than only those directly depended upon by the current project. + + #### `json` * Default: false @@ -107,6 +109,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `long` * Default: false @@ -114,6 +118,8 @@ Not supported by all npm commands. Show extended information in `ls`, `search`, and `help-search`. + + #### `parseable` * Default: false @@ -122,6 +128,8 @@ Show extended information in `ls`, `search`, and `help-search`. Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. + + #### `global` * Default: false @@ -136,6 +144,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-owner.md b/deps/npm/docs/content/commands/npm-owner.md index 2f1ca487d55aca..cd172adc3dee8d 100644 --- a/deps/npm/docs/content/commands/npm-owner.md +++ b/deps/npm/docs/content/commands/npm-owner.md @@ -42,6 +42,8 @@ flow when changing ownership or include an otp on the command line with `--otp`. The base URL of the npm registry. + + #### `otp` * Default: null @@ -53,6 +55,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-pack.md b/deps/npm/docs/content/commands/npm-pack.md index a39f0554391991..2ef859786085f2 100644 --- a/deps/npm/docs/content/commands/npm-pack.md +++ b/deps/npm/docs/content/commands/npm-pack.md @@ -25,6 +25,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `json` * Default: false @@ -37,6 +39,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `pack-destination` * Default: "." @@ -44,6 +48,8 @@ Not supported by all npm commands. Directory in which `npm pack` will save tarballs. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-ping.md b/deps/npm/docs/content/commands/npm-ping.md index 812be9f002deb8..cc3326f7594286 100644 --- a/deps/npm/docs/content/commands/npm-ping.md +++ b/deps/npm/docs/content/commands/npm-ping.md @@ -37,6 +37,8 @@ npm ERR! 404 Not Found - GET http://www.foo.com/-/ping?write=true The base URL of the npm registry. + + ### See Also * [npm doctor](/commands/npm-doctor) diff --git a/deps/npm/docs/content/commands/npm-pkg.md b/deps/npm/docs/content/commands/npm-pkg.md index 484aabfca5431c..1df2a8d1ddb898 100644 --- a/deps/npm/docs/content/commands/npm-pkg.md +++ b/deps/npm/docs/content/commands/npm-pkg.md @@ -201,6 +201,8 @@ mistakes, unnecessary performance degradation, and malicious input. If you don't have a clear idea of what you want to do, it is strongly recommended that you do not use this option! + + #### `json` * Default: false @@ -213,6 +215,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-prefix.md b/deps/npm/docs/content/commands/npm-prefix.md index e17a26d346b875..7718ed34ff828c 100644 --- a/deps/npm/docs/content/commands/npm-prefix.md +++ b/deps/npm/docs/content/commands/npm-prefix.md @@ -49,6 +49,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + ### See Also * [npm root](/commands/npm-root) diff --git a/deps/npm/docs/content/commands/npm-profile.md b/deps/npm/docs/content/commands/npm-profile.md index b8cdde7e151a63..d048532c98d452 100644 --- a/deps/npm/docs/content/commands/npm-profile.md +++ b/deps/npm/docs/content/commands/npm-profile.md @@ -81,6 +81,8 @@ Some of these commands may not be available on non npmjs.com registries. The base URL of the npm registry. + + #### `json` * Default: false @@ -93,6 +95,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `parseable` * Default: false @@ -101,6 +105,8 @@ Not supported by all npm commands. Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. + + #### `otp` * Default: null @@ -112,6 +118,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + ### See Also * [npm adduser](/commands/npm-adduser) diff --git a/deps/npm/docs/content/commands/npm-prune.md b/deps/npm/docs/content/commands/npm-prune.md index f0374944cc3f88..071258e78471ba 100644 --- a/deps/npm/docs/content/commands/npm-prune.md +++ b/deps/npm/docs/content/commands/npm-prune.md @@ -53,6 +53,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `dry-run` * Default: false @@ -66,6 +68,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `json` * Default: false @@ -78,6 +82,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `foreground-scripts` * Default: false @@ -90,6 +96,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -102,6 +110,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `workspace` * Default: @@ -164,6 +174,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm uninstall](/commands/npm-uninstall) diff --git a/deps/npm/docs/content/commands/npm-publish.md b/deps/npm/docs/content/commands/npm-publish.md index 334209490b2492..0e18cddf8b36d4 100644 --- a/deps/npm/docs/content/commands/npm-publish.md +++ b/deps/npm/docs/content/commands/npm-publish.md @@ -101,6 +101,8 @@ command, if no explicit tag is given. When used by the `npm diff` command, this is the tag used to fetch the tarball that will be compared with the local files by default. + + #### `access` * Default: 'public' for new packages, existing packages it will not change the @@ -117,6 +119,8 @@ packages. Specifying a value of `restricted` or `public` during publish will change the access for an existing package the same way that `npm access set status` would. + + #### `dry-run` * Default: false @@ -130,6 +134,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `otp` * Default: null @@ -141,6 +147,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + #### `workspace` * Default: @@ -202,6 +210,17 @@ This value is not exported to the environment for child processes. When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from. +This config can not be used with: `provenance-file` + +#### `provenance-file` + +* Default: null +* Type: Path + +When publishing, the provenance bundle at the given path will be used. + +This config can not be used with: `provenance` + ### See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-query.md b/deps/npm/docs/content/commands/npm-query.md index 5a6bfb79cee331..ec9cc2c5752f92 100644 --- a/deps/npm/docs/content/commands/npm-query.md +++ b/deps/npm/docs/content/commands/npm-query.md @@ -152,6 +152,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-rebuild.md b/deps/npm/docs/content/commands/npm-rebuild.md index 8a58a6176fa7d2..c42e09767ef4b4 100644 --- a/deps/npm/docs/content/commands/npm-rebuild.md +++ b/deps/npm/docs/content/commands/npm-rebuild.md @@ -39,6 +39,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `bin-links` * Default: true @@ -51,6 +53,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `foreground-scripts` * Default: false @@ -63,6 +67,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -75,6 +81,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `workspace` * Default: @@ -137,6 +145,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-repo.md b/deps/npm/docs/content/commands/npm-repo.md index 10ddc139f8535a..005f4ac8715838 100644 --- a/deps/npm/docs/content/commands/npm-repo.md +++ b/deps/npm/docs/content/commands/npm-repo.md @@ -32,6 +32,8 @@ terminal. Set to `true` to use default system URL opener. + + #### `registry` * Default: "https://registry.npmjs.org/" @@ -39,6 +41,8 @@ Set to `true` to use default system URL opener. The base URL of the npm registry. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-restart.md b/deps/npm/docs/content/commands/npm-restart.md index 6c31cfceb51189..545315c742fd02 100644 --- a/deps/npm/docs/content/commands/npm-restart.md +++ b/deps/npm/docs/content/commands/npm-restart.md @@ -48,6 +48,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `script-shell` * Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows @@ -56,6 +58,8 @@ will *not* run any pre- or post-scripts. The shell to use for scripts run with the `npm exec`, `npm run` and `npm init ` commands. + + ### See Also * [npm run-script](/commands/npm-run-script) diff --git a/deps/npm/docs/content/commands/npm-root.md b/deps/npm/docs/content/commands/npm-root.md index 41777d30255620..75d70c2afb6265 100644 --- a/deps/npm/docs/content/commands/npm-root.md +++ b/deps/npm/docs/content/commands/npm-root.md @@ -41,6 +41,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + ### See Also * [npm prefix](/commands/npm-prefix) diff --git a/deps/npm/docs/content/commands/npm-run-script.md b/deps/npm/docs/content/commands/npm-run-script.md index 26011e4f7959a6..9e3ae1e9b2571a 100644 --- a/deps/npm/docs/content/commands/npm-run-script.md +++ b/deps/npm/docs/content/commands/npm-run-script.md @@ -216,6 +216,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `foreground-scripts` * Default: false @@ -228,6 +230,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `script-shell` * Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows @@ -236,6 +240,8 @@ but can be useful for debugging. The shell to use for scripts run with the `npm exec`, `npm run` and `npm init ` commands. + + ### See Also * [npm scripts](/using-npm/scripts) diff --git a/deps/npm/docs/content/commands/npm-search.md b/deps/npm/docs/content/commands/npm-search.md index 3e4fa4553957a7..df5cc51b417ea2 100644 --- a/deps/npm/docs/content/commands/npm-search.md +++ b/deps/npm/docs/content/commands/npm-search.md @@ -46,6 +46,8 @@ expression characters in most shells.) Show extended information in `ls`, `search`, and `help-search`. + + #### `json` * Default: false @@ -58,6 +60,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `color` * Default: true unless the NO_COLOR environ is set to something other than '0' @@ -66,6 +70,8 @@ Not supported by all npm commands. If false, never shows colors. If `"always"` then always shows colors. If true, then only prints color codes for tty file descriptors. + + #### `parseable` * Default: false @@ -74,6 +80,8 @@ true, then only prints color codes for tty file descriptors. Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. + + #### `description` * Default: true @@ -81,6 +89,8 @@ Output parseable results from commands that write to standard output. For Show the description in `npm search` + + #### `searchopts` * Default: "" @@ -88,6 +98,8 @@ Show the description in `npm search` Space-separated options that are always passed to search. + + #### `searchexclude` * Default: "" @@ -95,6 +107,8 @@ Space-separated options that are always passed to search. Space-separated options that limit the results from search. + + #### `registry` * Default: "https://registry.npmjs.org/" @@ -102,6 +116,8 @@ Space-separated options that limit the results from search. The base URL of the npm registry. + + #### `prefer-online` * Default: false @@ -110,6 +126,8 @@ The base URL of the npm registry. If true, staleness checks for cached data will be forced, making the CLI look for updates immediately even for fresh package data. + + #### `prefer-offline` * Default: false @@ -119,6 +137,8 @@ If true, staleness checks for cached data will be bypassed, but missing data will be requested from the server. To force full offline mode, use `--offline`. + + #### `offline` * Default: false @@ -127,6 +147,8 @@ will be requested from the server. To force full offline mode, use Force offline mode: no network requests will be done during install. To allow the CLI to fill in missing cache data, see `--prefer-offline`. + + ### See Also * [npm registry](/using-npm/registry) diff --git a/deps/npm/docs/content/commands/npm-star.md b/deps/npm/docs/content/commands/npm-star.md index ba70051f10ac92..59e1fbec52cc97 100644 --- a/deps/npm/docs/content/commands/npm-star.md +++ b/deps/npm/docs/content/commands/npm-star.md @@ -42,6 +42,8 @@ You can see all your starred packages using [`npm stars`](/commands/npm-stars) The base URL of the npm registry. + + #### `unicode` * Default: false on windows, true on mac/unix systems with a unicode locale, @@ -51,6 +53,8 @@ The base URL of the npm registry. When set to true, npm uses unicode characters in the tree output. When false, it uses ascii characters instead of unicode glyphs. + + #### `otp` * Default: null @@ -62,6 +66,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + ### See Also * [package spec](/using-npm/package-spec) diff --git a/deps/npm/docs/content/commands/npm-stars.md b/deps/npm/docs/content/commands/npm-stars.md index 114cde202e2fa9..642ccfa14f1956 100644 --- a/deps/npm/docs/content/commands/npm-stars.md +++ b/deps/npm/docs/content/commands/npm-stars.md @@ -29,6 +29,8 @@ you will most certainly enjoy this command. The base URL of the npm registry. + + ### See Also * [npm star](/commands/npm-star) diff --git a/deps/npm/docs/content/commands/npm-start.md b/deps/npm/docs/content/commands/npm-start.md index 7ba8425ffa4748..cf9392c605c33f 100644 --- a/deps/npm/docs/content/commands/npm-start.md +++ b/deps/npm/docs/content/commands/npm-start.md @@ -59,6 +59,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `script-shell` * Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows @@ -67,6 +69,8 @@ will *not* run any pre- or post-scripts. The shell to use for scripts run with the `npm exec`, `npm run` and `npm init ` commands. + + ### See Also * [npm run-script](/commands/npm-run-script) diff --git a/deps/npm/docs/content/commands/npm-stop.md b/deps/npm/docs/content/commands/npm-stop.md index 05df3fb7d7425e..6075b4363c2fa7 100644 --- a/deps/npm/docs/content/commands/npm-stop.md +++ b/deps/npm/docs/content/commands/npm-stop.md @@ -52,6 +52,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `script-shell` * Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows @@ -60,6 +62,8 @@ will *not* run any pre- or post-scripts. The shell to use for scripts run with the `npm exec`, `npm run` and `npm init ` commands. + + ### See Also * [npm run-script](/commands/npm-run-script) diff --git a/deps/npm/docs/content/commands/npm-team.md b/deps/npm/docs/content/commands/npm-team.md index 68b2192673d326..a32619a75fe182 100644 --- a/deps/npm/docs/content/commands/npm-team.md +++ b/deps/npm/docs/content/commands/npm-team.md @@ -109,6 +109,8 @@ use the `npm access` command to grant or revoke the appropriate permissions. The base URL of the npm registry. + + #### `otp` * Default: null @@ -120,6 +122,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + #### `parseable` * Default: false @@ -128,6 +132,8 @@ password, npm will prompt on the command line for one. Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. + + #### `json` * Default: false @@ -140,6 +146,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + ### See Also * [npm access](/commands/npm-access) diff --git a/deps/npm/docs/content/commands/npm-test.md b/deps/npm/docs/content/commands/npm-test.md index ffdb578d10fc4e..72a7822b59fc3c 100644 --- a/deps/npm/docs/content/commands/npm-test.md +++ b/deps/npm/docs/content/commands/npm-test.md @@ -49,6 +49,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `script-shell` * Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows @@ -57,6 +59,8 @@ will *not* run any pre- or post-scripts. The shell to use for scripts run with the `npm exec`, `npm run` and `npm init ` commands. + + ### See Also * [npm run-script](/commands/npm-run-script) diff --git a/deps/npm/docs/content/commands/npm-token.md b/deps/npm/docs/content/commands/npm-token.md index bfd8e05a14f3fd..a17193d5fe8d05 100644 --- a/deps/npm/docs/content/commands/npm-token.md +++ b/deps/npm/docs/content/commands/npm-token.md @@ -85,6 +85,8 @@ This lets you list, create and revoke authentication tokens. This is used to mark a token as unable to publish when configuring limited access tokens with the `npm token create` command. + + #### `cidr` * Default: null @@ -93,6 +95,8 @@ access tokens with the `npm token create` command. This is a list of CIDR address to be used when configuring limited access tokens with the `npm token create` command. + + #### `registry` * Default: "https://registry.npmjs.org/" @@ -100,6 +104,8 @@ tokens with the `npm token create` command. The base URL of the npm registry. + + #### `otp` * Default: null @@ -111,6 +117,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + ### See Also * [npm adduser](/commands/npm-adduser) diff --git a/deps/npm/docs/content/commands/npm-uninstall.md b/deps/npm/docs/content/commands/npm-uninstall.md index ef12bcd64ac917..de90df9c0c3bc5 100644 --- a/deps/npm/docs/content/commands/npm-uninstall.md +++ b/deps/npm/docs/content/commands/npm-uninstall.md @@ -68,6 +68,24 @@ When used with the `npm rm` command, removes the dependency from Will also prevent writing to `package-lock.json` if set to `false`. + + +#### `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` + + + #### `workspace` * Default: @@ -130,6 +148,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm prune](/commands/npm-prune) diff --git a/deps/npm/docs/content/commands/npm-unpublish.md b/deps/npm/docs/content/commands/npm-unpublish.md index 20ef4afa947dce..52f2961246b1f1 100644 --- a/deps/npm/docs/content/commands/npm-unpublish.md +++ b/deps/npm/docs/content/commands/npm-unpublish.md @@ -52,6 +52,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `force` * Default: false @@ -78,6 +80,8 @@ mistakes, unnecessary performance degradation, and malicious input. If you don't have a clear idea of what you want to do, it is strongly recommended that you do not use this option! + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-unstar.md b/deps/npm/docs/content/commands/npm-unstar.md index 7e49ad096a8284..92ae740befa391 100644 --- a/deps/npm/docs/content/commands/npm-unstar.md +++ b/deps/npm/docs/content/commands/npm-unstar.md @@ -38,6 +38,8 @@ You can see all your starred packages using [`npm stars`](/commands/npm-stars) The base URL of the npm registry. + + #### `unicode` * Default: false on windows, true on mac/unix systems with a unicode locale, @@ -47,6 +49,8 @@ The base URL of the npm registry. When set to true, npm uses unicode characters in the tree output. When false, it uses ascii characters instead of unicode glyphs. + + #### `otp` * Default: null @@ -58,6 +62,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + ### See Also * [npm star](/commands/npm-star) diff --git a/deps/npm/docs/content/commands/npm-update.md b/deps/npm/docs/content/commands/npm-update.md index fa9d963c4f9608..7a8adb62bbb27f 100644 --- a/deps/npm/docs/content/commands/npm-update.md +++ b/deps/npm/docs/content/commands/npm-update.md @@ -169,6 +169,8 @@ When used with the `npm rm` command, removes the dependency from Will also prevent writing to `package-lock.json` if set to `false`. + + #### `global` * Default: false @@ -183,6 +185,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `install-strategy` * Default: "hoisted" @@ -195,6 +199,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `legacy-bundling` * Default: false @@ -207,6 +213,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `global-style` * Default: false @@ -217,6 +225,8 @@ de-duplicating. Sets `--install-strategy=nested`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -235,6 +245,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `strict-peer-deps` * Default: false @@ -254,6 +266,8 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. + + #### `package-lock` * Default: true @@ -262,7 +276,7 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. + #### `foreground-scripts` @@ -276,6 +290,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `ignore-scripts` * Default: false @@ -288,6 +304,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `audit` * Default: true @@ -298,6 +316,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `bin-links` * Default: true @@ -310,6 +330,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `fund` * Default: true @@ -319,6 +341,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `dry-run` * Default: false @@ -332,6 +356,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `workspace` * Default: @@ -394,6 +420,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + ### See Also * [npm install](/commands/npm-install) diff --git a/deps/npm/docs/content/commands/npm-version.md b/deps/npm/docs/content/commands/npm-version.md index 00d165cfbc77f1..bc31b4a12a7324 100644 --- a/deps/npm/docs/content/commands/npm-version.md +++ b/deps/npm/docs/content/commands/npm-version.md @@ -22,6 +22,8 @@ alias: verison Prevents throwing an error when `npm version` is used to set the new version to the same value as the current version. + + #### `commit-hooks` * Default: true @@ -29,6 +31,8 @@ to the same value as the current version. Run git commit hooks when using the `npm version` command. + + #### `git-tag-version` * Default: true @@ -37,6 +41,8 @@ Run git commit hooks when using the `npm version` command. Tag the commit when using the `npm version` command. Setting this to false results in no commit being made at all. + + #### `json` * Default: false @@ -49,6 +55,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `preid` * Default: "" @@ -57,6 +65,8 @@ Not supported by all npm commands. The "prerelease identifier" to use as a prefix for the "prerelease" part of a semver. Like the `rc` in `1.2.0-rc.8`. + + #### `sign-git-tag` * Default: false @@ -68,6 +78,8 @@ If set to true, then the `npm version` command will tag the version using Note that git requires you to have set up GPG keys in your git configs for this to work properly. + + #### `workspace` * Default: @@ -116,6 +128,8 @@ This value is not exported to the environment for child processes. If set to true, the npm cli will run an update after operations that may possibly change the workspaces installed to the `node_modules` folder. + + #### `include-workspace-root` * Default: false diff --git a/deps/npm/docs/content/commands/npm-view.md b/deps/npm/docs/content/commands/npm-view.md index 14a94305b82f34..280b6ebe1f091b 100644 --- a/deps/npm/docs/content/commands/npm-view.md +++ b/deps/npm/docs/content/commands/npm-view.md @@ -114,6 +114,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `workspace` * Default: diff --git a/deps/npm/docs/content/commands/npm-whoami.md b/deps/npm/docs/content/commands/npm-whoami.md index 3801dfaa4882b2..a1458f0202355c 100644 --- a/deps/npm/docs/content/commands/npm-whoami.md +++ b/deps/npm/docs/content/commands/npm-whoami.md @@ -32,6 +32,8 @@ If logged into a registry that uses Basic Auth, then simply print the The base URL of the npm registry. + + ### See Also * [npm config](/commands/npm-config) diff --git a/deps/npm/docs/content/commands/npm.md b/deps/npm/docs/content/commands/npm.md index 347e7d40993c88..4cd80b802510a7 100644 --- a/deps/npm/docs/content/commands/npm.md +++ b/deps/npm/docs/content/commands/npm.md @@ -14,7 +14,7 @@ Note: This command is unaware of workspaces. ### Version -9.6.7 +9.7.1 ### Description diff --git a/deps/npm/docs/content/using-npm/config.md b/deps/npm/docs/content/using-npm/config.md index 51983cbbe16718..9d1f02c42639e1 100644 --- a/deps/npm/docs/content/using-npm/config.md +++ b/deps/npm/docs/content/using-npm/config.md @@ -136,6 +136,8 @@ Warning: This should generally not be set via a command-line option. It is safer to use a registry-provided authentication bearer token stored in the ~/.npmrc file by running `npm login`. + + #### `access` * Default: 'public' for new packages, existing packages it will not change the @@ -152,6 +154,8 @@ packages. Specifying a value of `restricted` or `public` during publish will change the access for an existing package the same way that `npm access set status` would. + + #### `all` * Default: false @@ -161,6 +165,8 @@ When running `npm outdated` and `npm ls`, setting `--all` will show all outdated or installed packages, rather than only those directly depended upon by the current project. + + #### `allow-same-version` * Default: false @@ -169,6 +175,8 @@ upon by the current project. Prevents throwing an error when `npm version` is used to set the new version to the same value as the current version. + + #### `audit` * Default: true @@ -179,6 +187,8 @@ default registry and all registries configured for scopes. See the documentation for [`npm audit`](/commands/npm-audit) for details on what is submitted. + + #### `audit-level` * Default: null @@ -187,6 +197,8 @@ submitted. The minimum level of vulnerability for `npm audit` to exit with a non-zero exit code. + + #### `auth-type` * Default: "web" @@ -195,6 +207,8 @@ exit code. What authentication strategy to use with `login`. Note that if an `otp` config is given, this value will always be set to `legacy`. + + #### `before` * Default: null @@ -210,6 +224,8 @@ If the requested version is a `dist-tag` and the given tag does not pass the will be used. For example, `foo@latest` might install `foo@1.2` even though `latest` is `2.0`. + + #### `bin-links` * Default: true @@ -222,6 +238,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### `browser` * Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` @@ -234,6 +252,8 @@ terminal. Set to `true` to use default system URL opener. + + #### `ca` * Default: null @@ -260,6 +280,8 @@ ca[]="..." See also the `strict-ssl` config. + + #### `cache` * Default: Windows: `%LocalAppData%\npm-cache`, Posix: `~/.npm` @@ -267,6 +289,8 @@ See also the `strict-ssl` config. The location of npm's cache directory. + + #### `cafile` * Default: null @@ -276,6 +300,8 @@ A path to a file containing one or multiple Certificate Authority signing certificates. Similar to the `ca` setting, but allows for multiple CA's, as well as for the CA information to be stored in a file on disk. + + #### `call` * Default: "" @@ -289,6 +315,7 @@ npm exec --package yo --package generator-node --call "yo node" ``` + #### `cidr` * Default: null @@ -297,6 +324,8 @@ npm exec --package yo --package generator-node --call "yo node" This is a list of CIDR address to be used when configuring limited access tokens with the `npm token create` command. + + #### `color` * Default: true unless the NO_COLOR environ is set to something other than '0' @@ -305,6 +334,8 @@ tokens with the `npm token create` command. If false, never shows colors. If `"always"` then always shows colors. If true, then only prints color codes for tty file descriptors. + + #### `commit-hooks` * Default: true @@ -312,6 +343,8 @@ true, then only prints color codes for tty file descriptors. Run git commit hooks when using the `npm version` command. + + #### `depth` * Default: `Infinity` if `--all` is set, otherwise `1` @@ -322,6 +355,8 @@ The depth to go when recursing packages for `npm ls`. If not set, `npm ls` will show only the immediate dependencies of the root project. If `--all` is set, then npm will show all dependencies by default. + + #### `description` * Default: true @@ -329,6 +364,8 @@ project. If `--all` is set, then npm will show all dependencies by default. Show the description in `npm search` + + #### `diff` * Default: @@ -336,6 +373,8 @@ Show the description in `npm search` Define arguments to compare in `npm diff`. + + #### `diff-dst-prefix` * Default: "b/" @@ -343,6 +382,8 @@ Define arguments to compare in `npm diff`. Destination prefix to be used in `npm diff` output. + + #### `diff-ignore-all-space` * Default: false @@ -350,6 +391,8 @@ Destination prefix to be used in `npm diff` output. Ignore whitespace when comparing lines in `npm diff`. + + #### `diff-name-only` * Default: false @@ -357,6 +400,8 @@ Ignore whitespace when comparing lines in `npm diff`. Prints only filenames when using `npm diff`. + + #### `diff-no-prefix` * Default: false @@ -367,6 +412,8 @@ Do not show any source or destination prefix in `npm diff` output. Note: this causes `npm diff` to ignore the `--diff-src-prefix` and `--diff-dst-prefix` configs. + + #### `diff-src-prefix` * Default: "a/" @@ -374,6 +421,8 @@ Note: this causes `npm diff` to ignore the `--diff-src-prefix` and Source prefix to be used in `npm diff` output. + + #### `diff-text` * Default: false @@ -381,6 +430,8 @@ Source prefix to be used in `npm diff` output. Treat all files as text in `npm diff`. + + #### `diff-unified` * Default: 3 @@ -388,6 +439,8 @@ Treat all files as text in `npm diff`. The number of lines of context to print in `npm diff`. + + #### `dry-run` * Default: false @@ -401,6 +454,8 @@ commands that modify your local installation, eg, `install`, `update`, Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. + + #### `editor` * Default: The EDITOR or VISUAL environment variables, or @@ -409,6 +464,8 @@ Note: This is NOT honored by other network related commands, eg `dist-tags`, The command to run for `npm edit` and `npm config edit`. + + #### `engine-strict` * Default: false @@ -420,6 +477,8 @@ Node.js version. This can be overridden by setting the `--force` flag. + + #### `fetch-retries` * Default: 2 @@ -431,6 +490,8 @@ from the registry. npm will retry idempotent read requests to the registry in the case of network failures or 5xx HTTP errors. + + #### `fetch-retry-factor` * Default: 10 @@ -438,6 +499,8 @@ network failures or 5xx HTTP errors. The "factor" config for the `retry` module to use when fetching packages. + + #### `fetch-retry-maxtimeout` * Default: 60000 (1 minute) @@ -446,6 +509,8 @@ The "factor" config for the `retry` module to use when fetching packages. The "maxTimeout" config for the `retry` module to use when fetching packages. + + #### `fetch-retry-mintimeout` * Default: 10000 (10 seconds) @@ -454,6 +519,8 @@ packages. The "minTimeout" config for the `retry` module to use when fetching packages. + + #### `fetch-timeout` * Default: 300000 (5 minutes) @@ -461,6 +528,8 @@ packages. The maximum amount of time to wait for HTTP requests to complete. + + #### `force` * Default: false @@ -487,6 +556,8 @@ mistakes, unnecessary performance degradation, and malicious input. If you don't have a clear idea of what you want to do, it is strongly recommended that you do not use this option! + + #### `foreground-scripts` * Default: false @@ -499,6 +570,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### `format-package-lock` * Default: true @@ -507,6 +580,8 @@ but can be useful for debugging. Format `package-lock.json` or `npm-shrinkwrap.json` as a human readable file. + + #### `fund` * Default: true @@ -516,6 +591,8 @@ When "true" displays the message at the end of each `npm install` acknowledging the number of dependencies looking for funding. See [`npm fund`](/commands/npm-fund) for details. + + #### `git` * Default: "git" @@ -524,6 +601,8 @@ fund`](/commands/npm-fund) for details. The command to use for git commands. If git is installed on the computer, but is not in the `PATH`, then set this to the full path to the git binary. + + #### `git-tag-version` * Default: true @@ -532,6 +611,8 @@ but is not in the `PATH`, then set this to the full path to the git binary. Tag the commit when using the `npm version` command. Setting this to false results in no commit being made at all. + + #### `global` * Default: false @@ -546,6 +627,8 @@ folder instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `globalconfig` * Default: The global --prefix setting plus 'etc/npmrc'. For example, @@ -554,6 +637,8 @@ folder instead of the current working directory. See The config file to read for global config options. + + #### `heading` * Default: "npm" @@ -561,6 +646,8 @@ The config file to read for global config options. The string that starts all the debugging log output. + + #### `https-proxy` * Default: null @@ -571,6 +658,8 @@ A proxy to use for outgoing https requests. If the `HTTPS_PROXY` or proxy settings will be honored by the underlying `make-fetch-happen` library. + + #### `if-present` * Default: false @@ -597,6 +686,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if `ignore-scripts` is set, but they will *not* run any pre- or post-scripts. + + #### `include` * Default: @@ -609,6 +700,8 @@ This is the inverse of `--omit=`. Dependency types specified in `--include` will not be omitted, regardless of the order in which omit/include are specified on the command-line. + + #### `include-staged` * Default: false @@ -619,6 +712,8 @@ Allow installing "staged" published packages, as defined by [npm RFC PR This is experimental, and not implemented by the npm public registry. + + #### `include-workspace-root` * Default: false @@ -639,6 +734,8 @@ This value is not exported to the environment for child processes. The value `npm init` should use by default for the package author's email. + + #### `init-author-name` * Default: "" @@ -646,6 +743,8 @@ The value `npm init` should use by default for the package author's email. The value `npm init` should use by default for the package author's name. + + #### `init-author-url` * Default: "" @@ -654,6 +753,8 @@ The value `npm init` should use by default for the package author's name. The value `npm init` should use by default for the package author's homepage. + + #### `init-license` * Default: "ISC" @@ -661,6 +762,8 @@ homepage. The value `npm init` should use by default for the package license. + + #### `init-module` * Default: "~/.npm-init.js" @@ -671,6 +774,8 @@ documentation for the [init-package-json](https://github.com/npm/init-package-json) module for more information, or [npm init](/commands/npm-init). + + #### `init-version` * Default: "1.0.0" @@ -679,6 +784,8 @@ more information, or [npm init](/commands/npm-init). The value that `npm init` should use by default for the package version number, if not already set in package.json. + + #### `install-links` * Default: false @@ -688,6 +795,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + #### `install-strategy` * Default: "hoisted" @@ -700,6 +809,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### `json` * Default: false @@ -712,6 +823,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### `legacy-peer-deps` * Default: false @@ -730,6 +843,8 @@ This differs from `--omit=peer`, in that `--omit=peer` will avoid unpacking Use of `legacy-peer-deps` is not recommended, as it will not enforce the `peerDependencies` contract that meta-dependencies may rely on. + + #### `link` * Default: false @@ -737,6 +852,8 @@ Use of `legacy-peer-deps` is not recommended, as it will not enforce the Used with `npm ls`, limiting output to only those packages that are linked. + + #### `local-address` * Default: null @@ -745,6 +862,8 @@ Used with `npm ls`, limiting output to only those packages that are linked. The IP address of the local interface to use when making connections to the npm registry. Must be IPv4 in versions of Node prior to 0.12. + + #### `location` * Default: "user" unless `--global` is passed, which will also set this value @@ -762,6 +881,8 @@ instead of the current working directory. See * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` + + #### `lockfile-version` * Default: Version 3 if no lockfile, auto-converting v1 lockfiles to v3, @@ -784,6 +905,8 @@ determinism and interoperability, at the expense of more bytes on disk. disk than lockfile version 2, but not interoperable with older npm versions. Ideal if all users are on npm version 7 and higher. + + #### `loglevel` * Default: "notice" @@ -798,6 +921,8 @@ Any logs of a higher level than the setting are shown. The default is See also the `foreground-scripts` config. + + #### `logs-dir` * Default: A directory named `_logs` inside the cache @@ -806,6 +931,8 @@ See also the `foreground-scripts` config. The location of npm's log directory. See [`npm logging`](/using-npm/logging) for more information. + + #### `logs-max` * Default: 10 @@ -815,6 +942,8 @@ The maximum number of log files to store. If set to 0, no log files will be written for the current run. + + #### `long` * Default: false @@ -822,6 +951,8 @@ If set to 0, no log files will be written for the current run. Show extended information in `ls`, `search`, and `help-search`. + + #### `maxsockets` * Default: 15 @@ -830,6 +961,8 @@ Show extended information in `ls`, `search`, and `help-search`. The maximum number of connections to use per origin (protocol/host/port combination). + + #### `message` * Default: "%s" @@ -839,6 +972,8 @@ Commit message which is used by `npm version` when creating version commit. Any "%s" in the message will be replaced with the version number. + + #### `node-options` * Default: null @@ -848,6 +983,8 @@ Options to pass through to Node.js via the `NODE_OPTIONS` environment variable. This does not impact how npm itself is executed but it does impact how lifecycle scripts are called. + + #### `noproxy` * Default: The value of the NO_PROXY environment variable @@ -857,6 +994,8 @@ Domain extensions that should bypass any proxies. Also accepts a comma-delimited string. + + #### `offline` * Default: false @@ -865,6 +1004,8 @@ Also accepts a comma-delimited string. Force offline mode: no network requests will be done during install. To allow the CLI to fill in missing cache data, see `--prefer-offline`. + + #### `omit` * Default: 'dev' if the `NODE_ENV` environment variable is set to @@ -883,6 +1024,8 @@ it will be included. If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment variable will be set to `'production'` for all lifecycle scripts. + + #### `omit-lockfile-registry-resolved` * Default: false @@ -893,6 +1036,8 @@ registry dependencies. Subsequent installs will need to resolve tarball endpoints with the configured registry, likely resulting in a longer install time. + + #### `otp` * Default: null @@ -904,6 +1049,8 @@ when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + #### `pack-destination` * Default: "." @@ -911,6 +1058,8 @@ password, npm will prompt on the command line for one. Directory in which `npm pack` will save tarballs. + + #### `package` * Default: @@ -918,6 +1067,8 @@ Directory in which `npm pack` will save tarballs. The package or packages to install for [`npm exec`](/commands/npm-exec) + + #### `package-lock` * Default: true @@ -926,7 +1077,7 @@ The package or packages to install for [`npm exec`](/commands/npm-exec) If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -This configuration does not affect `npm ci`. + #### `package-lock-only` @@ -942,6 +1093,8 @@ instead of checking `node_modules` and downloading dependencies. For `list` this means the output will be based on the tree described by the `package-lock.json`, rather than the contents of `node_modules`. + + #### `parseable` * Default: false @@ -950,6 +1103,18 @@ For `list` this means the output will be based on the tree described by the Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. + + +#### `prefer-dedupe` + +* Default: false +* Type: Boolean + +Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency. + + + #### `prefer-offline` * Default: false @@ -959,6 +1124,8 @@ If true, staleness checks for cached data will be bypassed, but missing data will be requested from the server. To force full offline mode, use `--offline`. + + #### `prefer-online` * Default: false @@ -967,6 +1134,8 @@ will be requested from the server. To force full offline mode, use If true, staleness checks for cached data will be forced, making the CLI look for updates immediately even for fresh package data. + + #### `prefix` * Default: In global mode, the folder where the node executable is installed. @@ -977,6 +1146,8 @@ look for updates immediately even for fresh package data. The location to install global items. If set on the command line, then it forces non-global commands to run in the specified folder. + + #### `preid` * Default: "" @@ -985,6 +1156,8 @@ forces non-global commands to run in the specified folder. The "prerelease identifier" to use as a prefix for the "prerelease" part of a semver. Like the `rc` in `1.2.0-rc.8`. + + #### `progress` * Default: `true` unless running in a known CI system @@ -995,6 +1168,8 @@ operations, if `process.stderr` is a TTY. Set to `false` to suppress the progress bar. + + #### `provenance` * Default: false @@ -1003,6 +1178,17 @@ Set to `false` to suppress the progress bar. When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from. +This config can not be used with: `provenance-file` + +#### `provenance-file` + +* Default: null +* Type: Path + +When publishing, the provenance bundle at the given path will be used. + +This config can not be used with: `provenance` + #### `proxy` * Default: null @@ -1012,6 +1198,8 @@ A proxy to use for outgoing http requests. If the `HTTP_PROXY` or `http_proxy` environment variables are set, proxy settings will be honored by the underlying `request` library. + + #### `read-only` * Default: false @@ -1020,6 +1208,8 @@ by the underlying `request` library. This is used to mark a token as unable to publish when configuring limited access tokens with the `npm token create` command. + + #### `rebuild-bundle` * Default: true @@ -1027,6 +1217,8 @@ access tokens with the `npm token create` command. Rebuild bundled dependencies after installation. + + #### `registry` * Default: "https://registry.npmjs.org/" @@ -1034,6 +1226,8 @@ Rebuild bundled dependencies after installation. The base URL of the npm registry. + + #### `replace-registry-host` * Default: "npmjs" @@ -1049,6 +1243,8 @@ registry host with the configured host every time. You may also specify a bare hostname (e.g., "registry.npmjs.org"). + + #### `save` * Default: `true` unless when using `npm update` where it defaults to `false` @@ -1061,6 +1257,8 @@ When used with the `npm rm` command, removes the dependency from Will also prevent writing to `package-lock.json` if set to `false`. + + #### `save-bundle` * Default: false @@ -1072,6 +1270,8 @@ If a package would be saved at install time by the use of `--save`, Ignored if `--save-peer` is set, since peerDependencies cannot be bundled. + + #### `save-dev` * Default: false @@ -1079,6 +1279,8 @@ Ignored if `--save-peer` is set, since peerDependencies cannot be bundled. Save installed packages to a package.json file as `devDependencies`. + + #### `save-exact` * Default: false @@ -1087,6 +1289,8 @@ Save installed packages to a package.json file as `devDependencies`. Dependencies saved to package.json will be configured with an exact version rather than using npm's default semver range operator. + + #### `save-optional` * Default: false @@ -1094,6 +1298,8 @@ rather than using npm's default semver range operator. Save installed packages to a package.json file as `optionalDependencies`. + + #### `save-peer` * Default: false @@ -1101,6 +1307,8 @@ Save installed packages to a package.json file as `optionalDependencies`. Save installed packages to a package.json file as `peerDependencies` + + #### `save-prefix` * Default: "^" @@ -1114,6 +1322,8 @@ to `^1.2.3` which allows minor upgrades for that package, but after `npm config set save-prefix='~'` it would be set to `~1.2.3` which only allows patch upgrades. + + #### `save-prod` * Default: false @@ -1126,6 +1336,8 @@ you want to move it to be a non-optional production dependency. This is the default behavior if `--save` is true, and neither `--save-dev` or `--save-optional` are true. + + #### `scope` * Default: the scope of the current project, if any, or "" @@ -1156,6 +1368,7 @@ npm init --scope=@foo --yes ``` + #### `script-shell` * Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows @@ -1164,6 +1377,8 @@ npm init --scope=@foo --yes The shell to use for scripts run with the `npm exec`, `npm run` and `npm init ` commands. + + #### `searchexclude` * Default: "" @@ -1171,6 +1386,8 @@ init ` commands. Space-separated options that limit the results from search. + + #### `searchlimit` * Default: 20 @@ -1179,6 +1396,8 @@ Space-separated options that limit the results from search. Number of items to limit search results to. Will not apply at all to legacy searches. + + #### `searchopts` * Default: "" @@ -1186,6 +1405,8 @@ searches. Space-separated options that are always passed to search. + + #### `searchstaleness` * Default: 900 @@ -1194,6 +1415,8 @@ Space-separated options that are always passed to search. The age of the cache, in seconds, before another registry request is made if using legacy search endpoint. + + #### `shell` * Default: SHELL environment variable, or "bash" on Posix, or "cmd.exe" on @@ -1202,6 +1425,8 @@ using legacy search endpoint. The shell to run for the `npm explore` command. + + #### `sign-git-commit` * Default: false @@ -1213,6 +1438,8 @@ version using `-S` to add a signature. Note that git requires you to have set up GPG keys in your git configs for this to work properly. + + #### `sign-git-tag` * Default: false @@ -1224,6 +1451,8 @@ If set to true, then the `npm version` command will tag the version using Note that git requires you to have set up GPG keys in your git configs for this to work properly. + + #### `strict-peer-deps` * Default: false @@ -1243,6 +1472,8 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If `--strict-peer-deps` is set, then this warning is treated as a failure. + + #### `strict-ssl` * Default: true @@ -1253,6 +1484,8 @@ via https. See also the `ca` config. + + #### `tag` * Default: "latest" @@ -1267,6 +1500,8 @@ command, if no explicit tag is given. When used by the `npm diff` command, this is the tag used to fetch the tarball that will be compared with the local files by default. + + #### `tag-version-prefix` * Default: "v" @@ -1280,6 +1515,8 @@ Because other tools may rely on the convention that npm version tags look like `v1.0.0`, _only use this property if it is absolutely necessary_. In particular, use care when overriding this setting for public packages. + + #### `timing` * Default: false @@ -1294,6 +1531,8 @@ You can quickly view it with this [json](https://npm.im/json) command line: Timing information will also be reported in the terminal. To suppress this while still writing the timing file, use `--silent`. + + #### `umask` * Default: 0 @@ -1314,6 +1553,8 @@ Thus, the effective default umask value on most POSIX systems is 0o22, meaning that folders and executables are created with a mode of 0o755 and other files are created with a mode of 0o644. + + #### `unicode` * Default: false on windows, true on mac/unix systems with a unicode locale, @@ -1323,6 +1564,8 @@ other files are created with a mode of 0o644. When set to true, npm uses unicode characters in the tree output. When false, it uses ascii characters instead of unicode glyphs. + + #### `update-notifier` * Default: true @@ -1331,6 +1574,8 @@ false, it uses ascii characters instead of unicode glyphs. Set to false to suppress the update notification when using an older version of npm than the latest. + + #### `usage` * Default: false @@ -1338,6 +1583,8 @@ of npm than the latest. Show short usage output about the command specified. + + #### `user-agent` * Default: "npm/{npm-version} node/{node-version} {platform} {arch} @@ -1356,6 +1603,8 @@ their actual counterparts: * `{ci}` - The value of the `ci-name` config, if set, prefixed with `ci/`, or an empty string if `ci-name` is empty. + + #### `userconfig` * Default: "~/.npmrc" @@ -1367,6 +1616,8 @@ This may be overridden by the `npm_config_userconfig` environment variable or the `--userconfig` command line option, but may _not_ be overridden by settings in the `globalconfig` file. + + #### `version` * Default: false @@ -1376,6 +1627,8 @@ If true, output the npm version and exit successfully. Only relevant when specified explicitly on the command line. + + #### `versions` * Default: false @@ -1387,6 +1640,8 @@ exists, and exit successfully. Only relevant when specified explicitly on the command line. + + #### `viewer` * Default: "man" on Posix, "browser" on Windows @@ -1396,6 +1651,8 @@ The program to use to view help content. Set to `"browser"` to view html help content in the default web browser. + + #### `which` * Default: null @@ -1403,6 +1660,8 @@ Set to `"browser"` to view html help content in the default web browser. If there are multiple funding sources, which 1-indexed source URL to open. + + #### `workspace` * Default: @@ -1451,6 +1710,8 @@ This value is not exported to the environment for child processes. If set to true, the npm cli will run an update after operations that may possibly change the workspaces installed to the `node_modules` folder. + + #### `yes` * Default: null @@ -1459,6 +1720,8 @@ possibly change the workspaces installed to the `node_modules` folder. Automatically answer "yes" to any prompts that npm might print on the command line. + + #### `also` * Default: null @@ -1467,6 +1730,8 @@ command line. When set to `dev` or `development`, this is an alias for `--include=dev`. + + #### `cache-max` * Default: Infinity @@ -1475,6 +1740,8 @@ When set to `dev` or `development`, this is an alias for `--include=dev`. `--cache-max=0` is an alias for `--prefer-online` + + #### `cache-min` * Default: 0 @@ -1483,6 +1750,8 @@ When set to `dev` or `development`, this is an alias for `--include=dev`. `--cache-min=9999 (or bigger)` is an alias for `--prefer-offline`. + + #### `cert` * Default: null @@ -1504,6 +1773,8 @@ It is _not_ the path to a certificate file, though you can set a registry-scoped "certfile" path like "//other-registry.tld/:certfile=/path/to/cert.pem". + + #### `ci-name` * Default: The name of the current CI system, or `null` when not on a known CI @@ -1516,6 +1787,8 @@ The name of a continuous integration system. If not set explicitly, npm will detect the current CI environment using the [`ci-info`](http://npm.im/ci-info) module. + + #### `dev` * Default: false @@ -1524,6 +1797,8 @@ detect the current CI environment using the Alias for `--include=dev`. + + #### `global-style` * Default: false @@ -1534,6 +1809,8 @@ Alias for `--include=dev`. Only install direct dependencies in the top level `node_modules`, but hoist on deeper dependencies. Sets `--install-strategy=shallow`. + + #### `init.author.email` * Default: "" @@ -1542,6 +1819,8 @@ on deeper dependencies. Sets `--install-strategy=shallow`. Alias for `--init-author-email` + + #### `init.author.name` * Default: "" @@ -1550,6 +1829,8 @@ Alias for `--init-author-email` Alias for `--init-author-name` + + #### `init.author.url` * Default: "" @@ -1558,6 +1839,8 @@ Alias for `--init-author-name` Alias for `--init-author-url` + + #### `init.license` * Default: "ISC" @@ -1566,6 +1849,8 @@ Alias for `--init-author-url` Alias for `--init-license` + + #### `init.module` * Default: "~/.npm-init.js" @@ -1574,6 +1859,8 @@ Alias for `--init-license` Alias for `--init-module` + + #### `init.version` * Default: "1.0.0" @@ -1582,6 +1869,8 @@ Alias for `--init-module` Alias for `--init-version` + + #### `key` * Default: null @@ -1601,6 +1890,8 @@ key="-----BEGIN PRIVATE KEY-----\nXXXX\nXXXX\n-----END PRIVATE KEY-----" It is _not_ the path to a key file, though you can set a registry-scoped "keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem". + + #### `legacy-bundling` * Default: false @@ -1613,6 +1904,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets `--install-strategy=nested`. + + #### `only` * Default: null @@ -1621,6 +1914,8 @@ de-duplicating. Sets `--install-strategy=nested`. When set to `prod` or `production`, this is an alias for `--omit=dev`. + + #### `optional` * Default: null @@ -1632,6 +1927,8 @@ Default value does install optional deps unless otherwise omitted. Alias for --include=optional or --omit=optional + + #### `production` * Default: null @@ -1640,6 +1937,8 @@ Alias for --include=optional or --omit=optional Alias for `--omit=dev` + + #### `shrinkwrap` * Default: true @@ -1648,6 +1947,8 @@ Alias for `--omit=dev` Alias for --package-lock + + #### `tmp` * Default: The value returned by the Node.js `os.tmpdir()` method @@ -1660,6 +1961,8 @@ Alias for --package-lock Historically, the location where temporary files were stored. No longer relevant. + + ### See also * [npm config](/commands/npm-config) diff --git a/deps/npm/docs/output/commands/npm-ci.html b/deps/npm/docs/output/commands/npm-ci.html index 12dc2c58a75632..9fed910b2eba08 100644 --- a/deps/npm/docs/output/commands/npm-ci.html +++ b/deps/npm/docs/output/commands/npm-ci.html @@ -142,7 +142,7 @@

npm-ci

Table of contents

- +

Synopsis

@@ -257,14 +257,6 @@

strict-peer-deps

When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If --strict-peer-deps is set, then this warning is treated as a failure.

-

package-lock

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

If set to false, then ignore package-lock.json files when installing. This -will also prevent writing package-lock.json if save is true.

-

This configuration does not affect npm ci.

foreground-scripts

  • Default: false
  • diff --git a/deps/npm/docs/output/commands/npm-dedupe.html b/deps/npm/docs/output/commands/npm-dedupe.html index d77f4a59c7de98..46db8279fb0412 100644 --- a/deps/npm/docs/output/commands/npm-dedupe.html +++ b/deps/npm/docs/output/commands/npm-dedupe.html @@ -249,7 +249,6 @@

    package-lock

If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

-

This configuration does not affect npm ci.

omit

  • Default: 'dev' if the NODE_ENV environment variable is set to diff --git a/deps/npm/docs/output/commands/npm-find-dupes.html b/deps/npm/docs/output/commands/npm-find-dupes.html index 82d5eba473f1df..725f197e8503d4 100644 --- a/deps/npm/docs/output/commands/npm-find-dupes.html +++ b/deps/npm/docs/output/commands/npm-find-dupes.html @@ -206,7 +206,6 @@

    package-lock

If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

-

This configuration does not affect npm ci.

omit

  • Default: 'dev' if the NODE_ENV environment variable is set to diff --git a/deps/npm/docs/output/commands/npm-install-ci-test.html b/deps/npm/docs/output/commands/npm-install-ci-test.html index 1afa069a3dc259..f87de26e312b18 100644 --- a/deps/npm/docs/output/commands/npm-install-ci-test.html +++ b/deps/npm/docs/output/commands/npm-install-ci-test.html @@ -142,7 +142,7 @@

    npm-install-ci-test

    Table of contents

    - +

    Synopsis

    @@ -214,14 +214,6 @@

    strict-peer-deps

    When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If --strict-peer-deps is set, then this warning is treated as a failure.

    -

    package-lock

    -
      -
    • Default: true
    • -
    • Type: Boolean
    • -
    -

    If set to false, then ignore package-lock.json files when installing. This -will also prevent writing package-lock.json if save is true.

    -

    This configuration does not affect npm ci.

    foreground-scripts

    • Default: false
    • diff --git a/deps/npm/docs/output/commands/npm-install-test.html b/deps/npm/docs/output/commands/npm-install-test.html index 27ab7c3ae5b23a..5c0fb7cf08484b 100644 --- a/deps/npm/docs/output/commands/npm-install-test.html +++ b/deps/npm/docs/output/commands/npm-install-test.html @@ -142,7 +142,7 @@

      npm-install-test

      Table of contents

      - +

      Synopsis

      @@ -245,6 +245,13 @@

      strict-peer-deps

      When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If --strict-peer-deps is set, then this warning is treated as a failure.

      +

      prefer-dedupe

      +
        +
      • Default: false
      • +
      • Type: Boolean
      • +
      +

      Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency.

      package-lock

      • Default: true
      • @@ -252,7 +259,6 @@

        package-lock

      If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

      -

      This configuration does not affect npm ci.

      foreground-scripts

      • Default: false
      • diff --git a/deps/npm/docs/output/commands/npm-install.html b/deps/npm/docs/output/commands/npm-install.html index 0c72b0c0917200..ba8d534d1834f5 100644 --- a/deps/npm/docs/output/commands/npm-install.html +++ b/deps/npm/docs/output/commands/npm-install.html @@ -142,7 +142,7 @@

        npm-install

        Table of contents

        - +

        Synopsis

        @@ -571,6 +571,13 @@

        strict-peer-deps

        When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If --strict-peer-deps is set, then this warning is treated as a failure.

        +

        prefer-dedupe

        +
          +
        • Default: false
        • +
        • Type: Boolean
        • +
        +

        Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency.

        package-lock

        • Default: true
        • @@ -578,7 +585,6 @@

          package-lock

        If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

        -

        This configuration does not affect npm ci.

        foreground-scripts

        • Default: false
        • diff --git a/deps/npm/docs/output/commands/npm-link.html b/deps/npm/docs/output/commands/npm-link.html index 9686106d8b8d03..ac36e1beb56884 100644 --- a/deps/npm/docs/output/commands/npm-link.html +++ b/deps/npm/docs/output/commands/npm-link.html @@ -301,7 +301,6 @@

          package-lock

        If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

        -

        This configuration does not affect npm ci.

        omit

        When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from.

        +

        This config can not be used with: provenance-file

        +

        provenance-file

        +
          +
        • Default: null
        • +
        • Type: Path
        • +
        +

        When publishing, the provenance bundle at the given path will be used.

        +

        This config can not be used with: provenance

        See Also

        • package spec
        • diff --git a/deps/npm/docs/output/commands/npm-uninstall.html b/deps/npm/docs/output/commands/npm-uninstall.html index 98a9f08418a14e..4a4e6c274a09e7 100644 --- a/deps/npm/docs/output/commands/npm-uninstall.html +++ b/deps/npm/docs/output/commands/npm-uninstall.html @@ -142,7 +142,7 @@

          npm-uninstall

          Table of contents

          - +

          Synopsis

          @@ -187,6 +187,20 @@

          save

          When used with the npm rm command, removes the dependency from package.json.

          Will also prevent writing to package-lock.json if set to false.

          +

          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 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
          • +

          workspace

          • Default:
          • diff --git a/deps/npm/docs/output/commands/npm-update.html b/deps/npm/docs/output/commands/npm-update.html index 32c3da827ca805..373a2ae22f9235 100644 --- a/deps/npm/docs/output/commands/npm-update.html +++ b/deps/npm/docs/output/commands/npm-update.html @@ -342,7 +342,6 @@

            package-lock

          If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

          -

          This configuration does not affect npm ci.

          foreground-scripts

          If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true.

          -

          This configuration does not affect npm ci.

          package-lock-only

          • Default: false
          • @@ -941,6 +940,13 @@

            parseable

          Output parseable results from commands that write to standard output. For npm search, this will be tab-separated table format.

          +

          prefer-dedupe

          +
            +
          • Default: false
          • +
          • Type: Boolean
          • +
          +

          Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency.

          prefer-offline

          • Default: false
          • @@ -987,6 +993,14 @@

            provenance

          When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from.

          +

          This config can not be used with: provenance-file

          +

          provenance-file

          +
            +
          • Default: null
          • +
          • Type: Path
          • +
          +

          When publishing, the provenance bundle at the given path will be used.

          +

          This config can not be used with: provenance

          proxy

          • Default: null
          • diff --git a/deps/npm/lib/base-command.js b/deps/npm/lib/base-command.js index 0adff8e5d95ea8..598964ce524e39 100644 --- a/deps/npm/lib/base-command.js +++ b/deps/npm/lib/base-command.js @@ -2,17 +2,81 @@ const { relative } = require('path') -const ConfigDefinitions = require('./utils/config/definitions.js') +const definitions = require('./utils/config/definitions.js') const getWorkspaces = require('./workspaces/get-workspaces.js') - -const cmdAliases = require('./utils/cmd-list').aliases +const { aliases: cmdAliases } = require('./utils/cmd-list') class BaseCommand { static workspaces = false static ignoreImplicitWorkspace = true + // these are all overridden by individual commands + static name = null + static description = null + static params = null + + // this is a static so that we can read from it without instantiating a command + // which would require loading the config + static get describeUsage () { + const seenExclusive = new Set() + const wrapWidth = 80 + const { description, usage = [''], name, params } = this + + const fullUsage = [ + `${description}`, + '', + 'Usage:', + ...usage.map(u => `npm ${name} ${u}`.trim()), + ] + + if (params) { + let results = '' + let line = '' + for (const param of params) { + /* istanbul ignore next */ + if (seenExclusive.has(param)) { + continue + } + const { exclusive } = definitions[param] + let paramUsage = `${definitions[param].usage}` + if (exclusive) { + const exclusiveParams = [paramUsage] + seenExclusive.add(param) + for (const e of exclusive) { + seenExclusive.add(e) + exclusiveParams.push(definitions[e].usage) + } + paramUsage = `${exclusiveParams.join('|')}` + } + paramUsage = `[${paramUsage}]` + if (line.length + paramUsage.length > wrapWidth) { + results = [results, line].filter(Boolean).join('\n') + line = '' + } + line = [line, paramUsage].filter(Boolean).join(' ') + } + fullUsage.push('') + fullUsage.push('Options:') + fullUsage.push([results, line].filter(Boolean).join('\n')) + } + + const aliases = Object.entries(cmdAliases).reduce((p, [k, v]) => { + return p.concat(v === name ? k : []) + }, []) + + if (aliases.length) { + const plural = aliases.length === 1 ? '' : 'es' + fullUsage.push('') + fullUsage.push(`alias${plural}: ${aliases.join(', ')}`) + } + + fullUsage.push('') + fullUsage.push(`Run "npm help ${name}" for more info`) + + return fullUsage.join('\n') + } + constructor (npm) { - this.wrapWidth = 80 this.npm = npm const { config } = this.npm @@ -39,59 +103,7 @@ class BaseCommand { } get usage () { - const usage = [ - `${this.description}`, - '', - 'Usage:', - ] - - if (!this.constructor.usage) { - usage.push(`npm ${this.name}`) - } else { - usage.push(...this.constructor.usage.map(u => `npm ${this.name} ${u}`)) - } - - if (this.params) { - usage.push('') - usage.push('Options:') - usage.push(this.wrappedParams) - } - - const aliases = Object.keys(cmdAliases).reduce((p, c) => { - if (cmdAliases[c] === this.name) { - p.push(c) - } - return p - }, []) - - if (aliases.length === 1) { - usage.push('') - usage.push(`alias: ${aliases.join(', ')}`) - } else if (aliases.length > 1) { - usage.push('') - usage.push(`aliases: ${aliases.join(', ')}`) - } - - usage.push('') - usage.push(`Run "npm help ${this.name}" for more info`) - - return usage.join('\n') - } - - get wrappedParams () { - let results = '' - let line = '' - - for (const param of this.params) { - const usage = `[${ConfigDefinitions[param].usage}]` - if (line.length && line.length + usage.length > this.wrapWidth) { - results = [results, line].filter(Boolean).join('\n') - line = '' - } - line = [line, usage].filter(Boolean).join(' ') - } - results = [results, line].filter(Boolean).join('\n') - return results + return this.constructor.describeUsage } usageError (prefix = '') { diff --git a/deps/npm/lib/cli-entry.js b/deps/npm/lib/cli-entry.js new file mode 100644 index 00000000000000..aad06e06903856 --- /dev/null +++ b/deps/npm/lib/cli-entry.js @@ -0,0 +1,74 @@ +/* eslint-disable max-len */ + +// Separated out for easier unit testing +module.exports = async (process, validateEngines) => { + // set it here so that regardless of what happens later, we don't + // leak any private CLI configs to other programs + process.title = 'npm' + + // if npm is called as "npmg" or "npm_g", then run in global mode. + if (process.argv[1][process.argv[1].length - 1] === 'g') { + process.argv.splice(1, 1, 'npm', '-g') + } + + const satisfies = require('semver/functions/satisfies') + const exitHandler = require('./utils/exit-handler.js') + const Npm = require('./npm.js') + const npm = new Npm() + exitHandler.setNpm(npm) + + // only log node and npm paths in argv initially since argv can contain sensitive info. a cleaned version will be logged later + const log = require('./utils/log-shim.js') + log.verbose('cli', process.argv.slice(0, 2).join(' ')) + log.info('using', 'npm@%s', npm.version) + log.info('using', 'node@%s', process.version) + + // At this point we've required a few files and can be pretty sure we dont contain invalid syntax for this version of node. It's possible a lazy require would, but that's unlikely enough that it's not worth catching anymore and we attach the more important exit handlers. + validateEngines.off() + process.on('uncaughtException', exitHandler) + process.on('unhandledRejection', exitHandler) + + // It is now safe to log a warning if they are using a version of node that is not going to fail on syntax errors but is still unsupported and untested and might not work reliably. This is safe to use the logger now which we want since this will show up in the error log too. + if (!satisfies(validateEngines.node, validateEngines.engines)) { + log.warn('cli', validateEngines.unsupportedMessage) + } + + let cmd + // Now actually fire up npm and run the command. + // This is how to use npm programmatically: + try { + await npm.load() + + // npm -v + if (npm.config.get('version', 'cli')) { + npm.output(npm.version) + return exitHandler() + } + + // npm --versions + if (npm.config.get('versions', 'cli')) { + npm.argv = ['version'] + npm.config.set('usage', false, 'cli') + } + + cmd = npm.argv.shift() + if (!cmd) { + npm.output(npm.usage) + process.exitCode = 1 + return exitHandler() + } + + await npm.exec(cmd) + return exitHandler() + } catch (err) { + if (err.code === 'EUNKNOWNCOMMAND') { + const didYouMean = require('./utils/did-you-mean.js') + const suggestions = await didYouMean(npm.localPrefix, cmd) + npm.output(`Unknown command: "${cmd}"${suggestions}\n`) + npm.output('To see a list of supported npm commands, run:\n npm help') + process.exitCode = 1 + return exitHandler() + } + return exitHandler(err) + } +} diff --git a/deps/npm/lib/cli.js b/deps/npm/lib/cli.js index a393626f08291f..c85ecb65a7005a 100644 --- a/deps/npm/lib/cli.js +++ b/deps/npm/lib/cli.js @@ -1,102 +1,4 @@ -/* eslint-disable max-len */ -// Code in this file should work in all conceivably runnable versions of node. -// A best effort is made to catch syntax errors to give users a good error message if they are using a node version that doesn't allow syntax we are using in other files such as private properties, etc +const validateEngines = require('./es6/validate-engines.js') +const cliEntry = require('path').resolve(__dirname, 'cli-entry.js') -// Separated out for easier unit testing -module.exports = async process => { - // set it here so that regardless of what happens later, we don't - // leak any private CLI configs to other programs - process.title = 'npm' - - // if npm is called as "npmg" or "npm_g", then run in global mode. - if (process.argv[1][process.argv[1].length - 1] === 'g') { - process.argv.splice(1, 1, 'npm', '-g') - } - - const nodeVersion = process.version.replace(/-.*$/, '') - const pkg = require('../package.json') - const engines = pkg.engines.node - const npmVersion = `v${pkg.version}` - - const unsupportedMessage = `npm ${npmVersion} does not support Node.js ${nodeVersion}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` - - const brokenMessage = `ERROR: npm ${npmVersion} is known not to run on Node.js ${nodeVersion}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` - - // Coverage ignored because this is only hit in very unsupported node versions and it's a best effort attempt to show something nice in those cases - /* istanbul ignore next */ - const syntaxErrorHandler = (err) => { - if (err instanceof SyntaxError) { - // eslint-disable-next-line no-console - console.error(`${brokenMessage}\n\nERROR:`) - // eslint-disable-next-line no-console - console.error(err) - return process.exit(1) - } - throw err - } - - process.on('uncaughtException', syntaxErrorHandler) - process.on('unhandledRejection', syntaxErrorHandler) - - const satisfies = require('semver/functions/satisfies') - const exitHandler = require('./utils/exit-handler.js') - const Npm = require('./npm.js') - const npm = new Npm() - exitHandler.setNpm(npm) - - // only log node and npm paths in argv initially since argv can contain sensitive info. a cleaned version will be logged later - const log = require('./utils/log-shim.js') - log.verbose('cli', process.argv.slice(0, 2).join(' ')) - log.info('using', 'npm@%s', npm.version) - log.info('using', 'node@%s', process.version) - - // At this point we've required a few files and can be pretty sure we dont contain invalid syntax for this version of node. It's possible a lazy require would, but that's unlikely enough that it's not worth catching anymore and we attach the more important exit handlers. - process.off('uncaughtException', syntaxErrorHandler) - process.off('unhandledRejection', syntaxErrorHandler) - process.on('uncaughtException', exitHandler) - process.on('unhandledRejection', exitHandler) - - // It is now safe to log a warning if they are using a version of node that is not going to fail on syntax errors but is still unsupported and untested and might not work reliably. This is safe to use the logger now which we want since this will show up in the error log too. - if (!satisfies(nodeVersion, engines)) { - log.warn('cli', unsupportedMessage) - } - - let cmd - // Now actually fire up npm and run the command. - // This is how to use npm programmatically: - try { - await npm.load() - - // npm -v - if (npm.config.get('version', 'cli')) { - npm.output(npm.version) - return exitHandler() - } - - // npm --versions - if (npm.config.get('versions', 'cli')) { - npm.argv = ['version'] - npm.config.set('usage', false, 'cli') - } - - cmd = npm.argv.shift() - if (!cmd) { - npm.output(await npm.usage) - process.exitCode = 1 - return exitHandler() - } - - await npm.exec(cmd) - return exitHandler() - } catch (err) { - if (err.code === 'EUNKNOWNCOMMAND') { - const didYouMean = require('./utils/did-you-mean.js') - const suggestions = await didYouMean(npm, npm.localPrefix, cmd) - npm.output(`Unknown command: "${cmd}"${suggestions}\n`) - npm.output('To see a list of supported npm commands, run:\n npm help') - process.exitCode = 1 - return exitHandler() - } - return exitHandler(err) - } -} +module.exports = (process) => validateEngines(process, () => require(cliEntry)) diff --git a/deps/npm/lib/commands/access.js b/deps/npm/lib/commands/access.js index 318151fc81e2c0..99c1264a84eda3 100644 --- a/deps/npm/lib/commands/access.js +++ b/deps/npm/lib/commands/access.js @@ -1,8 +1,6 @@ -const path = require('path') - const libnpmaccess = require('libnpmaccess') const npa = require('npm-package-arg') -const readPackageJson = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const localeCompare = require('@isaacs/string-locale-compare')('en') const otplease = require('../utils/otplease.js') @@ -47,7 +45,7 @@ class Access extends BaseCommand { 'revoke []', ] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { return commands @@ -178,8 +176,8 @@ class Access extends BaseCommand { async #getPackage (name, requireScope) { if (!name) { try { - const pkg = await readPackageJson(path.resolve(this.npm.prefix, 'package.json')) - name = pkg.name + const { content } = await pkgJson.normalize(this.npm.prefix) + name = content.name } catch (err) { if (err.code === 'ENOENT') { throw Object.assign(new Error('no package name given and no package.json found'), { diff --git a/deps/npm/lib/commands/audit.js b/deps/npm/lib/commands/audit.js index 7b75ecbf2e0243..500620f2cd01bd 100644 --- a/deps/npm/lib/commands/audit.js +++ b/deps/npm/lib/commands/audit.js @@ -1,9 +1,10 @@ -const auditReport = require('npm-audit-report') +const npmAuditReport = require('npm-audit-report') const fetch = require('npm-registry-fetch') const localeCompare = require('@isaacs/string-locale-compare')('en') const npa = require('npm-package-arg') const pacote = require('pacote') const pMap = require('p-map') +const { sigstore } = require('sigstore') const ArboristWorkspaceCmd = require('../arborist-cmd.js') const auditError = require('../utils/audit-error.js') @@ -37,7 +38,12 @@ class VerifySignatures { throw new Error('found no installed dependencies to audit') } - await Promise.all([...registries].map(registry => this.setKeys({ registry }))) + const tuf = await sigstore.tuf.client({ + tufCachePath: this.opts.tufCache, + retry: this.opts.retry, + timeout: this.opts.timeout, + }) + await Promise.all([...registries].map(registry => this.setKeys({ registry, tuf }))) const progress = log.newItem('verifying registry signatures', edges.size) const mapper = async (edge) => { @@ -187,20 +193,42 @@ class VerifySignatures { return { edges, registries } } - async setKeys ({ registry }) { - const keys = await fetch.json('/-/npm/v1/keys', { - ...this.npm.flatOptions, - registry, - }).then(({ keys: ks }) => ks.map((key) => ({ - ...key, - pemkey: `-----BEGIN PUBLIC KEY-----\n${key.key}\n-----END PUBLIC KEY-----`, - }))).catch(err => { - if (err.code === 'E404' || err.code === 'E400') { - return null - } else { - throw err - } - }) + async setKeys ({ registry, tuf }) { + const { host, pathname } = new URL(registry) + // Strip any trailing slashes from pathname + const regKey = `${host}${pathname.replace(/\/$/, '')}/keys.json` + let keys = await tuf.getTarget(regKey) + .then((target) => JSON.parse(target)) + .then(({ keys: ks }) => ks.map((key) => ({ + ...key, + keyid: key.keyId, + pemkey: `-----BEGIN PUBLIC KEY-----\n${key.publicKey.rawBytes}\n-----END PUBLIC KEY-----`, + expires: key.publicKey.validFor.end || null, + }))).catch(err => { + if (err.code === 'TUF_FIND_TARGET_ERROR') { + return null + } else { + throw err + } + }) + + // If keys not found in Sigstore TUF repo, fallback to registry keys API + if (!keys) { + keys = await fetch.json('/-/npm/v1/keys', { + ...this.npm.flatOptions, + registry, + }).then(({ keys: ks }) => ks.map((key) => ({ + ...key, + pemkey: `-----BEGIN PUBLIC KEY-----\n${key.key}\n-----END PUBLIC KEY-----`, + }))).catch(err => { + if (err.code === 'E404' || err.code === 'E400') { + return null + } else { + throw err + } + }) + } + if (keys) { this.keys.set(registry, keys) } @@ -384,7 +412,7 @@ class Audit extends ArboristWorkspaceCmd { static usage = ['[fix|signatures]'] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { @@ -429,7 +457,10 @@ class Audit extends ArboristWorkspaceCmd { } else { // will throw if there's an error, because this is an audit command auditError(this.npm, arb.auditReport) - const result = auditReport(arb.auditReport, opts) + const result = npmAuditReport(arb.auditReport, { + ...opts, + chalk: this.npm.chalk, + }) process.exitCode = process.exitCode || result.exitCode this.npm.output(result.report) } diff --git a/deps/npm/lib/commands/cache.js b/deps/npm/lib/commands/cache.js index 66b432dfc13a66..50bb35e3544dfe 100644 --- a/deps/npm/lib/commands/cache.js +++ b/deps/npm/lib/commands/cache.js @@ -73,7 +73,7 @@ class Cache extends BaseCommand { 'verify', ] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { return ['add', 'clean', 'verify', 'ls'] diff --git a/deps/npm/lib/commands/ci.js b/deps/npm/lib/commands/ci.js index 97c292e8c53896..e662379278e031 100644 --- a/deps/npm/lib/commands/ci.js +++ b/deps/npm/lib/commands/ci.js @@ -17,7 +17,6 @@ class CI extends ArboristWorkspaceCmd { 'global-style', 'omit', 'strict-peer-deps', - 'package-lock', 'foreground-scripts', 'ignore-scripts', 'audit', diff --git a/deps/npm/lib/commands/completion.js b/deps/npm/lib/commands/completion.js index efbad9d61001b5..38205ad8fc49ee 100644 --- a/deps/npm/lib/commands/completion.js +++ b/deps/npm/lib/commands/completion.js @@ -33,8 +33,9 @@ const fs = require('fs/promises') const nopt = require('nopt') const { resolve } = require('path') +const Npm = require('../npm.js') const { definitions, shorthands } = require('../utils/config/index.js') -const { commands, aliases } = require('../utils/cmd-list.js') +const { commands, aliases, deref } = require('../utils/cmd-list.js') const configNames = Object.keys(definitions) const shorthandNames = Object.keys(shorthands) const allConfs = configNames.concat(shorthandNames) @@ -48,7 +49,7 @@ class Completion extends BaseCommand { static name = 'completion' // completion for the completion command - async completion (opts) { + static async completion (opts) { if (opts.w > 2) { return } @@ -156,10 +157,14 @@ class Completion extends BaseCommand { // at this point, if words[1] is some kind of npm command, // then complete on it. // otherwise, do nothing - const impl = await this.npm.cmd(cmd) - if (impl.completion) { - const comps = await impl.completion(opts) - return this.wrap(opts, comps) + try { + const { completion } = Npm.cmd(cmd) + if (completion) { + const comps = await completion(opts, this.npm) + return this.wrap(opts, comps) + } + } catch { + // it wasnt a valid command, so do nothing } } @@ -267,7 +272,7 @@ const cmdCompl = (opts, npm) => { return matches } - const derefs = new Set([...matches.map(c => npm.deref(c))]) + const derefs = new Set([...matches.map(c => deref(c))]) if (derefs.size === 1) { return [...derefs] } diff --git a/deps/npm/lib/commands/config.js b/deps/npm/lib/commands/config.js index dfd44015cd0432..b49cdd648f9d02 100644 --- a/deps/npm/lib/commands/config.js +++ b/deps/npm/lib/commands/config.js @@ -7,7 +7,7 @@ const { spawn } = require('child_process') const { EOL } = require('os') const ini = require('ini') const localeCompare = require('@isaacs/string-locale-compare')('en') -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const log = require('../utils/log-shim.js') // These are the configs that we can nerf-dart. Not all of them currently even @@ -74,7 +74,7 @@ class Config extends BaseCommand { static skipConfigValidation = true - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv[1] !== 'config') { argv.unshift('config') @@ -346,15 +346,15 @@ ${defData} } if (!this.npm.global) { - const pkgPath = resolve(this.npm.prefix, 'package.json') - const pkg = await rpj(pkgPath).catch(() => ({})) + const { content } = await pkgJson.normalize(this.npm.prefix).catch(() => ({ content: {} })) - if (pkg.publishConfig) { + if (content.publishConfig) { + const pkgPath = resolve(this.npm.prefix, 'package.json') msg.push(`; "publishConfig" from ${pkgPath}`) msg.push('; This set of config values will be used at publish-time.', '') - const pkgKeys = Object.keys(pkg.publishConfig).sort(localeCompare) + const pkgKeys = Object.keys(content.publishConfig).sort(localeCompare) for (const k of pkgKeys) { - const v = publicVar(k) ? JSON.stringify(pkg.publishConfig[k]) : '(protected)' + const v = publicVar(k) ? JSON.stringify(content.publishConfig[k]) : '(protected)' msg.push(`${k} = ${v}`) } msg.push('') diff --git a/deps/npm/lib/commands/deprecate.js b/deps/npm/lib/commands/deprecate.js index 844d5f60a02abe..ada2bac40f2fd6 100644 --- a/deps/npm/lib/commands/deprecate.js +++ b/deps/npm/lib/commands/deprecate.js @@ -17,13 +17,13 @@ class Deprecate extends BaseCommand { static ignoreImplicitWorkspace = false - async completion (opts) { + static async completion (opts, npm) { if (opts.conf.argv.remain.length > 1) { return [] } - const username = await getIdentity(this.npm, this.npm.flatOptions) - const packages = await libaccess.getPackages(username, this.npm.flatOptions) + const username = await getIdentity(npm, npm.flatOptions) + const packages = await libaccess.getPackages(username, npm.flatOptions) return Object.keys(packages) .filter((name) => packages[name] === 'write' && diff --git a/deps/npm/lib/commands/diff.js b/deps/npm/lib/commands/diff.js index 3924166af0a886..64d81d525d79d2 100644 --- a/deps/npm/lib/commands/diff.js +++ b/deps/npm/lib/commands/diff.js @@ -5,7 +5,7 @@ const npa = require('npm-package-arg') const pacote = require('pacote') const pickManifest = require('npm-pick-manifest') const log = require('../utils/log-shim') -const readPackage = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') class Diff extends BaseCommand { @@ -81,7 +81,7 @@ class Diff extends BaseCommand { async packageName (path) { let name try { - const pkg = await readPackage(resolve(this.prefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.prefix) name = pkg.name } catch (e) { log.verbose('diff', 'could not read project dir package.json') @@ -115,7 +115,7 @@ class Diff extends BaseCommand { let noPackageJson let pkgName try { - const pkg = await readPackage(resolve(this.prefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.prefix) pkgName = pkg.name } catch (e) { log.verbose('diff', 'could not read project dir package.json') @@ -228,7 +228,7 @@ class Diff extends BaseCommand { if (semverA && semverB) { let pkgName try { - const pkg = await readPackage(resolve(this.prefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.prefix) pkgName = pkg.name } catch (e) { log.verbose('diff', 'could not read project dir package.json') diff --git a/deps/npm/lib/commands/dist-tag.js b/deps/npm/lib/commands/dist-tag.js index bc61a4691e55a0..15f9622d14906c 100644 --- a/deps/npm/lib/commands/dist-tag.js +++ b/deps/npm/lib/commands/dist-tag.js @@ -1,10 +1,9 @@ const npa = require('npm-package-arg') -const path = require('path') const regFetch = require('npm-registry-fetch') const semver = require('semver') const log = require('../utils/log-shim') const otplease = require('../utils/otplease.js') -const readPackage = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') class DistTag extends BaseCommand { @@ -20,7 +19,7 @@ class DistTag extends BaseCommand { static workspaces = true static ignoreImplicitWorkspace = false - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { return ['add', 'rm', 'ls'] @@ -152,7 +151,7 @@ class DistTag extends BaseCommand { if (this.npm.global) { throw this.usageError() } - const { name } = await readPackage(path.resolve(this.npm.prefix, 'package.json')) + const { content: { name } } = await pkgJson.normalize(this.npm.prefix) if (!name) { throw this.usageError() } diff --git a/deps/npm/lib/commands/edit.js b/deps/npm/lib/commands/edit.js index a671a5d6bad5d6..fbc7840a39876f 100644 --- a/deps/npm/lib/commands/edit.js +++ b/deps/npm/lib/commands/edit.js @@ -38,8 +38,8 @@ class Edit extends BaseCommand { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + return completion(npm, opts) } async exec (args) { diff --git a/deps/npm/lib/commands/exec.js b/deps/npm/lib/commands/exec.js index a5235c7845851b..ed4b07dc39b4d2 100644 --- a/deps/npm/lib/commands/exec.js +++ b/deps/npm/lib/commands/exec.js @@ -54,6 +54,7 @@ class Exec extends BaseCommand { localBin, globalBin, globalDir, + chalk, } = this.npm const output = this.npm.output.bind(this.npm) const scriptShell = this.npm.config.get('script-shell') || undefined @@ -83,6 +84,7 @@ class Exec extends BaseCommand { globalBin, globalPath, output, + chalk, packages, path: localPrefix, runPath, diff --git a/deps/npm/lib/commands/explain.js b/deps/npm/lib/commands/explain.js index a72514fb978055..403274db68dfaf 100644 --- a/deps/npm/lib/commands/explain.js +++ b/deps/npm/lib/commands/explain.js @@ -18,9 +18,9 @@ class Explain extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { + static async completion (opts, npm) { const completion = require('../utils/completion/installed-deep.js') - return completion(this.npm, opts) + return completion(npm, opts) } async exec (args) { diff --git a/deps/npm/lib/commands/explore.js b/deps/npm/lib/commands/explore.js index 0d915cb4c69583..7a03ea4eabd7f6 100644 --- a/deps/npm/lib/commands/explore.js +++ b/deps/npm/lib/commands/explore.js @@ -1,9 +1,9 @@ // npm explore [@] // open a subshell to the package folder. -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const runScript = require('@npmcli/run-script') -const { join, resolve, relative } = require('path') +const { join, relative } = require('path') const log = require('../utils/log-shim.js') const completion = require('../utils/completion/installed-shallow.js') const BaseCommand = require('../base-command.js') @@ -17,8 +17,8 @@ class Explore extends BaseCommand { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + return completion(npm, opts) } async exec (args) { @@ -38,7 +38,7 @@ class Explore extends BaseCommand { // the set of arguments, or the shell config, and let @npmcli/run-script // handle all the escaping and PATH setup stuff. - const pkg = await rpj(resolve(path, 'package.json')).catch(er => { + const { content: pkg } = await pkgJson.normalize(path).catch(er => { log.error('explore', `It doesn't look like ${pkgname} is installed.`) throw er }) diff --git a/deps/npm/lib/commands/fund.js b/deps/npm/lib/commands/fund.js index 1e8981967fc327..2804d36cd56034 100644 --- a/deps/npm/lib/commands/fund.js +++ b/deps/npm/lib/commands/fund.js @@ -36,9 +36,9 @@ class Fund extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { + static async completion (opts, npm) { const completion = require('../utils/completion/installed-deep.js') - return completion(this.npm, opts) + return completion(npm, opts) } async exec (args) { diff --git a/deps/npm/lib/commands/get.js b/deps/npm/lib/commands/get.js index 5e92e85a66382f..4bf5d2caf82645 100644 --- a/deps/npm/lib/commands/get.js +++ b/deps/npm/lib/commands/get.js @@ -1,16 +1,18 @@ +const Npm = require('../npm.js') const BaseCommand = require('../base-command.js') class Get extends BaseCommand { static description = 'Get a value from the npm configuration' static name = 'get' static usage = ['[ ...] (See `npm config`)'] + static params = ['long'] static ignoreImplicitWorkspace = false // TODO /* istanbul ignore next */ - async completion (opts) { - const config = await this.npm.cmd('config') - return config.completion(opts) + static async completion (opts) { + const Config = Npm.cmd('config') + return Config.completion(opts) } async exec (args) { diff --git a/deps/npm/lib/commands/help.js b/deps/npm/lib/commands/help.js index 4b40ef37afa2de..39c580f9a68715 100644 --- a/deps/npm/lib/commands/help.js +++ b/deps/npm/lib/commands/help.js @@ -3,6 +3,7 @@ const path = require('path') const openUrl = require('../utils/open-url.js') const { glob } = require('glob') const localeCompare = require('@isaacs/string-locale-compare')('en') +const { deref } = require('../utils/cmd-list.js') const globify = pattern => pattern.split('\\').join('/') const BaseCommand = require('../base-command.js') @@ -26,11 +27,11 @@ class Help extends BaseCommand { static usage = [' []'] static params = ['viewer'] - async completion (opts) { + static async completion (opts, npm) { if (opts.conf.argv.remain.length > 2) { return [] } - const g = path.resolve(this.npm.npmRoot, 'man/man[0-9]/*.[0-9]') + const g = path.resolve(npm.npmRoot, 'man/man[0-9]/*.[0-9]') let files = await glob(globify(g)) // preserve glob@8 behavior files = files.sort((a, b) => a.localeCompare(b, 'en')) @@ -49,7 +50,7 @@ class Help extends BaseCommand { const manSearch = /^\d+$/.test(args[0]) ? `man${args.shift()}` : 'man*' if (!args.length) { - return this.npm.output(await this.npm.usage) + return this.npm.output(this.npm.usage) } // npm help foo bar baz: search topics @@ -58,7 +59,7 @@ class Help extends BaseCommand { } // `npm help package.json` - const arg = (this.npm.deref(args[0]) || args[0]).replace('.json', '-json') + const arg = (deref(args[0]) || args[0]).replace('.json', '-json') // find either section.n or npm-section.n const f = globify(path.resolve(this.npm.npmRoot, `man/${manSearch}/?(npm-)${arg}.[0-9]*`)) diff --git a/deps/npm/lib/commands/init.js b/deps/npm/lib/commands/init.js index 1e5661a7840f26..539fba885deef3 100644 --- a/deps/npm/lib/commands/init.js +++ b/deps/npm/lib/commands/init.js @@ -3,7 +3,6 @@ const { relative, resolve } = require('path') const { mkdir } = require('fs/promises') const initJson = require('init-package-json') const npa = require('npm-package-arg') -const rpj = require('read-package-json-fast') const libexec = require('libnpmexec') const mapWorkspaces = require('@npmcli/map-workspaces') const PackageJson = require('@npmcli/package-json') @@ -54,7 +53,7 @@ class Init extends BaseCommand { // reads package.json for the top-level folder first, by doing this we // ensure the command throw if no package.json is found before trying // to create a workspace package.json file or its folders - const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json')).catch((err) => { + const { content: pkg } = await PackageJson.normalize(this.npm.localPrefix).catch(err => { if (err.code === 'ENOENT') { log.warn('Missing package.json. Try with `--include-workspace-root`.') } @@ -120,11 +119,11 @@ class Init extends BaseCommand { } const newArgs = [packageName, ...otherArgs] - const { color } = this.npm.flatOptions const { flatOptions, localBin, globalBin, + chalk, } = this.npm const output = this.npm.output.bind(this.npm) const runPath = path @@ -134,10 +133,10 @@ class Init extends BaseCommand { await libexec({ ...flatOptions, args: newArgs, - color, localBin, globalBin, output, + chalk, path, runPath, scriptShell, @@ -217,7 +216,7 @@ class Init extends BaseCommand { // translate workspaces paths into an array containing workspaces names const workspaces = [] for (const path of workspacesPaths) { - const { name } = await rpj(resolve(path, 'package.json')).catch(() => ({})) + const { content: { name } } = await PackageJson.normalize(path).catch(() => ({ content: {} })) if (name) { workspaces.push(name) diff --git a/deps/npm/lib/commands/install.js b/deps/npm/lib/commands/install.js index 99f5b326f7b2bf..2bfd20a72658f7 100644 --- a/deps/npm/lib/commands/install.js +++ b/deps/npm/lib/commands/install.js @@ -25,6 +25,7 @@ class Install extends ArboristWorkspaceCmd { 'global-style', 'omit', 'strict-peer-deps', + 'prefer-dedupe', 'package-lock', 'foreground-scripts', 'ignore-scripts', @@ -37,7 +38,7 @@ class Install extends ArboristWorkspaceCmd { static usage = ['[ ...]'] - async completion (opts) { + static async completion (opts) { const { partialWord } = opts // install can complete to a folder with a package.json, or any package. // if it has a slash, then it's gotta be a folder diff --git a/deps/npm/lib/commands/link.js b/deps/npm/lib/commands/link.js index 61ae5a98088684..a81450a247ed64 100644 --- a/deps/npm/lib/commands/link.js +++ b/deps/npm/lib/commands/link.js @@ -4,7 +4,7 @@ const readdir = util.promisify(fs.readdir) const { resolve } = require('path') const npa = require('npm-package-arg') -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const semver = require('semver') const reifyFinish = require('../utils/reify-finish.js') @@ -35,8 +35,8 @@ class Link extends ArboristWorkspaceCmd { ...super.params, ] - async completion (opts) { - const dir = this.npm.globalDir + static async completion (opts, npm) { + const dir = npm.globalDir const files = await readdir(dir) return files.filter(f => !/^[._-]/.test(f)) } @@ -96,11 +96,12 @@ class Link extends ArboristWorkspaceCmd { const names = [] for (const a of args) { const arg = npa(a) - names.push( - arg.type === 'directory' - ? (await rpj(resolve(arg.fetchSpec, 'package.json'))).name - : arg.name - ) + if (arg.type === 'directory') { + const { content } = await pkgJson.normalize(arg.fetchSpec) + names.push(content.name) + } else { + names.push(arg.name) + } } // npm link should not save=true by default unless you're diff --git a/deps/npm/lib/commands/ls.js b/deps/npm/lib/commands/ls.js index eb9114802d5e0a..92300b1c404a35 100644 --- a/deps/npm/lib/commands/ls.js +++ b/deps/npm/lib/commands/ls.js @@ -40,9 +40,9 @@ class LS extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { + static async completion (opts, npm) { const completion = require('../utils/completion/installed-deep.js') - return completion(this.npm, opts) + return completion(npm, opts) } async exec (args) { diff --git a/deps/npm/lib/commands/org.js b/deps/npm/lib/commands/org.js index 575ff75e2a6cf3..1f32d41ff73068 100644 --- a/deps/npm/lib/commands/org.js +++ b/deps/npm/lib/commands/org.js @@ -14,7 +14,7 @@ class Org extends BaseCommand { static params = ['registry', 'otp', 'json', 'parseable'] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { return ['set', 'rm', 'ls'] diff --git a/deps/npm/lib/commands/owner.js b/deps/npm/lib/commands/owner.js index 3a997db800db7d..5b54dd41f3d607 100644 --- a/deps/npm/lib/commands/owner.js +++ b/deps/npm/lib/commands/owner.js @@ -3,14 +3,13 @@ const npmFetch = require('npm-registry-fetch') const pacote = require('pacote') const log = require('../utils/log-shim') const otplease = require('../utils/otplease.js') -const readPackageJsonFast = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') -const { resolve } = require('path') -const readJson = async (pkg) => { +const readJson = async (path) => { try { - const json = await readPackageJsonFast(pkg) - return json + const { content } = await pkgJson.normalize(path) + return content } catch { return {} } @@ -35,7 +34,7 @@ class Owner extends BaseCommand { static workspaces = true static ignoreImplicitWorkspace = false - async completion (opts) { + static async completion (opts, npm) { const argv = opts.conf.argv.remain if (argv.length > 3) { return [] @@ -51,17 +50,17 @@ class Owner extends BaseCommand { // reaches registry in order to autocomplete rm if (argv[2] === 'rm') { - if (this.npm.global) { + if (npm.global) { return [] } - const { name } = await readJson(resolve(this.npm.prefix, 'package.json')) + const { name } = await readJson(npm.prefix) if (!name) { return [] } const spec = npa(name) const data = await pacote.packument(spec, { - ...this.npm.flatOptions, + ...npm.flatOptions, fullMetadata: true, }) if (data && data.maintainers && data.maintainers.length) { @@ -130,7 +129,7 @@ class Owner extends BaseCommand { if (this.npm.global) { throw this.usageError() } - const { name } = await readJson(resolve(prefix, 'package.json')) + const { name } = await readJson(prefix) if (!name) { throw this.usageError() } diff --git a/deps/npm/lib/commands/profile.js b/deps/npm/lib/commands/profile.js index 4fba1209e03350..a7d4ac2f29fbe7 100644 --- a/deps/npm/lib/commands/profile.js +++ b/deps/npm/lib/commands/profile.js @@ -53,7 +53,7 @@ class Profile extends BaseCommand { 'otp', ] - async completion (opts) { + static async completion (opts) { var argv = opts.conf.argv.remain if (!argv[2]) { diff --git a/deps/npm/lib/commands/publish.js b/deps/npm/lib/commands/publish.js index 8befbc5ca34cec..54707278f96918 100644 --- a/deps/npm/lib/commands/publish.js +++ b/deps/npm/lib/commands/publish.js @@ -1,4 +1,3 @@ -const util = require('util') const log = require('../utils/log-shim.js') const semver = require('semver') const pack = require('libnpmpack') @@ -17,11 +16,7 @@ const { getContents, logTar } = require('../utils/tar.js') // revisit this at some point, and have a minimal set that's a SemVer-major // change that ought to get a RFC written on it. const { flatten } = require('../utils/config/index.js') - -// this is the only case in the CLI where we want to use the old full slow -// 'read-package-json' module, because we want to pull in all the defaults and -// metadata, like git sha's and default scripts and all that. -const readJson = util.promisify(require('read-package-json')) +const pkgJson = require('@npmcli/package-json') const BaseCommand = require('../base-command.js') class Publish extends BaseCommand { @@ -204,7 +199,9 @@ class Publish extends BaseCommand { async getManifest (spec, opts) { let manifest if (spec.type === 'directory') { - manifest = await readJson(`${spec.fetchSpec}/package.json`) + // Prepare is the special function for publishing, different than normalize + const { content } = await pkgJson.prepare(spec.fetchSpec) + manifest = content } else { manifest = await pacote.manifest(spec, { ...opts, diff --git a/deps/npm/lib/commands/rebuild.js b/deps/npm/lib/commands/rebuild.js index 527447e4279175..8af96f725555cb 100644 --- a/deps/npm/lib/commands/rebuild.js +++ b/deps/npm/lib/commands/rebuild.js @@ -18,9 +18,9 @@ class Rebuild extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { + static async completion (opts, npm) { const completion = require('../utils/completion/installed-deep.js') - return completion(this.npm, opts) + return completion(npm, opts) } async exec (args) { diff --git a/deps/npm/lib/commands/run-script.js b/deps/npm/lib/commands/run-script.js index e1bce0e52a5132..13efdde750a825 100644 --- a/deps/npm/lib/commands/run-script.js +++ b/deps/npm/lib/commands/run-script.js @@ -1,7 +1,6 @@ -const { resolve } = require('path') const runScript = require('@npmcli/run-script') const { isServerPackage } = runScript -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const log = require('../utils/log-shim.js') const didYouMean = require('../utils/did-you-mean.js') const { isWindowsShell } = require('../utils/is-windows.js') @@ -36,12 +35,11 @@ class RunScript extends BaseCommand { static ignoreImplicitWorkspace = false static isShellout = true - async completion (opts) { + static async completion (opts, npm) { const argv = opts.conf.argv.remain if (argv.length === 2) { - // find the script name - const json = resolve(this.npm.localPrefix, 'package.json') - const { scripts = {} } = await rpj(json).catch(er => ({})) + const { content: { scripts = {} } } = await pkgJson.normalize(npm.localPrefix) + .catch(er => ({ content: {} })) if (opts.isFish) { return Object.keys(scripts).map(s => `${s}\t${scripts[s].slice(0, 30)}`) } @@ -70,7 +68,10 @@ class RunScript extends BaseCommand { // null value const scriptShell = this.npm.config.get('script-shell') || undefined - pkg = pkg || (await rpj(`${path}/package.json`)) + if (!pkg) { + const { content } = await pkgJson.normalize(path) + pkg = content + } const { scripts = {} } = pkg if (event === 'restart' && !scripts.restart) { @@ -89,7 +90,7 @@ class RunScript extends BaseCommand { return } - const suggestions = await didYouMean(this.npm, path, event) + const suggestions = await didYouMean(path, event) throw new Error( `Missing script: "${event}"${suggestions}\n\nTo see a list of scripts, run:\n npm run` ) @@ -126,8 +127,8 @@ class RunScript extends BaseCommand { } async list (args, path) { - path = path || this.npm.localPrefix - const { scripts, name, _id } = await rpj(`${path}/package.json`) + /* eslint-disable-next-line max-len */ + const { content: { scripts, name, _id } } = await pkgJson.normalize(path || this.npm.localPrefix) const pkgid = _id || name if (!scripts) { @@ -197,7 +198,7 @@ class RunScript extends BaseCommand { await this.setWorkspaces() for (const workspacePath of this.workspacePaths) { - const pkg = await rpj(`${workspacePath}/package.json`) + const { content: pkg } = await pkgJson.normalize(workspacePath) const runResult = await this.run(args, { path: workspacePath, pkg, @@ -236,7 +237,7 @@ class RunScript extends BaseCommand { if (this.npm.config.get('json')) { const res = {} for (const workspacePath of this.workspacePaths) { - const { scripts, name } = await rpj(`${workspacePath}/package.json`) + const { content: { scripts, name } } = await pkgJson.normalize(workspacePath) res[name] = { ...scripts } } this.npm.output(JSON.stringify(res, null, 2)) @@ -245,7 +246,7 @@ class RunScript extends BaseCommand { if (this.npm.config.get('parseable')) { for (const workspacePath of this.workspacePaths) { - const { scripts, name } = await rpj(`${workspacePath}/package.json`) + const { content: { scripts, name } } = await pkgJson.normalize(workspacePath) for (const [script, cmd] of Object.entries(scripts || {})) { this.npm.output(`${name}:${script}:${cmd}`) } diff --git a/deps/npm/lib/commands/set.js b/deps/npm/lib/commands/set.js index b650026a599a96..f315d183845c5e 100644 --- a/deps/npm/lib/commands/set.js +++ b/deps/npm/lib/commands/set.js @@ -1,15 +1,18 @@ +const Npm = require('../npm.js') const BaseCommand = require('../base-command.js') class Set extends BaseCommand { static description = 'Set a value in the npm configuration' static name = 'set' static usage = ['= [= ...] (See `npm config`)'] + static params = ['global', 'location'] static ignoreImplicitWorkspace = false // TODO /* istanbul ignore next */ - async completion (opts) { - return this.npm.cmd('config').completion(opts) + static async completion (opts) { + const Config = Npm.cmd('config') + return Config.completion(opts) } async exec (args) { diff --git a/deps/npm/lib/commands/team.js b/deps/npm/lib/commands/team.js index 2d4fc663715e4e..3c6cf305a6e5f9 100644 --- a/deps/npm/lib/commands/team.js +++ b/deps/npm/lib/commands/team.js @@ -24,7 +24,7 @@ class Team extends BaseCommand { static ignoreImplicitWorkspace = false - async completion (opts) { + static async completion (opts) { const { conf: { argv: { remain: argv } } } = opts const subcommands = ['create', 'destroy', 'add', 'rm', 'ls'] diff --git a/deps/npm/lib/commands/token.js b/deps/npm/lib/commands/token.js index bc2e4f3796364d..c24684b3dd6143 100644 --- a/deps/npm/lib/commands/token.js +++ b/deps/npm/lib/commands/token.js @@ -14,7 +14,7 @@ class Token extends BaseCommand { static usage = ['list', 'revoke ', 'create [--read-only] [--cidr=list]'] static params = ['read-only', 'cidr', 'registry', 'otp'] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain const subcommands = ['list', 'revoke', 'create'] if (argv.length === 2) { diff --git a/deps/npm/lib/commands/uninstall.js b/deps/npm/lib/commands/uninstall.js index e5373119ec757a..07775efb9cf2f1 100644 --- a/deps/npm/lib/commands/uninstall.js +++ b/deps/npm/lib/commands/uninstall.js @@ -1,5 +1,5 @@ const { resolve } = require('path') -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const reifyFinish = require('../utils/reify-finish.js') const completion = require('../utils/completion/installed-shallow.js') @@ -8,14 +8,14 @@ const ArboristWorkspaceCmd = require('../arborist-cmd.js') class Uninstall extends ArboristWorkspaceCmd { static description = 'Remove a package' static name = 'uninstall' - static params = ['save', ...super.params] + static params = ['save', 'global', ...super.params] static usage = ['[<@scope>/]...'] static ignoreImplicitWorkspace = false // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + return completion(npm, opts) } async exec (args) { @@ -24,7 +24,7 @@ class Uninstall extends ArboristWorkspaceCmd { throw new Error('Must provide a package name to remove') } else { try { - const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.npm.localPrefix) args.push(pkg.name) } catch (er) { if (er.code !== 'ENOENT' && er.code !== 'ENOTDIR') { diff --git a/deps/npm/lib/commands/unpublish.js b/deps/npm/lib/commands/unpublish.js index f1bcded192e5ad..66985297b9574b 100644 --- a/deps/npm/lib/commands/unpublish.js +++ b/deps/npm/lib/commands/unpublish.js @@ -2,9 +2,7 @@ const libaccess = require('libnpmaccess') const libunpub = require('libnpmpublish').unpublish const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') -const path = require('path') -const util = require('util') -const readJson = util.promisify(require('read-package-json')) +const pkgJson = require('@npmcli/package-json') const { flatten } = require('../utils/config/index.js') const getIdentity = require('../utils/get-identity.js') @@ -24,7 +22,7 @@ class Unpublish extends BaseCommand { static workspaces = true static ignoreImplicitWorkspace = false - async getKeysOfVersions (name, opts) { + static async getKeysOfVersions (name, opts) { const pkgUri = npa(name).escapedName const json = await npmFetch.json(`${pkgUri}?write=true`, { ...opts, @@ -33,15 +31,15 @@ class Unpublish extends BaseCommand { return Object.keys(json.versions) } - async completion (args) { + static async completion (args, npm) { const { partialWord, conf } = args if (conf.argv.remain.length >= 3) { return [] } - const opts = { ...this.npm.flatOptions } - const username = await getIdentity(this.npm, { ...opts }).catch(() => null) + const opts = { ...npm.flatOptions } + const username = await getIdentity(npm, { ...opts }).catch(() => null) if (!username) { return [] } @@ -96,8 +94,8 @@ class Unpublish extends BaseCommand { let manifest let manifestErr try { - const pkgJson = path.join(this.npm.localPrefix, 'package.json') - manifest = await readJson(pkgJson) + const { content } = await pkgJson.prepare(this.npm.localPrefix) + manifest = content } catch (err) { manifestErr = err } @@ -107,7 +105,7 @@ class Unpublish extends BaseCommand { if (manifest && manifest.name === spec.name && manifest.publishConfig) { flatten(manifest.publishConfig, opts) } - const versions = await this.getKeysOfVersions(spec.name, opts) + const versions = await Unpublish.getKeysOfVersions(spec.name, opts) if (versions.length === 1 && !force) { throw this.usageError(LAST_REMAINING_VERSION_ERROR) } diff --git a/deps/npm/lib/commands/update.js b/deps/npm/lib/commands/update.js index 26be5ad681983b..caa69dd317ca6b 100644 --- a/deps/npm/lib/commands/update.js +++ b/deps/npm/lib/commands/update.js @@ -31,9 +31,9 @@ class Update extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { + static async completion (opts, npm) { const completion = require('../utils/completion/installed-deep.js') - return completion(this.npm, opts) + return completion(npm, opts) } async exec (args) { diff --git a/deps/npm/lib/commands/version.js b/deps/npm/lib/commands/version.js index a5232836717917..029a6fdd3101e4 100644 --- a/deps/npm/lib/commands/version.js +++ b/deps/npm/lib/commands/version.js @@ -28,7 +28,7 @@ class Version extends BaseCommand { /* eslint-disable-next-line max-len */ static usage = ['[ | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]'] - async completion (opts) { + static async completion (opts) { const { conf: { argv: { remain }, diff --git a/deps/npm/lib/commands/view.js b/deps/npm/lib/commands/view.js index bbe7dcdd18bbf7..f118184124db97 100644 --- a/deps/npm/lib/commands/view.js +++ b/deps/npm/lib/commands/view.js @@ -29,7 +29,7 @@ class View extends BaseCommand { static ignoreImplicitWorkspace = false static usage = ['[] [[.subfield]...]'] - async completion (opts) { + static async completion (opts, npm) { if (opts.conf.argv.remain.length <= 2) { // There used to be registry completion here, but it stopped // making sense somewhere around 50,000 packages on the registry @@ -37,13 +37,13 @@ class View extends BaseCommand { } // have the package, get the fields const config = { - ...this.npm.flatOptions, + ...npm.flatOptions, fullMetadata: true, preferOnline: true, } const spec = npa(opts.conf.argv.remain[2]) const pckmnt = await packument(spec, config) - const defaultTag = this.npm.config.get('tag') + const defaultTag = npm.config.get('tag') const dv = pckmnt.versions[pckmnt['dist-tags'][defaultTag]] pckmnt.versions = Object.keys(pckmnt.versions).sort(semver.compareLoose) diff --git a/deps/npm/lib/es6/validate-engines.js b/deps/npm/lib/es6/validate-engines.js new file mode 100644 index 00000000000000..0eaa549fc3702d --- /dev/null +++ b/deps/npm/lib/es6/validate-engines.js @@ -0,0 +1,49 @@ +// This is separate to indicate that it should contain code we expect to work in +// all versions of node >= 6. This is a best effort to catch syntax errors to +// give users a good error message if they are using a node version that doesn't +// allow syntax we are using such as private properties, etc. This file is +// linted with ecmaVersion=6 so we don't use invalid syntax, which is set in the +// .eslintrc.local.json file + +const { engines: { node: engines }, version } = require('../../package.json') +const npm = `v${version}` + +module.exports = (process, getCli) => { + const node = process.version.replace(/-.*$/, '') + + /* eslint-disable-next-line max-len */ + const unsupportedMessage = `npm ${npm} does not support Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` + + /* eslint-disable-next-line max-len */ + const brokenMessage = `ERROR: npm ${npm} is known not to run on Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` + + // coverage ignored because this is only hit in very unsupported node versions + // and it's a best effort attempt to show something nice in those cases + /* istanbul ignore next */ + const syntaxErrorHandler = (err) => { + if (err instanceof SyntaxError) { + // eslint-disable-next-line no-console + console.error(`${brokenMessage}\n\nERROR:`) + // eslint-disable-next-line no-console + console.error(err) + return process.exit(1) + } + throw err + } + + process.on('uncaughtException', syntaxErrorHandler) + process.on('unhandledRejection', syntaxErrorHandler) + + // require this only after setting up the error handlers + const cli = getCli() + return cli(process, { + node, + npm, + engines, + unsupportedMessage, + off: () => { + process.off('uncaughtException', syntaxErrorHandler) + process.off('unhandledRejection', syntaxErrorHandler) + }, + }) +} diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index eebb453dbbacb1..f08ef32c180d91 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -1,10 +1,7 @@ -const EventEmitter = require('events') const { resolve, dirname, join } = require('path') const Config = require('@npmcli/config') -const chalk = require('chalk') const which = require('which') const fs = require('fs/promises') -const abbrev = require('abbrev') // Patch the global fs module here at the app level require('graceful-fs').gracefulify(require('fs')) @@ -18,13 +15,23 @@ const log = require('./utils/log-shim') const replaceInfo = require('./utils/replace-info.js') const updateNotifier = require('./utils/update-notifier.js') const pkg = require('../package.json') -const { commands, aliases } = require('./utils/cmd-list.js') +const { deref } = require('./utils/cmd-list.js') -class Npm extends EventEmitter { +class Npm { static get version () { return pkg.version } + static cmd (c) { + const command = deref(c) + if (!command) { + throw Object.assign(new Error(`Unknown command ${c}`), { + code: 'EUNKNOWNCOMMAND', + }) + } + return require(`./commands/${command}.js`) + } + updateNotification = null loadErr = null argv = [] @@ -32,15 +39,15 @@ class Npm extends EventEmitter { #command = null #runId = new Date().toISOString().replace(/[.:]/g, '_') #loadPromise = null - #tmpFolder = null #title = 'npm' #argvClean = [] - #chalk = null - #logChalk = null - #noColorChalk = new chalk.Instance({ level: 0 }) #npmRoot = null #warnedNonDashArg = false + #chalk = null + #logChalk = null + #noColorChalk = null + #outputBuffer = [] #logFile = new LogFile() #display = new Display() @@ -66,7 +73,6 @@ class Npm extends EventEmitter { // prefix to `npmRoot` since that is the first dir it would encounter when // doing implicit detection constructor ({ npmRoot = dirname(__dirname), argv = [], excludeNpmCwd = false } = {}) { - super() this.#npmRoot = npmRoot this.config = new Config({ npmPath: this.#npmRoot, @@ -82,53 +88,9 @@ class Npm extends EventEmitter { return this.constructor.version } - deref (c) { - if (!c) { - return - } - - // Translate camelCase to snake-case (i.e. installTest to install-test) - if (c.match(/[A-Z]/)) { - c = c.replace(/([A-Z])/g, m => '-' + m.toLowerCase()) - } - - // if they asked for something exactly we are done - if (commands.includes(c)) { - return c - } - - // if they asked for a direct alias - if (aliases[c]) { - return aliases[c] - } - - const abbrevs = abbrev(commands.concat(Object.keys(aliases))) - - // first deref the abbrev, if there is one - // then resolve any aliases - // so `npm install-cl` will resolve to `install-clean` then to `ci` - let a = abbrevs[c] - while (aliases[a]) { - a = aliases[a] - } - return a - } - - // Get an instantiated npm command - // npm.command is already taken as the currently running command, a refactor - // would be needed to change this - async cmd (cmd) { - await this.load() - - const cmdId = this.deref(cmd) - if (!cmdId) { - throw Object.assign(new Error(`Unknown command ${cmd}`), { - code: 'EUNKNOWNCOMMAND', - }) - } - - const Impl = require(`./commands/${cmdId}.js`) - const command = new Impl(this) + setCmd (cmd) { + const Command = Npm.cmd(cmd) + const command = new Command(this) // since 'test', 'start', 'stop', etc. commands re-enter this function // to call the run-script command, we need to only set it one time. @@ -141,8 +103,14 @@ class Npm extends EventEmitter { } // Call an npm command + // TODO: tests are currently the only time the second + // parameter of args is used. When called via `lib/cli.js` the config is + // loaded and this.argv is set to the remaining command line args. We should + // consider testing the CLI the same way it is used and not allow args to be + // passed in directly. async exec (cmd, args = this.argv) { - const command = await this.cmd(cmd) + const command = this.setCmd(cmd) + const timeEnd = this.time(`command:${cmd}`) // this is async but we dont await it, since its ok if it doesnt @@ -226,6 +194,13 @@ class Npm extends EventEmitter { await this.time('npm:load:configload', () => this.config.load()) + const { Chalk, supportsColor, supportsColorStderr } = await import('chalk') + this.#noColorChalk = new Chalk({ level: 0 }) + this.#chalk = this.color ? new Chalk({ level: supportsColor.level }) + : this.#noColorChalk + this.#logChalk = this.logColor ? new Chalk({ level: supportsColorStderr.level }) + : this.#noColorChalk + // mkdir this separately since the logs dir can be set to // a different location. if this fails, then we don't have // a cache dir, but we don't want to fail immediately since @@ -333,20 +308,10 @@ class Npm extends EventEmitter { } get chalk () { - if (!this.#chalk) { - this.#chalk = new chalk.Instance({ - level: this.color ? chalk.level : 0, - }) - } return this.#chalk } get logChalk () { - if (!this.#logChalk) { - this.#logChalk = new chalk.Instance({ - level: this.logColor ? chalk.stderr.level : 0, - }) - } return this.#logChalk } @@ -462,15 +427,6 @@ class Npm extends EventEmitter { return usage(this) } - // XXX add logging to see if we actually use this - get tmp () { - if (!this.#tmpFolder) { - const rand = require('crypto').randomBytes(4).toString('hex') - this.#tmpFolder = `npm-${process.pid}-${rand}` - } - return resolve(this.config.get('tmp'), this.#tmpFolder) - } - // output to stdout in a progress bar compatible way output (...msg) { log.clearProgress() diff --git a/deps/npm/lib/utils/cmd-list.js b/deps/npm/lib/utils/cmd-list.js index e5479139033d57..9bd252bc3facce 100644 --- a/deps/npm/lib/utils/cmd-list.js +++ b/deps/npm/lib/utils/cmd-list.js @@ -1,3 +1,5 @@ +const abbrev = require('abbrev') + // These correspond to filenames in lib/commands // Please keep this list sorted alphabetically const commands = [ @@ -136,7 +138,40 @@ const aliases = { 'add-user': 'adduser', } +const deref = (c) => { + if (!c) { + return + } + + // Translate camelCase to snake-case (i.e. installTest to install-test) + if (c.match(/[A-Z]/)) { + c = c.replace(/([A-Z])/g, m => '-' + m.toLowerCase()) + } + + // if they asked for something exactly we are done + if (commands.includes(c)) { + return c + } + + // if they asked for a direct alias + if (aliases[c]) { + return aliases[c] + } + + const abbrevs = abbrev(commands.concat(Object.keys(aliases))) + + // first deref the abbrev, if there is one + // then resolve any aliases + // so `npm install-cl` will resolve to `install-clean` then to `ci` + let a = abbrevs[c] + while (aliases[a]) { + a = aliases[a] + } + return a +} + module.exports = { aliases, commands, + deref, } diff --git a/deps/npm/lib/utils/config/definition.js b/deps/npm/lib/utils/config/definition.js index f88d8334cf01fb..54e522c355b93d 100644 --- a/deps/npm/lib/utils/config/definition.js +++ b/deps/npm/lib/utils/config/definition.js @@ -13,6 +13,7 @@ const allowed = [ 'defaultDescription', 'deprecated', 'description', + 'exclusive', 'flatten', 'hint', 'key', @@ -83,12 +84,15 @@ class Definition { This value is not exported to the environment for child processes. ` const deprecated = !this.deprecated ? '' : `* DEPRECATED: ${unindent(this.deprecated)}\n` + /* eslint-disable-next-line max-len */ + const exclusive = !this.exclusive ? '' : `\nThis config can not be used with: \`${this.exclusive.join('`, `')}\`` return wrapAll(`#### \`${this.key}\` * Default: ${unindent(this.defaultDescription)} * Type: ${unindent(this.typeDescription)} ${deprecated} ${description} +${exclusive} ${noEnvExport}`) } } diff --git a/deps/npm/lib/utils/config/definitions.js b/deps/npm/lib/utils/config/definitions.js index 78c341eabeffa7..f86c3ddff81b5e 100644 --- a/deps/npm/lib/utils/config/definitions.js +++ b/deps/npm/lib/utils/config/definitions.js @@ -331,6 +331,7 @@ define('cache', { flatten (key, obj, flatOptions) { flatOptions.cache = join(obj.cache, '_cacache') flatOptions.npxCache = join(obj.cache, '_npx') + flatOptions.tufCache = join(obj.cache, '_tuf') }, }) @@ -1495,8 +1496,6 @@ define('package-lock', { If set to false, then ignore \`package-lock.json\` files when installing. This will also prevent _writing_ \`package-lock.json\` if \`save\` is true. - - This configuration does not affect \`npm ci\`. `, flatten: (key, obj, flatOptions) => { flatten(key, obj, flatOptions) @@ -1547,6 +1546,16 @@ define('parseable', { flatten, }) +define('prefer-dedupe', { + default: false, + type: Boolean, + description: ` + Prefer to deduplicate packages if possible, rather than + choosing a newer version of a dependency. + `, + flatten, +}) + define('prefer-offline', { default: false, type: Boolean, @@ -1626,6 +1635,7 @@ define('progress', { define('provenance', { default: false, type: Boolean, + exclusive: ['provenance-file'], description: ` When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from. @@ -1633,6 +1643,17 @@ define('provenance', { flatten, }) +define('provenance-file', { + default: null, + type: path, + hint: '', + exclusive: ['provenance'], + description: ` + When publishing, the provenance bundle at the given path will be used. + `, + flatten, +}) + define('proxy', { default: null, type: [null, false, url], // allow proxy to be disabled explicitly diff --git a/deps/npm/lib/utils/did-you-mean.js b/deps/npm/lib/utils/did-you-mean.js index 10b33d5f83a080..ff3c812b46c3c7 100644 --- a/deps/npm/lib/utils/did-you-mean.js +++ b/deps/npm/lib/utils/did-you-mean.js @@ -1,19 +1,19 @@ +const Npm = require('../npm') const { distance } = require('fastest-levenshtein') -const readJson = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const { commands } = require('./cmd-list.js') -const didYouMean = async (npm, path, scmd) => { - // const cmd = await npm.cmd(str) +const didYouMean = async (path, scmd) => { const close = commands.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && scmd !== cmd) let best = [] for (const str of close) { - const cmd = await npm.cmd(str) + const cmd = Npm.cmd(str) best.push(` npm ${str} # ${cmd.description}`) } // We would already be suggesting this in `npm x` so omit them here const runScripts = ['stop', 'start', 'test', 'restart'] try { - const { bin, scripts } = await readJson(`${path}/package.json`) + const { content: { scripts, bin } } = await pkgJson.normalize(path) best = best.concat( Object.keys(scripts || {}) .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && !runScripts.includes(cmd)) diff --git a/deps/npm/lib/utils/explain-eresolve.js b/deps/npm/lib/utils/explain-eresolve.js index ba46f3480adb36..f3c6ae23a479db 100644 --- a/deps/npm/lib/utils/explain-eresolve.js +++ b/deps/npm/lib/utils/explain-eresolve.js @@ -44,7 +44,7 @@ const explain = (expl, chalk, depth) => { } // generate a full verbose report and tell the user how to fix it -const report = (expl, chalk, noColor) => { +const report = (expl, chalk, noColorChalk) => { const flags = [ expl.strictPeerDeps ? '--no-strict-peer-deps' : '', '--force', @@ -61,7 +61,7 @@ to accept an incorrect (and potentially broken) dependency resolution.` return { explanation: `${explain(expl, chalk, 4)}\n\n${fix}`, - file: `# npm resolution error report\n\n${explain(expl, noColor, Infinity)}\n\n${fix}`, + file: `# npm resolution error report\n\n${explain(expl, noColorChalk, Infinity)}\n\n${fix}`, } } diff --git a/deps/npm/lib/utils/format-search-stream.js b/deps/npm/lib/utils/format-search-stream.js index 21929cce7d056b..762dea90859d19 100644 --- a/deps/npm/lib/utils/format-search-stream.js +++ b/deps/npm/lib/utils/format-search-stream.js @@ -1,5 +1,6 @@ const { Minipass } = require('minipass') const columnify = require('columnify') +const ansiTrim = require('../utils/ansi-trim.js') // This module consumes package data in the following format: // @@ -141,13 +142,13 @@ function highlightSearchTerms (str, terms) { function normalizePackage (data, opts) { return { - name: data.name, - description: data.description, - author: data.maintainers.map((m) => `=${m.username}`).join(' '), + name: ansiTrim(data.name), + description: ansiTrim(data.description), + author: data.maintainers.map((m) => `=${ansiTrim(m.username)}`).join(' '), keywords: Array.isArray(data.keywords) - ? data.keywords.join(' ') + ? data.keywords.map(ansiTrim).join(' ') : typeof data.keywords === 'string' - ? data.keywords.replace(/[,\s]+/, ' ') + ? ansiTrim(data.keywords.replace(/[,\s]+/, ' ')) : '', version: data.version, date: (data.date && diff --git a/deps/npm/lib/utils/npm-usage.js b/deps/npm/lib/utils/npm-usage.js index b04ad33f9dd79f..1bd790ca601bcd 100644 --- a/deps/npm/lib/utils/npm-usage.js +++ b/deps/npm/lib/utils/npm-usage.js @@ -8,9 +8,9 @@ const INDENT = 4 const indent = (repeat = INDENT) => ' '.repeat(repeat) const indentNewline = (repeat) => `\n${indent(repeat)}` -module.exports = async (npm) => { +module.exports = (npm) => { const browser = npm.config.get('viewer') === 'browser' ? ' (in a browser)' : '' - const allCommands = npm.config.get('long') ? await cmdUsages(npm) : cmdNames() + const allCommands = npm.config.get('long') ? cmdUsages(npm.constructor) : cmdNames() return `npm @@ -57,13 +57,12 @@ const cmdNames = () => { return indentNewline() + out.join(indentNewline()).slice(2) } -const cmdUsages = async (npm) => { +const cmdUsages = (Npm) => { // return a string of : let maxLen = 0 const set = [] for (const c of commands) { - const { usage } = await npm.cmd(c) - set.push([c, usage.split('\n')]) + set.push([c, Npm.cmd(c).describeUsage.split('\n')]) maxLen = Math.max(maxLen, c.length) } diff --git a/deps/npm/lib/utils/reify-output.js b/deps/npm/lib/utils/reify-output.js index 5ac7fa4b01896b..22036dc8110cfc 100644 --- a/deps/npm/lib/utils/reify-output.js +++ b/deps/npm/lib/utils/reify-output.js @@ -116,6 +116,7 @@ const getAuditReport = (npm, report) => { reporter, ...npm.flatOptions, auditLevel, + chalk: npm.chalk, }) if (npm.command === 'audit') { process.exitCode = process.exitCode || res.exitCode diff --git a/deps/npm/lib/workspaces/get-workspaces.js b/deps/npm/lib/workspaces/get-workspaces.js index 7065533596000e..59efb0e9f01bef 100644 --- a/deps/npm/lib/workspaces/get-workspaces.js +++ b/deps/npm/lib/workspaces/get-workspaces.js @@ -1,7 +1,7 @@ const { resolve, relative } = require('path') const mapWorkspaces = require('@npmcli/map-workspaces') const { minimatch } = require('minimatch') -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') // minimatch wants forward slashes only for glob patterns const globify = pattern => pattern.split('\\').join('/') @@ -9,8 +9,8 @@ const globify = pattern => pattern.split('\\').join('/') // Returns an Map of paths to workspaces indexed by workspace name // { foo => '/path/to/foo' } const getWorkspaces = async (filters, { path, includeWorkspaceRoot, relativeFrom }) => { - // TODO we need a better error to be bubbled up here if this rpj call fails - const pkg = await rpj(resolve(path, 'package.json')) + // TODO we need a better error to be bubbled up here if this call fails + const { content: pkg } = await pkgJson.normalize(path) const workspaces = await mapWorkspaces({ cwd: path, pkg }) let res = new Map() if (includeWorkspaceRoot) { diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index 8b8d996a119970..96534a0850595a 100644 --- a/deps/npm/man/man1/npm-access.1 +++ b/deps/npm/man/man1/npm-access.1 @@ -1,4 +1,4 @@ -.TH "NPM-ACCESS" "1" "May 2023" "" "" +.TH "NPM-ACCESS" "1" "June 2023" "" "" .SH "NAME" \fBnpm-access\fR - Set access level on published packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1 index 4653d85c7f8f8e..3a018dbdb9bc15 100644 --- a/deps/npm/man/man1/npm-adduser.1 +++ b/deps/npm/man/man1/npm-adduser.1 @@ -1,4 +1,4 @@ -.TH "NPM-ADDUSER" "1" "May 2023" "" "" +.TH "NPM-ADDUSER" "1" "June 2023" "" "" .SH "NAME" \fBnpm-adduser\fR - Add a registry user account .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-audit.1 b/deps/npm/man/man1/npm-audit.1 index 270c517ef17fc5..da9a483715f697 100644 --- a/deps/npm/man/man1/npm-audit.1 +++ b/deps/npm/man/man1/npm-audit.1 @@ -1,4 +1,4 @@ -.TH "NPM-AUDIT" "1" "May 2023" "" "" +.TH "NPM-AUDIT" "1" "June 2023" "" "" .SH "NAME" \fBnpm-audit\fR - Run a security audit .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1 index efd8922d66c65a..a5ddd4e79cf712 100644 --- a/deps/npm/man/man1/npm-bugs.1 +++ b/deps/npm/man/man1/npm-bugs.1 @@ -1,4 +1,4 @@ -.TH "NPM-BUGS" "1" "May 2023" "" "" +.TH "NPM-BUGS" "1" "June 2023" "" "" .SH "NAME" \fBnpm-bugs\fR - Report bugs for a package in a web browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1 index 2757922d47b37f..5669388f55387d 100644 --- a/deps/npm/man/man1/npm-cache.1 +++ b/deps/npm/man/man1/npm-cache.1 @@ -1,4 +1,4 @@ -.TH "NPM-CACHE" "1" "May 2023" "" "" +.TH "NPM-CACHE" "1" "June 2023" "" "" .SH "NAME" \fBnpm-cache\fR - Manipulates packages cache .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ci.1 b/deps/npm/man/man1/npm-ci.1 index 4728ef4cb9bf44..05e435ec7b9fcf 100644 --- a/deps/npm/man/man1/npm-ci.1 +++ b/deps/npm/man/man1/npm-ci.1 @@ -1,4 +1,4 @@ -.TH "NPM-CI" "1" "May 2023" "" "" +.TH "NPM-CI" "1" "June 2023" "" "" .SH "NAME" \fBnpm-ci\fR - Clean install a project .SS "Synopsis" @@ -130,18 +130,6 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object. .P When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure. -.SS "\fBpackage-lock\fR" -.RS 0 -.IP \(bu 4 -Default: true -.IP \(bu 4 -Type: Boolean -.RE 0 - -.P -If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBforeground-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1 index 18a006978e39b0..d72df722ccd343 100644 --- a/deps/npm/man/man1/npm-completion.1 +++ b/deps/npm/man/man1/npm-completion.1 @@ -1,4 +1,4 @@ -.TH "NPM-COMPLETION" "1" "May 2023" "" "" +.TH "NPM-COMPLETION" "1" "June 2023" "" "" .SH "NAME" \fBnpm-completion\fR - Tab Completion for npm .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1 index a860ea4a9533fc..4b19fa0e473575 100644 --- a/deps/npm/man/man1/npm-config.1 +++ b/deps/npm/man/man1/npm-config.1 @@ -1,4 +1,4 @@ -.TH "NPM-CONFIG" "1" "May 2023" "" "" +.TH "NPM-CONFIG" "1" "June 2023" "" "" .SH "NAME" \fBnpm-config\fR - Manage the npm configuration files .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1 index 8cbe55011c070e..56e57db5eb54d0 100644 --- a/deps/npm/man/man1/npm-dedupe.1 +++ b/deps/npm/man/man1/npm-dedupe.1 @@ -1,4 +1,4 @@ -.TH "NPM-DEDUPE" "1" "May 2023" "" "" +.TH "NPM-DEDUPE" "1" "June 2023" "" "" .SH "NAME" \fBnpm-dedupe\fR - Reduce duplication in the package tree .SS "Synopsis" @@ -123,8 +123,6 @@ Type: Boolean .P If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBomit\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index f4b4087a428007..1458a880fca9d2 100644 --- a/deps/npm/man/man1/npm-deprecate.1 +++ b/deps/npm/man/man1/npm-deprecate.1 @@ -1,4 +1,4 @@ -.TH "NPM-DEPRECATE" "1" "May 2023" "" "" +.TH "NPM-DEPRECATE" "1" "June 2023" "" "" .SH "NAME" \fBnpm-deprecate\fR - Deprecate a version of a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-diff.1 b/deps/npm/man/man1/npm-diff.1 index 906e1776f5f028..44df189c3910b9 100644 --- a/deps/npm/man/man1/npm-diff.1 +++ b/deps/npm/man/man1/npm-diff.1 @@ -1,4 +1,4 @@ -.TH "NPM-DIFF" "1" "May 2023" "" "" +.TH "NPM-DIFF" "1" "June 2023" "" "" .SH "NAME" \fBnpm-diff\fR - The registry diff command .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1 index 50dc8e3908041e..11e501009fb13b 100644 --- a/deps/npm/man/man1/npm-dist-tag.1 +++ b/deps/npm/man/man1/npm-dist-tag.1 @@ -1,4 +1,4 @@ -.TH "NPM-DIST-TAG" "1" "May 2023" "" "" +.TH "NPM-DIST-TAG" "1" "June 2023" "" "" .SH "NAME" \fBnpm-dist-tag\fR - Modify package distribution tags .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1 index be212b1f014cae..dd701e97099786 100644 --- a/deps/npm/man/man1/npm-docs.1 +++ b/deps/npm/man/man1/npm-docs.1 @@ -1,4 +1,4 @@ -.TH "NPM-DOCS" "1" "May 2023" "" "" +.TH "NPM-DOCS" "1" "June 2023" "" "" .SH "NAME" \fBnpm-docs\fR - Open documentation for a package in a web browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1 index 1592de0c32203b..b1d36f31034abb 100644 --- a/deps/npm/man/man1/npm-doctor.1 +++ b/deps/npm/man/man1/npm-doctor.1 @@ -1,4 +1,4 @@ -.TH "NPM-DOCTOR" "1" "May 2023" "" "" +.TH "NPM-DOCTOR" "1" "June 2023" "" "" .SH "NAME" \fBnpm-doctor\fR - Check your npm environment .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1 index 1c428d2c2a9f89..140946f3a1d30c 100644 --- a/deps/npm/man/man1/npm-edit.1 +++ b/deps/npm/man/man1/npm-edit.1 @@ -1,4 +1,4 @@ -.TH "NPM-EDIT" "1" "May 2023" "" "" +.TH "NPM-EDIT" "1" "June 2023" "" "" .SH "NAME" \fBnpm-edit\fR - Edit an installed package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-exec.1 b/deps/npm/man/man1/npm-exec.1 index d1260e21844075..d6efae12633f32 100644 --- a/deps/npm/man/man1/npm-exec.1 +++ b/deps/npm/man/man1/npm-exec.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXEC" "1" "May 2023" "" "" +.TH "NPM-EXEC" "1" "June 2023" "" "" .SH "NAME" \fBnpm-exec\fR - Run a command from a local or remote npm package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-explain.1 b/deps/npm/man/man1/npm-explain.1 index d206176d92ba6a..1a32c14c1d3d71 100644 --- a/deps/npm/man/man1/npm-explain.1 +++ b/deps/npm/man/man1/npm-explain.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXPLAIN" "1" "May 2023" "" "" +.TH "NPM-EXPLAIN" "1" "June 2023" "" "" .SH "NAME" \fBnpm-explain\fR - Explain installed packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1 index 39fe060038a849..2e9549c753aa92 100644 --- a/deps/npm/man/man1/npm-explore.1 +++ b/deps/npm/man/man1/npm-explore.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXPLORE" "1" "May 2023" "" "" +.TH "NPM-EXPLORE" "1" "June 2023" "" "" .SH "NAME" \fBnpm-explore\fR - Browse an installed package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-find-dupes.1 b/deps/npm/man/man1/npm-find-dupes.1 index efb00a7eba7b88..13d9d3adebaafa 100644 --- a/deps/npm/man/man1/npm-find-dupes.1 +++ b/deps/npm/man/man1/npm-find-dupes.1 @@ -1,4 +1,4 @@ -.TH "NPM-FIND-DUPES" "1" "May 2023" "" "" +.TH "NPM-FIND-DUPES" "1" "June 2023" "" "" .SH "NAME" \fBnpm-find-dupes\fR - Find duplication in the package tree .SS "Synopsis" @@ -70,8 +70,6 @@ Type: Boolean .P If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBomit\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1 index fe3adb8a7bca8f..074cd075823dc8 100644 --- a/deps/npm/man/man1/npm-fund.1 +++ b/deps/npm/man/man1/npm-fund.1 @@ -1,4 +1,4 @@ -.TH "NPM-FUND" "1" "May 2023" "" "" +.TH "NPM-FUND" "1" "June 2023" "" "" .SH "NAME" \fBnpm-fund\fR - Retrieve funding information .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1 index e46f4b3d2f89c5..1de2840e884e26 100644 --- a/deps/npm/man/man1/npm-help-search.1 +++ b/deps/npm/man/man1/npm-help-search.1 @@ -1,4 +1,4 @@ -.TH "NPM-HELP-SEARCH" "1" "May 2023" "" "" +.TH "NPM-HELP-SEARCH" "1" "June 2023" "" "" .SH "NAME" \fBnpm-help-search\fR - Search npm help documentation .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1 index b95a78b18bf959..340db5486a6451 100644 --- a/deps/npm/man/man1/npm-help.1 +++ b/deps/npm/man/man1/npm-help.1 @@ -1,4 +1,4 @@ -.TH "NPM-HELP" "1" "May 2023" "" "" +.TH "NPM-HELP" "1" "June 2023" "" "" .SH "NAME" \fBnpm-help\fR - Get help on npm .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-hook.1 b/deps/npm/man/man1/npm-hook.1 index 99cc0585ffda58..4dfab8c702c82e 100644 --- a/deps/npm/man/man1/npm-hook.1 +++ b/deps/npm/man/man1/npm-hook.1 @@ -1,4 +1,4 @@ -.TH "NPM-HOOK" "1" "May 2023" "" "" +.TH "NPM-HOOK" "1" "June 2023" "" "" .SH "NAME" \fBnpm-hook\fR - Manage registry hooks .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1 index ec4f8c5c1e35fa..d74c57e3266c81 100644 --- a/deps/npm/man/man1/npm-init.1 +++ b/deps/npm/man/man1/npm-init.1 @@ -1,4 +1,4 @@ -.TH "NPM-INIT" "1" "May 2023" "" "" +.TH "NPM-INIT" "1" "June 2023" "" "" .SH "NAME" \fBnpm-init\fR - Create a package.json file .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-install-ci-test.1 b/deps/npm/man/man1/npm-install-ci-test.1 index 96b310cdf98766..0aac5f1f874954 100644 --- a/deps/npm/man/man1/npm-install-ci-test.1 +++ b/deps/npm/man/man1/npm-install-ci-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL-CI-TEST" "1" "May 2023" "" "" +.TH "NPM-INSTALL-CI-TEST" "1" "June 2023" "" "" .SH "NAME" \fBnpm-install-ci-test\fR - Install a project with a clean slate and run tests .SS "Synopsis" @@ -78,18 +78,6 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object. .P When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure. -.SS "\fBpackage-lock\fR" -.RS 0 -.IP \(bu 4 -Default: true -.IP \(bu 4 -Type: Boolean -.RE 0 - -.P -If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBforeground-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1 index a403b55b15ba10..b66013372f7be7 100644 --- a/deps/npm/man/man1/npm-install-test.1 +++ b/deps/npm/man/man1/npm-install-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL-TEST" "1" "May 2023" "" "" +.TH "NPM-INSTALL-TEST" "1" "June 2023" "" "" .SH "NAME" \fBnpm-install-test\fR - Install package(s) and run tests .SS "Synopsis" @@ -121,6 +121,16 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object. .P When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure. +.SS "\fBprefer-dedupe\fR" +.RS 0 +.IP \(bu 4 +Default: false +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Prefer to deduplicate packages if possible, rather than choosing a newer version of a dependency. .SS "\fBpackage-lock\fR" .RS 0 .IP \(bu 4 @@ -131,8 +141,6 @@ Type: Boolean .P If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBforeground-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1 index 8359b949f1644e..e8a019ad45e325 100644 --- a/deps/npm/man/man1/npm-install.1 +++ b/deps/npm/man/man1/npm-install.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL" "1" "May 2023" "" "" +.TH "NPM-INSTALL" "1" "June 2023" "" "" .SH "NAME" \fBnpm-install\fR - Install a package .SS "Synopsis" @@ -483,6 +483,16 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object. .P When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure. +.SS "\fBprefer-dedupe\fR" +.RS 0 +.IP \(bu 4 +Default: false +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Prefer to deduplicate packages if possible, rather than choosing a newer version of a dependency. .SS "\fBpackage-lock\fR" .RS 0 .IP \(bu 4 @@ -493,8 +503,6 @@ Type: Boolean .P If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBforeground-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1 index ebe0a7c70d7ae4..38df2396ca9b08 100644 --- a/deps/npm/man/man1/npm-link.1 +++ b/deps/npm/man/man1/npm-link.1 @@ -1,4 +1,4 @@ -.TH "NPM-LINK" "1" "May 2023" "" "" +.TH "NPM-LINK" "1" "June 2023" "" "" .SH "NAME" \fBnpm-link\fR - Symlink a package folder .SS "Synopsis" @@ -182,8 +182,6 @@ Type: Boolean .P If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBomit\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-login.1 b/deps/npm/man/man1/npm-login.1 index 61b9c2ae235dd7..f593dbb817ef87 100644 --- a/deps/npm/man/man1/npm-login.1 +++ b/deps/npm/man/man1/npm-login.1 @@ -1,4 +1,4 @@ -.TH "NPM-LOGIN" "1" "May 2023" "" "" +.TH "NPM-LOGIN" "1" "June 2023" "" "" .SH "NAME" \fBnpm-login\fR - Login to a registry user account .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1 index 546a04044e4eeb..1f3fbb5f40b0f4 100644 --- a/deps/npm/man/man1/npm-logout.1 +++ b/deps/npm/man/man1/npm-logout.1 @@ -1,4 +1,4 @@ -.TH "NPM-LOGOUT" "1" "May 2023" "" "" +.TH "NPM-LOGOUT" "1" "June 2023" "" "" .SH "NAME" \fBnpm-logout\fR - Log out of the registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index fe605158b7aaa9..4696fc20bf6d4a 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -1,4 +1,4 @@ -.TH "NPM-LS" "1" "May 2023" "" "" +.TH "NPM-LS" "1" "June 2023" "" "" .SH "NAME" \fBnpm-ls\fR - List installed packages .SS "Synopsis" @@ -20,7 +20,7 @@ Positional arguments are \fBname@version-range\fR identifiers, which will limit .P .RS 2 .nf -npm@9.6.7 /path/to/npm +npm@9.7.1 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 .fi diff --git a/deps/npm/man/man1/npm-org.1 b/deps/npm/man/man1/npm-org.1 index 8a69570f2da319..0d1d4458e2f0c5 100644 --- a/deps/npm/man/man1/npm-org.1 +++ b/deps/npm/man/man1/npm-org.1 @@ -1,4 +1,4 @@ -.TH "NPM-ORG" "1" "May 2023" "" "" +.TH "NPM-ORG" "1" "June 2023" "" "" .SH "NAME" \fBnpm-org\fR - Manage orgs .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1 index 96527eec8bda05..b1665a772b0b94 100644 --- a/deps/npm/man/man1/npm-outdated.1 +++ b/deps/npm/man/man1/npm-outdated.1 @@ -1,4 +1,4 @@ -.TH "NPM-OUTDATED" "1" "May 2023" "" "" +.TH "NPM-OUTDATED" "1" "June 2023" "" "" .SH "NAME" \fBnpm-outdated\fR - Check for outdated packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1 index 68997c98c121b5..16a6febff6c7c6 100644 --- a/deps/npm/man/man1/npm-owner.1 +++ b/deps/npm/man/man1/npm-owner.1 @@ -1,4 +1,4 @@ -.TH "NPM-OWNER" "1" "May 2023" "" "" +.TH "NPM-OWNER" "1" "June 2023" "" "" .SH "NAME" \fBnpm-owner\fR - Manage package owners .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1 index 40e1ac2e382466..7803db5d7a8f8a 100644 --- a/deps/npm/man/man1/npm-pack.1 +++ b/deps/npm/man/man1/npm-pack.1 @@ -1,4 +1,4 @@ -.TH "NPM-PACK" "1" "May 2023" "" "" +.TH "NPM-PACK" "1" "June 2023" "" "" .SH "NAME" \fBnpm-pack\fR - Create a tarball from a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ping.1 b/deps/npm/man/man1/npm-ping.1 index db6f0a79d6bb92..568a752ae79da4 100644 --- a/deps/npm/man/man1/npm-ping.1 +++ b/deps/npm/man/man1/npm-ping.1 @@ -1,4 +1,4 @@ -.TH "NPM-PING" "1" "May 2023" "" "" +.TH "NPM-PING" "1" "June 2023" "" "" .SH "NAME" \fBnpm-ping\fR - Ping npm registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-pkg.1 b/deps/npm/man/man1/npm-pkg.1 index 42e6834e7e55c2..ec10aec156d281 100644 --- a/deps/npm/man/man1/npm-pkg.1 +++ b/deps/npm/man/man1/npm-pkg.1 @@ -1,4 +1,4 @@ -.TH "NPM-PKG" "1" "May 2023" "" "" +.TH "NPM-PKG" "1" "June 2023" "" "" .SH "NAME" \fBnpm-pkg\fR - Manages your package.json .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1 index a1d4ee3dbc022b..9b24982794ac1b 100644 --- a/deps/npm/man/man1/npm-prefix.1 +++ b/deps/npm/man/man1/npm-prefix.1 @@ -1,4 +1,4 @@ -.TH "NPM-PREFIX" "1" "May 2023" "" "" +.TH "NPM-PREFIX" "1" "June 2023" "" "" .SH "NAME" \fBnpm-prefix\fR - Display prefix .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-profile.1 b/deps/npm/man/man1/npm-profile.1 index b4f3595ff6832f..cc5daf398a546e 100644 --- a/deps/npm/man/man1/npm-profile.1 +++ b/deps/npm/man/man1/npm-profile.1 @@ -1,4 +1,4 @@ -.TH "NPM-PROFILE" "1" "May 2023" "" "" +.TH "NPM-PROFILE" "1" "June 2023" "" "" .SH "NAME" \fBnpm-profile\fR - Change settings on your registry profile .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1 index 98d181fe627348..d724cc5282c7c5 100644 --- a/deps/npm/man/man1/npm-prune.1 +++ b/deps/npm/man/man1/npm-prune.1 @@ -1,4 +1,4 @@ -.TH "NPM-PRUNE" "1" "May 2023" "" "" +.TH "NPM-PRUNE" "1" "June 2023" "" "" .SH "NAME" \fBnpm-prune\fR - Remove extraneous packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1 index 5f7ccce98d1180..bb315398794607 100644 --- a/deps/npm/man/man1/npm-publish.1 +++ b/deps/npm/man/man1/npm-publish.1 @@ -1,4 +1,4 @@ -.TH "NPM-PUBLISH" "1" "May 2023" "" "" +.TH "NPM-PUBLISH" "1" "June 2023" "" "" .SH "NAME" \fBnpm-publish\fR - Publish a package .SS "Synopsis" @@ -182,6 +182,20 @@ Type: Boolean .P When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from. +.P +This config can not be used with: \fBprovenance-file\fR +.SS "\fBprovenance-file\fR" +.RS 0 +.IP \(bu 4 +Default: null +.IP \(bu 4 +Type: Path +.RE 0 + +.P +When publishing, the provenance bundle at the given path will be used. +.P +This config can not be used with: \fBprovenance\fR .SS "See Also" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-query.1 b/deps/npm/man/man1/npm-query.1 index 0cd80c479cfe2b..84dcbb9775770d 100644 --- a/deps/npm/man/man1/npm-query.1 +++ b/deps/npm/man/man1/npm-query.1 @@ -1,4 +1,4 @@ -.TH "NPM-QUERY" "1" "May 2023" "" "" +.TH "NPM-QUERY" "1" "June 2023" "" "" .SH "NAME" \fBnpm-query\fR - Dependency selector query .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1 index 5153e2297755d1..e0f8c8e084c297 100644 --- a/deps/npm/man/man1/npm-rebuild.1 +++ b/deps/npm/man/man1/npm-rebuild.1 @@ -1,4 +1,4 @@ -.TH "NPM-REBUILD" "1" "May 2023" "" "" +.TH "NPM-REBUILD" "1" "June 2023" "" "" .SH "NAME" \fBnpm-rebuild\fR - Rebuild a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1 index 960699c6192f36..91d81761c10586 100644 --- a/deps/npm/man/man1/npm-repo.1 +++ b/deps/npm/man/man1/npm-repo.1 @@ -1,4 +1,4 @@ -.TH "NPM-REPO" "1" "May 2023" "" "" +.TH "NPM-REPO" "1" "June 2023" "" "" .SH "NAME" \fBnpm-repo\fR - Open package repository page in the browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1 index 21ae38d01ccb97..0caa8f7eea4486 100644 --- a/deps/npm/man/man1/npm-restart.1 +++ b/deps/npm/man/man1/npm-restart.1 @@ -1,4 +1,4 @@ -.TH "NPM-RESTART" "1" "May 2023" "" "" +.TH "NPM-RESTART" "1" "June 2023" "" "" .SH "NAME" \fBnpm-restart\fR - Restart a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1 index 6a53d9e695a280..e640d17e025d2a 100644 --- a/deps/npm/man/man1/npm-root.1 +++ b/deps/npm/man/man1/npm-root.1 @@ -1,4 +1,4 @@ -.TH "NPM-ROOT" "1" "May 2023" "" "" +.TH "NPM-ROOT" "1" "June 2023" "" "" .SH "NAME" \fBnpm-root\fR - Display npm root .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-run-script.1 b/deps/npm/man/man1/npm-run-script.1 index 0838720edb31d3..cdd5e4ad7ddb4b 100644 --- a/deps/npm/man/man1/npm-run-script.1 +++ b/deps/npm/man/man1/npm-run-script.1 @@ -1,4 +1,4 @@ -.TH "NPM-RUN-SCRIPT" "1" "May 2023" "" "" +.TH "NPM-RUN-SCRIPT" "1" "June 2023" "" "" .SH "NAME" \fBnpm-run-script\fR - Run arbitrary package scripts .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index 18024e5e9cddbc..f26ddca63b832d 100644 --- a/deps/npm/man/man1/npm-search.1 +++ b/deps/npm/man/man1/npm-search.1 @@ -1,4 +1,4 @@ -.TH "NPM-SEARCH" "1" "May 2023" "" "" +.TH "NPM-SEARCH" "1" "June 2023" "" "" .SH "NAME" \fBnpm-search\fR - Search for packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index 312c444488333d..0d641645964db9 100644 --- a/deps/npm/man/man1/npm-shrinkwrap.1 +++ b/deps/npm/man/man1/npm-shrinkwrap.1 @@ -1,4 +1,4 @@ -.TH "NPM-SHRINKWRAP" "1" "May 2023" "" "" +.TH "NPM-SHRINKWRAP" "1" "June 2023" "" "" .SH "NAME" \fBnpm-shrinkwrap\fR - Lock down dependency versions for publication .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1 index f293aa8a346b9b..2bbd7b3e2de063 100644 --- a/deps/npm/man/man1/npm-star.1 +++ b/deps/npm/man/man1/npm-star.1 @@ -1,4 +1,4 @@ -.TH "NPM-STAR" "1" "May 2023" "" "" +.TH "NPM-STAR" "1" "June 2023" "" "" .SH "NAME" \fBnpm-star\fR - Mark your favorite packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1 index c7812e1e925aee..3f8721a2fcf260 100644 --- a/deps/npm/man/man1/npm-stars.1 +++ b/deps/npm/man/man1/npm-stars.1 @@ -1,4 +1,4 @@ -.TH "NPM-STARS" "1" "May 2023" "" "" +.TH "NPM-STARS" "1" "June 2023" "" "" .SH "NAME" \fBnpm-stars\fR - View packages marked as favorites .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1 index 06dbfc0142751f..27c095652c3994 100644 --- a/deps/npm/man/man1/npm-start.1 +++ b/deps/npm/man/man1/npm-start.1 @@ -1,4 +1,4 @@ -.TH "NPM-START" "1" "May 2023" "" "" +.TH "NPM-START" "1" "June 2023" "" "" .SH "NAME" \fBnpm-start\fR - Start a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1 index cdc7d807cf6508..14742a96d8a10a 100644 --- a/deps/npm/man/man1/npm-stop.1 +++ b/deps/npm/man/man1/npm-stop.1 @@ -1,4 +1,4 @@ -.TH "NPM-STOP" "1" "May 2023" "" "" +.TH "NPM-STOP" "1" "June 2023" "" "" .SH "NAME" \fBnpm-stop\fR - Stop a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-team.1 b/deps/npm/man/man1/npm-team.1 index 84b82d9a2cb92f..abed5a5d48d008 100644 --- a/deps/npm/man/man1/npm-team.1 +++ b/deps/npm/man/man1/npm-team.1 @@ -1,4 +1,4 @@ -.TH "NPM-TEAM" "1" "May 2023" "" "" +.TH "NPM-TEAM" "1" "June 2023" "" "" .SH "NAME" \fBnpm-team\fR - Manage organization teams and team memberships .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1 index 9832f0b5f01c08..7f4945ba882db3 100644 --- a/deps/npm/man/man1/npm-test.1 +++ b/deps/npm/man/man1/npm-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-TEST" "1" "May 2023" "" "" +.TH "NPM-TEST" "1" "June 2023" "" "" .SH "NAME" \fBnpm-test\fR - Test a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-token.1 b/deps/npm/man/man1/npm-token.1 index d0593123ac8437..a9aeb2f6c24f53 100644 --- a/deps/npm/man/man1/npm-token.1 +++ b/deps/npm/man/man1/npm-token.1 @@ -1,4 +1,4 @@ -.TH "NPM-TOKEN" "1" "May 2023" "" "" +.TH "NPM-TOKEN" "1" "June 2023" "" "" .SH "NAME" \fBnpm-token\fR - Manage your authentication tokens .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1 index 7e0237c768a800..b35a578da663db 100644 --- a/deps/npm/man/man1/npm-uninstall.1 +++ b/deps/npm/man/man1/npm-uninstall.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNINSTALL" "1" "May 2023" "" "" +.TH "NPM-UNINSTALL" "1" "June 2023" "" "" .SH "NAME" \fBnpm-uninstall\fR - Remove a package .SS "Synopsis" @@ -57,6 +57,25 @@ Save installed packages to a \fBpackage.json\fR file as dependencies. When used with the \fBnpm rm\fR command, removes the dependency from \fBpackage.json\fR. .P Will also prevent writing to \fBpackage-lock.json\fR if set to \fBfalse\fR. +.SS "\fBglobal\fR" +.RS 0 +.IP \(bu 4 +Default: false +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Operates in "global" mode, so that packages are installed into the \fBprefix\fR folder instead of the current working directory. See npm help folders for more on the differences in behavior. +.RS 0 +.IP \(bu 4 +packages are installed into the \fB{prefix}/lib/node_modules\fR folder, instead of the current working directory. +.IP \(bu 4 +bin files are linked to \fB{prefix}/bin\fR +.IP \(bu 4 +man pages are linked to \fB{prefix}/share/man\fR +.RE 0 + .SS "\fBworkspace\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1 index 21ac3b07226c3a..151d24baa7c8c7 100644 --- a/deps/npm/man/man1/npm-unpublish.1 +++ b/deps/npm/man/man1/npm-unpublish.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNPUBLISH" "1" "May 2023" "" "" +.TH "NPM-UNPUBLISH" "1" "June 2023" "" "" .SH "NAME" \fBnpm-unpublish\fR - Remove a package from the registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-unstar.1 b/deps/npm/man/man1/npm-unstar.1 index 70242ed19632c3..802ccf68678ed6 100644 --- a/deps/npm/man/man1/npm-unstar.1 +++ b/deps/npm/man/man1/npm-unstar.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNSTAR" "1" "May 2023" "" "" +.TH "NPM-UNSTAR" "1" "June 2023" "" "" .SH "NAME" \fBnpm-unstar\fR - Remove an item from your favorite packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1 index 82e3ff9b193d1d..787e2ee663875b 100644 --- a/deps/npm/man/man1/npm-update.1 +++ b/deps/npm/man/man1/npm-update.1 @@ -1,4 +1,4 @@ -.TH "NPM-UPDATE" "1" "May 2023" "" "" +.TH "NPM-UPDATE" "1" "June 2023" "" "" .SH "NAME" \fBnpm-update\fR - Update packages .SS "Synopsis" @@ -239,8 +239,6 @@ Type: Boolean .P If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBforeground-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index 620d6d56fe08fb..3a88228dc2f261 100644 --- a/deps/npm/man/man1/npm-version.1 +++ b/deps/npm/man/man1/npm-version.1 @@ -1,4 +1,4 @@ -.TH "NPM-VERSION" "1" "May 2023" "" "" +.TH "NPM-VERSION" "1" "June 2023" "" "" .SH "NAME" \fBnpm-version\fR - Bump a package version .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1 index 5733d82cfcfd6d..50b8dcb5e4cfbd 100644 --- a/deps/npm/man/man1/npm-view.1 +++ b/deps/npm/man/man1/npm-view.1 @@ -1,4 +1,4 @@ -.TH "NPM-VIEW" "1" "May 2023" "" "" +.TH "NPM-VIEW" "1" "June 2023" "" "" .SH "NAME" \fBnpm-view\fR - View registry info .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1 index add5aac5a2689a..7bc53ca0d7796b 100644 --- a/deps/npm/man/man1/npm-whoami.1 +++ b/deps/npm/man/man1/npm-whoami.1 @@ -1,4 +1,4 @@ -.TH "NPM-WHOAMI" "1" "May 2023" "" "" +.TH "NPM-WHOAMI" "1" "June 2023" "" "" .SH "NAME" \fBnpm-whoami\fR - Display npm username .SS "Synopsis" diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 1fcb52d7b3952b..7e6e660595d87b 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,4 +1,4 @@ -.TH "NPM" "1" "May 2023" "" "" +.TH "NPM" "1" "June 2023" "" "" .SH "NAME" \fBnpm\fR - javascript package manager .SS "Synopsis" @@ -12,7 +12,7 @@ npm Note: This command is unaware of workspaces. .SS "Version" .P -9.6.7 +9.7.1 .SS "Description" .P npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency conflicts intelligently. diff --git a/deps/npm/man/man1/npx.1 b/deps/npm/man/man1/npx.1 index c392079457ac1d..62545305dc679e 100644 --- a/deps/npm/man/man1/npx.1 +++ b/deps/npm/man/man1/npx.1 @@ -1,4 +1,4 @@ -.TH "NPX" "1" "May 2023" "" "" +.TH "NPX" "1" "June 2023" "" "" .SH "NAME" \fBnpx\fR - Run a command from a local or remote npm package .SS "Synopsis" diff --git a/deps/npm/man/man5/folders.5 b/deps/npm/man/man5/folders.5 index 934e3af20f757e..c4ddf51f87cade 100644 --- a/deps/npm/man/man5/folders.5 +++ b/deps/npm/man/man5/folders.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "May 2023" "" "" +.TH "FOLDERS" "5" "June 2023" "" "" .SH "NAME" \fBfolders\fR - Folder Structures Used by npm .SS "Description" diff --git a/deps/npm/man/man5/install.5 b/deps/npm/man/man5/install.5 index de38edb1b1b4a5..096c705950c113 100644 --- a/deps/npm/man/man5/install.5 +++ b/deps/npm/man/man5/install.5 @@ -1,4 +1,4 @@ -.TH "INSTALL" "5" "May 2023" "" "" +.TH "INSTALL" "5" "June 2023" "" "" .SH "NAME" \fBinstall\fR - Download and install node and npm .SS "Description" diff --git a/deps/npm/man/man5/npm-global.5 b/deps/npm/man/man5/npm-global.5 index 934e3af20f757e..c4ddf51f87cade 100644 --- a/deps/npm/man/man5/npm-global.5 +++ b/deps/npm/man/man5/npm-global.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "May 2023" "" "" +.TH "FOLDERS" "5" "June 2023" "" "" .SH "NAME" \fBfolders\fR - Folder Structures Used by npm .SS "Description" diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/npm-json.5 index c646afa88dfedc..36e22713c4ce82 100644 --- a/deps/npm/man/man5/npm-json.5 +++ b/deps/npm/man/man5/npm-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE.JSON" "5" "May 2023" "" "" +.TH "PACKAGE.JSON" "5" "June 2023" "" "" .SH "NAME" \fBpackage.json\fR - Specifics of npm's package.json handling .SS "Description" diff --git a/deps/npm/man/man5/npm-shrinkwrap-json.5 b/deps/npm/man/man5/npm-shrinkwrap-json.5 index f3ab3eda6aa409..3ac345a3452cc2 100644 --- a/deps/npm/man/man5/npm-shrinkwrap-json.5 +++ b/deps/npm/man/man5/npm-shrinkwrap-json.5 @@ -1,4 +1,4 @@ -.TH "NPM-SHRINKWRAP.JSON" "5" "May 2023" "" "" +.TH "NPM-SHRINKWRAP.JSON" "5" "June 2023" "" "" .SH "NAME" \fBnpm-shrinkwrap.json\fR - A publishable lockfile .SS "Description" diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5 index c04212f9e21d96..8aaab33cd74448 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,4 +1,4 @@ -.TH "NPMRC" "5" "May 2023" "" "" +.TH "NPMRC" "5" "June 2023" "" "" .SH "NAME" \fBnpmrc\fR - The npm config files .SS "Description" diff --git a/deps/npm/man/man5/package-json.5 b/deps/npm/man/man5/package-json.5 index c646afa88dfedc..36e22713c4ce82 100644 --- a/deps/npm/man/man5/package-json.5 +++ b/deps/npm/man/man5/package-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE.JSON" "5" "May 2023" "" "" +.TH "PACKAGE.JSON" "5" "June 2023" "" "" .SH "NAME" \fBpackage.json\fR - Specifics of npm's package.json handling .SS "Description" diff --git a/deps/npm/man/man5/package-lock-json.5 b/deps/npm/man/man5/package-lock-json.5 index 0f529dc9bbc4ae..ceac876f546a5b 100644 --- a/deps/npm/man/man5/package-lock-json.5 +++ b/deps/npm/man/man5/package-lock-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE-LOCK.JSON" "5" "May 2023" "" "" +.TH "PACKAGE-LOCK.JSON" "5" "June 2023" "" "" .SH "NAME" \fBpackage-lock.json\fR - A manifestation of the manifest .SS "Description" diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7 index e20d300946a863..cec41d8d3f4b87 100644 --- a/deps/npm/man/man7/config.7 +++ b/deps/npm/man/man7/config.7 @@ -1,4 +1,4 @@ -.TH "CONFIG" "7" "May 2023" "" "" +.TH "CONFIG" "7" "June 2023" "" "" .SH "NAME" \fBconfig\fR - More than you probably want to know about npm configuration .SS "Description" @@ -1080,8 +1080,6 @@ Type: Boolean .P If set to false, then ignore \fBpackage-lock.json\fR files when installing. This will also prevent \fIwriting\fR \fBpackage-lock.json\fR if \fBsave\fR is true. -.P -This configuration does not affect \fBnpm ci\fR. .SS "\fBpackage-lock-only\fR" .RS 0 .IP \(bu 4 @@ -1106,6 +1104,16 @@ Type: Boolean .P Output parseable results from commands that write to standard output. For \fBnpm search\fR, this will be tab-separated table format. +.SS "\fBprefer-dedupe\fR" +.RS 0 +.IP \(bu 4 +Default: false +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Prefer to deduplicate packages if possible, rather than choosing a newer version of a dependency. .SS "\fBprefer-offline\fR" .RS 0 .IP \(bu 4 @@ -1168,6 +1176,20 @@ Type: Boolean .P When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from. +.P +This config can not be used with: \fBprovenance-file\fR +.SS "\fBprovenance-file\fR" +.RS 0 +.IP \(bu 4 +Default: null +.IP \(bu 4 +Type: Path +.RE 0 + +.P +When publishing, the provenance bundle at the given path will be used. +.P +This config can not be used with: \fBprovenance\fR .SS "\fBproxy\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man7/dependency-selectors.7 b/deps/npm/man/man7/dependency-selectors.7 index d84c647c93038f..74767ecff53496 100644 --- a/deps/npm/man/man7/dependency-selectors.7 +++ b/deps/npm/man/man7/dependency-selectors.7 @@ -1,4 +1,4 @@ -.TH "QUERYING" "7" "May 2023" "" "" +.TH "QUERYING" "7" "June 2023" "" "" .SH "NAME" \fBQuerying\fR - Dependency Selector Syntax & Querying .SS "Description" diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7 index 9d1c568bd7c437..30c2c60da44c93 100644 --- a/deps/npm/man/man7/developers.7 +++ b/deps/npm/man/man7/developers.7 @@ -1,4 +1,4 @@ -.TH "DEVELOPERS" "7" "May 2023" "" "" +.TH "DEVELOPERS" "7" "June 2023" "" "" .SH "NAME" \fBdevelopers\fR - Developer Guide .SS "Description" diff --git a/deps/npm/man/man7/logging.7 b/deps/npm/man/man7/logging.7 index f8f0e9a9e0d8ef..62ae6b1a5b1076 100644 --- a/deps/npm/man/man7/logging.7 +++ b/deps/npm/man/man7/logging.7 @@ -1,4 +1,4 @@ -.TH "LOGGING" "7" "May 2023" "" "" +.TH "LOGGING" "7" "June 2023" "" "" .SH "NAME" \fBLogging\fR - Why, What & How We Log .SS "Description" diff --git a/deps/npm/man/man7/orgs.7 b/deps/npm/man/man7/orgs.7 index 7e67161fb6830d..6ebfc55f1526f0 100644 --- a/deps/npm/man/man7/orgs.7 +++ b/deps/npm/man/man7/orgs.7 @@ -1,4 +1,4 @@ -.TH "ORGS" "7" "May 2023" "" "" +.TH "ORGS" "7" "June 2023" "" "" .SH "NAME" \fBorgs\fR - Working with Teams & Orgs .SS "Description" diff --git a/deps/npm/man/man7/package-spec.7 b/deps/npm/man/man7/package-spec.7 index 21342529c51c1a..0e3ff55c217d5f 100644 --- a/deps/npm/man/man7/package-spec.7 +++ b/deps/npm/man/man7/package-spec.7 @@ -1,4 +1,4 @@ -.TH "PACKAGE-SPEC" "7" "May 2023" "" "" +.TH "PACKAGE-SPEC" "7" "June 2023" "" "" .SH "NAME" \fBpackage-spec\fR - Package name specifier .SS "Description" diff --git a/deps/npm/man/man7/registry.7 b/deps/npm/man/man7/registry.7 index b27bdd40295099..db66480d4465d8 100644 --- a/deps/npm/man/man7/registry.7 +++ b/deps/npm/man/man7/registry.7 @@ -1,4 +1,4 @@ -.TH "REGISTRY" "7" "May 2023" "" "" +.TH "REGISTRY" "7" "June 2023" "" "" .SH "NAME" \fBregistry\fR - The JavaScript Package Registry .SS "Description" diff --git a/deps/npm/man/man7/removal.7 b/deps/npm/man/man7/removal.7 index 1f9dfcf016aea4..dfd9542fb278c8 100644 --- a/deps/npm/man/man7/removal.7 +++ b/deps/npm/man/man7/removal.7 @@ -1,4 +1,4 @@ -.TH "REMOVAL" "7" "May 2023" "" "" +.TH "REMOVAL" "7" "June 2023" "" "" .SH "NAME" \fBremoval\fR - Cleaning the Slate .SS "Synopsis" diff --git a/deps/npm/man/man7/scope.7 b/deps/npm/man/man7/scope.7 index 00f2240aedd385..ac9cd5f29ee605 100644 --- a/deps/npm/man/man7/scope.7 +++ b/deps/npm/man/man7/scope.7 @@ -1,4 +1,4 @@ -.TH "SCOPE" "7" "May 2023" "" "" +.TH "SCOPE" "7" "June 2023" "" "" .SH "NAME" \fBscope\fR - Scoped packages .SS "Description" diff --git a/deps/npm/man/man7/scripts.7 b/deps/npm/man/man7/scripts.7 index 00ae221f4b0901..72012d4dcd48d2 100644 --- a/deps/npm/man/man7/scripts.7 +++ b/deps/npm/man/man7/scripts.7 @@ -1,4 +1,4 @@ -.TH "SCRIPTS" "7" "May 2023" "" "" +.TH "SCRIPTS" "7" "June 2023" "" "" .SH "NAME" \fBscripts\fR - How npm handles the "scripts" field .SS "Description" diff --git a/deps/npm/man/man7/workspaces.7 b/deps/npm/man/man7/workspaces.7 index 896e40c294c367..68dca1c75aa14b 100644 --- a/deps/npm/man/man7/workspaces.7 +++ b/deps/npm/man/man7/workspaces.7 @@ -1,4 +1,4 @@ -.TH "WORKSPACES" "7" "May 2023" "" "" +.TH "WORKSPACES" "7" "June 2023" "" "" .SH "NAME" \fBworkspaces\fR - Working with workspaces .SS "Description" diff --git a/deps/npm/node_modules/@npmcli/arborist/package.json b/deps/npm/node_modules/@npmcli/arborist/package.json index bba6a2e9e5c85c..ec98a3c6a69394 100644 --- a/deps/npm/node_modules/@npmcli/arborist/package.json +++ b/deps/npm/node_modules/@npmcli/arborist/package.json @@ -41,7 +41,6 @@ "@npmcli/eslint-config": "^4.0.0", "@npmcli/template-oss": "4.14.1", "benchmark": "^2.1.4", - "chalk": "^4.1.0", "minify-registry-metadata": "^3.0.0", "nock": "^13.3.0", "tap": "^16.3.4", diff --git a/deps/npm/node_modules/@npmcli/config/lib/index.js b/deps/npm/node_modules/@npmcli/config/lib/index.js index b7b848dea151c8..84a009851d8a2e 100644 --- a/deps/npm/node_modules/@npmcli/config/lib/index.js +++ b/deps/npm/node_modules/@npmcli/config/lib/index.js @@ -575,6 +575,13 @@ class Config { const v = this.parseField(value, k) if (where !== 'default') { this.#checkDeprecated(k, where, obj, [key, value]) + if (this.definitions[key]?.exclusive) { + for (const exclusive of this.definitions[key].exclusive) { + if (!this.isDefault(exclusive)) { + throw new TypeError(`--${key} can not be provided when using --${exclusive}`) + } + } + } } conf.data[k] = v } diff --git a/deps/npm/node_modules/@npmcli/config/package.json b/deps/npm/node_modules/@npmcli/config/package.json index e68d5166901451..e0190fc3ac53f6 100644 --- a/deps/npm/node_modules/@npmcli/config/package.json +++ b/deps/npm/node_modules/@npmcli/config/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/config", - "version": "6.1.7", + "version": "6.2.0", "files": [ "bin/", "lib/" diff --git a/deps/npm/node_modules/@npmcli/git/lib/find.js b/deps/npm/node_modules/@npmcli/git/lib/find.js index d58f01dbcc16ff..34bd310b88e5d5 100644 --- a/deps/npm/node_modules/@npmcli/git/lib/find.js +++ b/deps/npm/node_modules/@npmcli/git/lib/find.js @@ -1,15 +1,15 @@ const is = require('./is.js') const { dirname } = require('path') -module.exports = async ({ cwd = process.cwd() } = {}) => { - if (await is({ cwd })) { - return cwd - } - while (cwd !== dirname(cwd)) { - cwd = dirname(cwd) +module.exports = async ({ cwd = process.cwd(), root } = {}) => { + while (true) { if (await is({ cwd })) { return cwd } + const next = dirname(cwd) + if (cwd === root || cwd === next) { + return null + } + cwd = next } - return null } diff --git a/deps/npm/node_modules/@npmcli/git/package.json b/deps/npm/node_modules/@npmcli/git/package.json index 41c78dddfa3ccc..eeba1c0415788c 100644 --- a/deps/npm/node_modules/@npmcli/git/package.json +++ b/deps/npm/node_modules/@npmcli/git/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/git", - "version": "4.0.4", + "version": "4.1.0", "main": "lib/index.js", "files": [ "bin/", @@ -23,8 +23,7 @@ "template-oss-apply": "template-oss-apply --force" }, "tap": { - "check-coverage": true, - "coverage-map": "map.js", + "timeout": 600, "nyc-arg": [ "--exclude", "tap-snapshots/**" @@ -32,7 +31,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.12.0", + "@npmcli/template-oss": "4.15.1", "npm-package-arg": "^10.0.0", "slash": "^3.0.0", "tap": "^16.0.1" @@ -52,7 +51,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "windowsCI": false, - "version": "4.12.0" + "version": "4.15.1", + "publish": true } } diff --git a/deps/npm/node_modules/@npmcli/package-json/lib/index.js b/deps/npm/node_modules/@npmcli/package-json/lib/index.js index 34e415b45d49fe..756837cdde58a0 100644 --- a/deps/npm/node_modules/@npmcli/package-json/lib/index.js +++ b/deps/npm/node_modules/@npmcli/package-json/lib/index.js @@ -38,6 +38,7 @@ class PackageJson { '_attributes', 'bundledDependencies', 'bundleDependencies', + 'bundleDependenciesDeleteFalse', 'gypfile', 'serverjs', 'scriptpath', diff --git a/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js b/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js index bc101cd4fde1b0..9594ef3d7ff4ff 100644 --- a/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js +++ b/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js @@ -3,10 +3,13 @@ const { glob } = require('glob') const normalizePackageBin = require('npm-normalize-package-bin') const normalizePackageData = require('normalize-package-data') const path = require('path') +const log = require('proc-log') +const git = require('@npmcli/git') -const normalize = async (pkg, { strict, steps }) => { +const normalize = async (pkg, { strict, steps, root }) => { const data = pkg.content const scripts = data.scripts || {} + const pkgId = `${data.name ?? ''}@${data.version ?? ''}` // remove attributes that start with "_" if (steps.includes('_attributes')) { @@ -20,7 +23,7 @@ const normalize = async (pkg, { strict, steps }) => { // build the "_id" attribute if (steps.includes('_id')) { if (data.name && data.version) { - data._id = `${data.name}@${data.version}` + data._id = pkgId } } @@ -34,7 +37,9 @@ const normalize = async (pkg, { strict, steps }) => { // expand "bundleDependencies: true or translate from object" if (steps.includes('bundleDependencies')) { const bd = data.bundleDependencies - if (bd === true) { + if (bd === false && !steps.includes('bundleDependenciesDeleteFalse')) { + data.bundleDependencies = [] + } else if (bd === true) { data.bundleDependencies = Object.keys(data.dependencies || {}) } else if (bd && typeof bd === 'object') { if (!Array.isArray(bd)) { @@ -158,7 +163,7 @@ const normalize = async (pkg, { strict, steps }) => { } // expand "directories.bin" - if (steps.includes('binDir') && data.directories?.bin) { + if (steps.includes('binDir') && data.directories?.bin && !data.bin) { const binsDir = path.resolve(pkg.path, path.join('.', path.join('/', data.directories.bin))) const bins = await glob('**', { cwd: binsDir }) data.bin = bins.reduce((acc, binFile) => { @@ -174,17 +179,20 @@ const normalize = async (pkg, { strict, steps }) => { // populate "gitHead" attribute if (steps.includes('gitHead') && !data.gitHead) { + const gitRoot = await git.find({ cwd: pkg.path, root }) let head - try { - head = await fs.readFile(path.resolve(pkg.path, '.git/HEAD'), 'utf8') - } catch (err) { + if (gitRoot) { + try { + head = await fs.readFile(path.resolve(gitRoot, '.git/HEAD'), 'utf8') + } catch (err) { // do nothing + } } let headData if (head) { if (head.startsWith('ref: ')) { const headRef = head.replace(/^ref: /, '').trim() - const headFile = path.resolve(pkg.path, '.git', headRef) + const headFile = path.resolve(gitRoot, '.git', headRef) try { headData = await fs.readFile(headFile, 'utf8') headData = headData.replace(/^ref: /, '').trim() @@ -192,7 +200,7 @@ const normalize = async (pkg, { strict, steps }) => { // do nothing } if (!headData) { - const packFile = path.resolve(pkg.path, '.git/packed-refs') + const packFile = path.resolve(gitRoot, '.git/packed-refs') try { let refs = await fs.readFile(packFile, 'utf8') if (refs) { @@ -271,11 +279,11 @@ const normalize = async (pkg, { strict, steps }) => { // in normalize-package-data if it had access to the file path. if (steps.includes('binRefs') && data.bin instanceof Object) { for (const key in data.bin) { - const binPath = path.resolve(pkg.path, data.bin[key]) try { - await fs.access(binPath) + await fs.access(path.resolve(pkg.path, data.bin[key])) } catch { - delete data.bin[key] + log.warn('package-json', pkgId, `No bin file found at ${data.bin[key]}`) + // XXX: should a future breaking change delete bin entries that cannot be accessed? } } } diff --git a/deps/npm/node_modules/@npmcli/package-json/package.json b/deps/npm/node_modules/@npmcli/package-json/package.json index 61607c5bb6ae70..a4e2cbab4c0bdd 100644 --- a/deps/npm/node_modules/@npmcli/package-json/package.json +++ b/deps/npm/node_modules/@npmcli/package-json/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/package-json", - "version": "3.1.0", + "version": "3.1.1", "description": "Programmatic API to update package.json", "main": "lib/index.js", "files": [ @@ -26,13 +26,17 @@ "devDependencies": { "@npmcli/eslint-config": "^4.0.0", "@npmcli/template-oss": "4.15.1", + "read-package-json": "^6.0.4", + "read-package-json-fast": "^3.0.2", "tap": "^16.0.1" }, "dependencies": { + "@npmcli/git": "^4.1.0", "glob": "^10.2.2", "json-parse-even-better-errors": "^3.0.0", "normalize-package-data": "^5.0.0", - "npm-normalize-package-bin": "^3.0.1" + "npm-normalize-package-bin": "^3.0.1", + "proc-log": "^3.0.0" }, "repository": { "type": "git", diff --git a/deps/npm/node_modules/chalk/license b/deps/npm/node_modules/chalk/license index e7af2f77107d73..fa7ceba3eb4a96 100644 --- a/deps/npm/node_modules/chalk/license +++ b/deps/npm/node_modules/chalk/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus (sindresorhus.com) +Copyright (c) Sindre Sorhus (https://sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/deps/npm/node_modules/chalk/package.json b/deps/npm/node_modules/chalk/package.json index 47c23f29068caa..ddcf7589e9797d 100644 --- a/deps/npm/node_modules/chalk/package.json +++ b/deps/npm/node_modules/chalk/package.json @@ -1,21 +1,31 @@ { "name": "chalk", - "version": "4.1.2", + "version": "5.2.0", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", "funding": "https://github.com/chalk/chalk?sponsor=1", - "main": "source", + "type": "module", + "main": "./source/index.js", + "exports": "./source/index.js", + "imports": { + "#ansi-styles": "./source/vendor/ansi-styles/index.js", + "#supports-color": { + "node": "./source/vendor/supports-color/index.js", + "default": "./source/vendor/supports-color/browser.js" + } + }, + "types": "./source/index.d.ts", "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "scripts": { - "test": "xo && nyc ava && tsd", + "test": "xo && c8 ava && tsd", "bench": "matcha benchmark.js" }, "files": [ "source", - "index.d.ts" + "!source/index.test-d.ts" ], "keywords": [ "color", @@ -25,7 +35,6 @@ "console", "cli", "string", - "str", "ansi", "style", "styles", @@ -40,29 +49,33 @@ "command-line", "text" ], - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "devDependencies": { - "ava": "^2.4.0", - "coveralls": "^3.0.7", - "execa": "^4.0.0", - "import-fresh": "^3.1.0", + "@types/node": "^16.11.10", + "ava": "^3.15.0", + "c8": "^7.10.0", + "color-convert": "^2.0.1", + "execa": "^6.0.0", + "log-update": "^5.0.0", "matcha": "^0.7.0", - "nyc": "^15.0.0", - "resolve-from": "^5.0.0", - "tsd": "^0.7.4", - "xo": "^0.28.2" + "tsd": "^0.19.0", + "xo": "^0.53.0", + "yoctodelay": "^2.0.0" }, "xo": { "rules": { "unicorn/prefer-string-slice": "off", - "unicorn/prefer-includes": "off", - "@typescript-eslint/member-ordering": "off", - "no-redeclare": "off", - "unicorn/string-content": "off", - "unicorn/better-regex": "off" + "@typescript-eslint/consistent-type-imports": "off", + "@typescript-eslint/consistent-type-exports": "off", + "@typescript-eslint/consistent-type-definitions": "off" } + }, + "c8": { + "reporter": [ + "text", + "lcov" + ], + "exclude": [ + "source/vendor" + ] } } diff --git a/deps/npm/node_modules/chalk/source/index.js b/deps/npm/node_modules/chalk/source/index.js index 75ec66350527a8..8bc993da5d6229 100644 --- a/deps/npm/node_modules/chalk/source/index.js +++ b/deps/npm/node_modules/chalk/source/index.js @@ -1,19 +1,22 @@ -'use strict'; -const ansiStyles = require('ansi-styles'); -const {stdout: stdoutColor, stderr: stderrColor} = require('supports-color'); -const { +import ansiStyles from '#ansi-styles'; +import supportsColor from '#supports-color'; +import { // eslint-disable-line import/order stringReplaceAll, - stringEncaseCRLFWithFirstIndex -} = require('./util'); + stringEncaseCRLFWithFirstIndex, +} from './utilities.js'; -const {isArray} = Array; +const {stdout: stdoutColor, stderr: stderrColor} = supportsColor; + +const GENERATOR = Symbol('GENERATOR'); +const STYLER = Symbol('STYLER'); +const IS_EMPTY = Symbol('IS_EMPTY'); // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ 'ansi', 'ansi', 'ansi256', - 'ansi16m' + 'ansi16m', ]; const styles = Object.create(null); @@ -28,7 +31,7 @@ const applyOptions = (object, options = {}) => { object.level = options.level === undefined ? colorLevel : options.level; }; -class ChalkClass { +export class Chalk { constructor(options) { // eslint-disable-next-line no-constructor-return return chalkFactory(options); @@ -36,69 +39,80 @@ class ChalkClass { } const chalkFactory = options => { - const chalk = {}; + const chalk = (...strings) => strings.join(' '); applyOptions(chalk, options); - chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = () => { - throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); - }; - - chalk.template.Instance = ChalkClass; + Object.setPrototypeOf(chalk, createChalk.prototype); - return chalk.template; + return chalk; }; -function Chalk(options) { +function createChalk(options) { return chalkFactory(options); } +Object.setPrototypeOf(createChalk.prototype, Function.prototype); + for (const [styleName, style] of Object.entries(ansiStyles)) { styles[styleName] = { get() { - const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]); Object.defineProperty(this, styleName, {value: builder}); return builder; - } + }, }; } styles.visible = { get() { - const builder = createBuilder(this, this._styler, true); + const builder = createBuilder(this, this[STYLER], true); Object.defineProperty(this, 'visible', {value: builder}); return builder; + }, +}; + +const getModelAnsi = (model, level, type, ...arguments_) => { + if (model === 'rgb') { + if (level === 'ansi16m') { + return ansiStyles[type].ansi16m(...arguments_); + } + + if (level === 'ansi256') { + return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_)); + } + + return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_)); } + + if (model === 'hex') { + return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_)); + } + + return ansiStyles[type][model](...arguments_); }; -const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; +const usedModels = ['rgb', 'hex', 'ansi256']; for (const model of usedModels) { styles[model] = { get() { const {level} = this; return function (...arguments_) { - const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); - return createBuilder(this, styler, this._isEmpty); + const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]); + return createBuilder(this, styler, this[IS_EMPTY]); }; - } + }, }; -} -for (const model of usedModels) { const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); styles[bgModel] = { get() { const {level} = this; return function (...arguments_) { - const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); - return createBuilder(this, styler, this._isEmpty); + const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]); + return createBuilder(this, styler, this[IS_EMPTY]); }; - } + }, }; } @@ -107,12 +121,12 @@ const proto = Object.defineProperties(() => {}, { level: { enumerable: true, get() { - return this._generator.level; + return this[GENERATOR].level; }, set(level) { - this._generator.level = level; - } - } + this[GENERATOR].level = level; + }, + }, }); const createStyler = (open, close, parent) => { @@ -131,46 +145,39 @@ const createStyler = (open, close, parent) => { close, openAll, closeAll, - parent + parent, }; }; const createBuilder = (self, _styler, _isEmpty) => { - const builder = (...arguments_) => { - if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { - // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` - return applyStyle(builder, chalkTag(builder, ...arguments_)); - } - - // Single argument is hot path, implicit coercion is faster than anything - // eslint-disable-next-line no-implicit-coercion - return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); - }; + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); // We alter the prototype because we must return a function, but there is // no way to create a function with a different prototype Object.setPrototypeOf(builder, proto); - builder._generator = self; - builder._styler = _styler; - builder._isEmpty = _isEmpty; + builder[GENERATOR] = self; + builder[STYLER] = _styler; + builder[IS_EMPTY] = _isEmpty; return builder; }; const applyStyle = (self, string) => { if (self.level <= 0 || !string) { - return self._isEmpty ? '' : string; + return self[IS_EMPTY] ? '' : string; } - let styler = self._styler; + let styler = self[STYLER]; if (styler === undefined) { return string; } const {openAll, closeAll} = styler; - if (string.indexOf('\u001B') !== -1) { + if (string.includes('\u001B')) { while (styler !== undefined) { // Replace any instances already present with a re-opening code // otherwise only the part of the string until said closing code @@ -192,38 +199,27 @@ const applyStyle = (self, string) => { return openAll + string + closeAll; }; -let template; -const chalkTag = (chalk, ...strings) => { - const [firstString] = strings; - - if (!isArray(firstString) || !isArray(firstString.raw)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return strings.join(' '); - } +Object.defineProperties(createChalk.prototype, styles); - const arguments_ = strings.slice(1); - const parts = [firstString.raw[0]]; +const chalk = createChalk(); +export const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0}); - for (let i = 1; i < firstString.length; i++) { - parts.push( - String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), - String(firstString.raw[i]) - ); - } +export { + modifierNames, + foregroundColorNames, + backgroundColorNames, + colorNames, - if (template === undefined) { - template = require('./templates'); - } + // TODO: Remove these aliases in the next major version + modifierNames as modifiers, + foregroundColorNames as foregroundColors, + backgroundColorNames as backgroundColors, + colorNames as colors, +} from './vendor/ansi-styles/index.js'; - return template(chalk, parts.join('')); +export { + stdoutColor as supportsColor, + stderrColor as supportsColorStderr, }; -Object.defineProperties(Chalk.prototype, styles); - -const chalk = Chalk(); // eslint-disable-line new-cap -chalk.supportsColor = stdoutColor; -chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap -chalk.stderr.supportsColor = stderrColor; - -module.exports = chalk; +export default chalk; diff --git a/deps/npm/node_modules/chalk/source/templates.js b/deps/npm/node_modules/chalk/source/templates.js deleted file mode 100644 index b130949d646fda..00000000000000 --- a/deps/npm/node_modules/chalk/source/templates.js +++ /dev/null @@ -1,134 +0,0 @@ -'use strict'; -const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape(c) { - const u = c[0] === 'u'; - const bracket = c[1] === '{'; - - if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - if (u && bracket) { - return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); - } - - return ESCAPES.get(c) || c; -} - -function parseArguments(name, arguments_) { - const results = []; - const chunks = arguments_.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - const number = Number(chunk); - if (!Number.isNaN(number)) { - results.push(number); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; -} - -function buildStyle(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const [styleName, styles] of Object.entries(enabled)) { - if (!Array.isArray(styles)) { - continue; - } - - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; - } - - return current; -} - -module.exports = (chalk, temporary) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { - if (escapeCharacter) { - chunk.push(unescape(escapeCharacter)); - } else if (style) { - const string = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(character); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); - } - - return chunks.join(''); -}; diff --git a/deps/npm/node_modules/chalk/source/util.js b/deps/npm/node_modules/chalk/source/util.js deleted file mode 100644 index ca466fd466c07f..00000000000000 --- a/deps/npm/node_modules/chalk/source/util.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -const stringReplaceAll = (string, substring, replacer) => { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } - - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ''; - do { - returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring, endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { - let endIndex = 0; - let returnValue = ''; - do { - const gotCR = string[index - 1] === '\r'; - returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - endIndex = index + 1; - index = string.indexOf('\n', endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -module.exports = { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -}; diff --git a/deps/npm/node_modules/chalk/source/utilities.js b/deps/npm/node_modules/chalk/source/utilities.js new file mode 100644 index 00000000000000..4366dee0d84d72 --- /dev/null +++ b/deps/npm/node_modules/chalk/source/utilities.js @@ -0,0 +1,33 @@ +// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`. +export function stringReplaceAll(string, substring, replacer) { + let index = string.indexOf(substring); + if (index === -1) { + return string; + } + + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ''; + do { + returnValue += string.slice(endIndex, index) + substring + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring, endIndex); + } while (index !== -1); + + returnValue += string.slice(endIndex); + return returnValue; +} + +export function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) { + let endIndex = 0; + let returnValue = ''; + do { + const gotCR = string[index - 1] === '\r'; + returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + endIndex = index + 1; + index = string.indexOf('\n', endIndex); + } while (index !== -1); + + returnValue += string.slice(endIndex); + return returnValue; +} diff --git a/deps/npm/node_modules/chalk/source/vendor/ansi-styles/index.js b/deps/npm/node_modules/chalk/source/vendor/ansi-styles/index.js new file mode 100644 index 00000000000000..eaa7bed6cb1ed9 --- /dev/null +++ b/deps/npm/node_modules/chalk/source/vendor/ansi-styles/index.js @@ -0,0 +1,223 @@ +const ANSI_BACKGROUND_OFFSET = 10; + +const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`; + +const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`; + +const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`; + +const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + overline: [53, 55], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + + // Bright color + blackBright: [90, 39], + gray: [90, 39], // Alias of `blackBright` + grey: [90, 39], // Alias of `blackBright` + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39], + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + + // Bright color + bgBlackBright: [100, 49], + bgGray: [100, 49], // Alias of `bgBlackBright` + bgGrey: [100, 49], // Alias of `bgBlackBright` + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49], + }, +}; + +export const modifierNames = Object.keys(styles.modifier); +export const foregroundColorNames = Object.keys(styles.color); +export const backgroundColorNames = Object.keys(styles.bgColor); +export const colorNames = [...foregroundColorNames, ...backgroundColorNames]; + +function assembleStyles() { + const codes = new Map(); + + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m`, + }; + + group[styleName] = styles[styleName]; + + codes.set(style[0], style[1]); + } + + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false, + }); + } + + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false, + }); + + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; + + styles.color.ansi = wrapAnsi16(); + styles.color.ansi256 = wrapAnsi256(); + styles.color.ansi16m = wrapAnsi16m(); + styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); + styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); + styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); + + // From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js + Object.defineProperties(styles, { + rgbToAnsi256: { + value(red, green, blue) { + // We use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (red === green && green === blue) { + if (red < 8) { + return 16; + } + + if (red > 248) { + return 231; + } + + return Math.round(((red - 8) / 247) * 24) + 232; + } + + return 16 + + (36 * Math.round(red / 255 * 5)) + + (6 * Math.round(green / 255 * 5)) + + Math.round(blue / 255 * 5); + }, + enumerable: false, + }, + hexToRgb: { + value(hex) { + const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16)); + if (!matches) { + return [0, 0, 0]; + } + + let [colorString] = matches; + + if (colorString.length === 3) { + colorString = [...colorString].map(character => character + character).join(''); + } + + const integer = Number.parseInt(colorString, 16); + + return [ + /* eslint-disable no-bitwise */ + (integer >> 16) & 0xFF, + (integer >> 8) & 0xFF, + integer & 0xFF, + /* eslint-enable no-bitwise */ + ]; + }, + enumerable: false, + }, + hexToAnsi256: { + value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)), + enumerable: false, + }, + ansi256ToAnsi: { + value(code) { + if (code < 8) { + return 30 + code; + } + + if (code < 16) { + return 90 + (code - 8); + } + + let red; + let green; + let blue; + + if (code >= 232) { + red = (((code - 232) * 10) + 8) / 255; + green = red; + blue = red; + } else { + code -= 16; + + const remainder = code % 36; + + red = Math.floor(code / 36) / 5; + green = Math.floor(remainder / 6) / 5; + blue = (remainder % 6) / 5; + } + + const value = Math.max(red, green, blue) * 2; + + if (value === 0) { + return 30; + } + + // eslint-disable-next-line no-bitwise + let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red)); + + if (value === 2) { + result += 60; + } + + return result; + }, + enumerable: false, + }, + rgbToAnsi: { + value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)), + enumerable: false, + }, + hexToAnsi: { + value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), + enumerable: false, + }, + }); + + return styles; +} + +const ansiStyles = assembleStyles(); + +export default ansiStyles; diff --git a/deps/npm/node_modules/chalk/source/vendor/supports-color/browser.js b/deps/npm/node_modules/chalk/source/vendor/supports-color/browser.js new file mode 100644 index 00000000000000..9fa6888f10288e --- /dev/null +++ b/deps/npm/node_modules/chalk/source/vendor/supports-color/browser.js @@ -0,0 +1,30 @@ +/* eslint-env browser */ + +const level = (() => { + if (navigator.userAgentData) { + const brand = navigator.userAgentData.brands.find(({brand}) => brand === 'Chromium'); + if (brand && brand.version > 93) { + return 3; + } + } + + if (/\b(Chrome|Chromium)\//.test(navigator.userAgent)) { + return 1; + } + + return 0; +})(); + +const colorSupport = level !== 0 && { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3, +}; + +const supportsColor = { + stdout: colorSupport, + stderr: colorSupport, +}; + +export default supportsColor; diff --git a/deps/npm/node_modules/chalk/source/vendor/supports-color/index.js b/deps/npm/node_modules/chalk/source/vendor/supports-color/index.js new file mode 100644 index 00000000000000..a7cea61e9eb5fd --- /dev/null +++ b/deps/npm/node_modules/chalk/source/vendor/supports-color/index.js @@ -0,0 +1,181 @@ +import process from 'node:process'; +import os from 'node:os'; +import tty from 'node:tty'; + +// From: https://github.com/sindresorhus/has-flag/blob/main/index.js +function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) { + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +} + +const {env} = process; + +let flagForceColor; +if ( + hasFlag('no-color') + || hasFlag('no-colors') + || hasFlag('color=false') + || hasFlag('color=never') +) { + flagForceColor = 0; +} else if ( + hasFlag('color') + || hasFlag('colors') + || hasFlag('color=true') + || hasFlag('color=always') +) { + flagForceColor = 1; +} + +function envForceColor() { + if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === 'true') { + return 1; + } + + if (env.FORCE_COLOR === 'false') { + return 0; + } + + return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + } +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3, + }; +} + +function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { + const noFlagForceColor = envForceColor(); + if (noFlagForceColor !== undefined) { + flagForceColor = noFlagForceColor; + } + + const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; + + if (forceColor === 0) { + return 0; + } + + if (sniffFlags) { + if (hasFlag('color=16m') + || hasFlag('color=full') + || hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + } + + // Check for Azure DevOps pipelines. + // Has to be above the `!streamIsTTY` check. + if ('TF_BUILD' in env && 'AGENT_NAME' in env) { + return 1; + } + + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } + + const min = forceColor || 0; + + if (env.TERM === 'dumb') { + return min; + } + + if (process.platform === 'win32') { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(osRelease[0]) >= 10 + && Number(osRelease[2]) >= 10_586 + ) { + return Number(osRelease[2]) >= 14_931 ? 3 : 2; + } + + return 1; + } + + if ('CI' in env) { + if ('GITHUB_ACTIONS' in env) { + return 3; + } + + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + + return min; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if (env.TERM === 'xterm-kitty') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': { + return version >= 3 ? 3 : 2; + } + + case 'Apple_Terminal': { + return 2; + } + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + return min; +} + +export function createSupportsColor(stream, options = {}) { + const level = _supportsColor(stream, { + streamIsTTY: stream && stream.isTTY, + ...options, + }); + + return translateLevel(level); +} + +const supportsColor = { + stdout: createSupportsColor({isTTY: tty.isatty(1)}), + stderr: createSupportsColor({isTTY: tty.isatty(2)}), +}; + +export default supportsColor; diff --git a/deps/npm/node_modules/has-flag/index.js b/deps/npm/node_modules/has-flag/index.js deleted file mode 100644 index b6f80b1f8ffd76..00000000000000 --- a/deps/npm/node_modules/has-flag/index.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -module.exports = (flag, argv = process.argv) => { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -}; diff --git a/deps/npm/node_modules/has-flag/license b/deps/npm/node_modules/has-flag/license deleted file mode 100644 index e7af2f77107d73..00000000000000 --- a/deps/npm/node_modules/has-flag/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/has-flag/package.json b/deps/npm/node_modules/has-flag/package.json deleted file mode 100644 index a9cba4b856d046..00000000000000 --- a/deps/npm/node_modules/has-flag/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "has-flag", - "version": "4.0.0", - "description": "Check if argv has a specific flag", - "license": "MIT", - "repository": "sindresorhus/has-flag", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "has", - "check", - "detect", - "contains", - "find", - "flag", - "cli", - "command-line", - "argv", - "process", - "arg", - "args", - "argument", - "arguments", - "getopt", - "minimist", - "optimist" - ], - "devDependencies": { - "ava": "^1.4.1", - "tsd": "^0.7.2", - "xo": "^0.24.0" - } -} diff --git a/deps/npm/node_modules/libnpmexec/README.md b/deps/npm/node_modules/libnpmexec/README.md index dc79d12cffc456..fb4a1e32b18df7 100644 --- a/deps/npm/node_modules/libnpmexec/README.md +++ b/deps/npm/node_modules/libnpmexec/README.md @@ -31,7 +31,7 @@ await libexec({ - `call`: An alternative command to run when using `packages` option **String**, defaults to empty string. - `cache`: The path location to where the npm cache folder is placed **String** - `npxCache`: The path location to where the npx cache folder is placed **String** - - `color`: Output should use color? **Boolean**, defaults to `false` + - `chalk`: Chalk instance to use for colors? **Required** - `localBin`: Location to the `node_modules/.bin` folder of the local project to start scanning for bin files **String**, defaults to `./node_modules/.bin`. **libexec** will walk up the directory structure looking for `node_modules/.bin` folders in parent folders that might satisfy the current `arg` and will use that bin if found. - `locationMsg`: Overrides "at location" message when entering interactive mode **String** - `globalBin`: Location to the global space bin folder, same as: `$(npm bin -g)` **String**, defaults to empty string. diff --git a/deps/npm/node_modules/libnpmexec/lib/run-script.js b/deps/npm/node_modules/libnpmexec/lib/run-script.js index ba60395468d626..89dcf2e653036e 100644 --- a/deps/npm/node_modules/libnpmexec/lib/run-script.js +++ b/deps/npm/node_modules/libnpmexec/lib/run-script.js @@ -1,4 +1,3 @@ -const chalk = require('chalk') const ciInfo = require('ci-info') const runScript = require('@npmcli/run-script') const readPackageJson = require('read-package-json-fast') @@ -6,12 +5,6 @@ const npmlog = require('npmlog') const log = require('proc-log') const noTTY = require('./no-tty.js') -const nocolor = { - reset: s => s, - bold: s => s, - dim: s => s, -} - const run = async ({ args, call, @@ -25,8 +18,6 @@ const run = async ({ }) => { // turn list of args into command string const script = call || args.shift() || scriptShell - const color = !!flatOptions.color - const colorize = color ? chalk : nocolor // do the fakey runScript dance // still should work if no package.json in cwd @@ -49,14 +40,14 @@ const run = async ({ return log.warn('exec', 'Interactive mode disabled in CI environment') } - locationMsg = locationMsg || ` at location:\n${colorize.dim(runPath)}` + locationMsg = locationMsg || ` at location:\n${flatOptions.chalk.dim(runPath)}` output(`${ - colorize.reset('\nEntering npm script environment') + flatOptions.chalk.reset('\nEntering npm script environment') }${ - colorize.reset(locationMsg) + flatOptions.chalk.reset(locationMsg) }${ - colorize.bold('\nType \'exit\' or ^D when finished\n') + flatOptions.chalk.bold('\nType \'exit\' or ^D when finished\n') }`) } } diff --git a/deps/npm/node_modules/libnpmexec/package.json b/deps/npm/node_modules/libnpmexec/package.json index e47e301ab7dd77..1fa85ff033b8cb 100644 --- a/deps/npm/node_modules/libnpmexec/package.json +++ b/deps/npm/node_modules/libnpmexec/package.json @@ -1,6 +1,6 @@ { "name": "libnpmexec", - "version": "5.0.17", + "version": "6.0.0", "files": [ "bin/", "lib/" @@ -42,7 +42,6 @@ "template-oss-apply": "template-oss-apply --force" }, "tap": { - "color": true, "files": "test/*.js", "nyc-arg": [ "--exclude", @@ -54,6 +53,7 @@ "@npmcli/mock-registry": "^1.0.0", "@npmcli/template-oss": "4.14.1", "bin-links": "^4.0.1", + "chalk": "^5.2.0", "just-extend": "^6.2.0", "just-safe-set": "^4.2.1", "minify-registry-metadata": "^3.0.0", @@ -62,7 +62,6 @@ "dependencies": { "@npmcli/arborist": "^6.2.9", "@npmcli/run-script": "^6.0.0", - "chalk": "^4.1.0", "ci-info": "^3.7.1", "npm-package-arg": "^10.1.0", "npmlog": "^7.0.1", diff --git a/deps/npm/node_modules/libnpmpublish/README.md b/deps/npm/node_modules/libnpmpublish/README.md index 9c9c61d4b59657..90b1f7c68ab4f2 100644 --- a/deps/npm/node_modules/libnpmpublish/README.md +++ b/deps/npm/node_modules/libnpmpublish/README.md @@ -51,6 +51,17 @@ A couple of options of note: token for the registry. For other ways to pass in auth details, see the n-r-f docs. +* `opts.provenance` - when running in a supported CI environment, will trigger + the generation of a signed provenance statement to be published alongside + the package. Mutually exclusive with the `provenanceFile` option. + +* `opts.provenanceFile` - specifies the path to an externally-generated + provenance statement to be published alongside the package. Mutually + exclusive with the `provenance` option. The specified file should be a + [Sigstore Bundle](https://github.com/sigstore/protobuf-specs/blob/main/protos/sigstore_bundle.proto) + containing a [DSSE](https://github.com/secure-systems-lab/dsse)-packaged + provenance statement. + #### `> libpub.publish(manifest, tarData, [opts]) -> Promise` Sends the package represented by the `manifest` and `tarData` to the diff --git a/deps/npm/node_modules/libnpmpublish/lib/provenance.js b/deps/npm/node_modules/libnpmpublish/lib/provenance.js index 1eb870da5f24f7..ebe4a24475331d 100644 --- a/deps/npm/node_modules/libnpmpublish/lib/provenance.js +++ b/deps/npm/node_modules/libnpmpublish/lib/provenance.js @@ -1,4 +1,5 @@ const { sigstore } = require('sigstore') +const { readFile } = require('fs/promises') const INTOTO_PAYLOAD_TYPE = 'application/vnd.in-toto+json' const INTOTO_STATEMENT_TYPE = 'https://in-toto.io/Statement/v0.1' @@ -66,6 +67,50 @@ const generateProvenance = async (subject, opts) => { return sigstore.attest(Buffer.from(JSON.stringify(payload)), INTOTO_PAYLOAD_TYPE, opts) } +const verifyProvenance = async (subject, provenancePath) => { + let provenanceBundle + try { + provenanceBundle = JSON.parse(await readFile(provenancePath)) + } catch (err) { + err.message = `Invalid provenance provided: ${err.message}` + throw err + } + + const payload = extractProvenance(provenanceBundle) + if (!payload.subject || !payload.subject.length) { + throw new Error('No subject found in sigstore bundle payload') + } + if (payload.subject.length > 1) { + throw new Error('Found more than one subject in the sigstore bundle payload') + } + + const bundleSubject = payload.subject[0] + if (subject.name !== bundleSubject.name) { + throw new Error( + `Provenance subject ${bundleSubject.name} does not match the package: ${subject.name}` + ) + } + if (subject.digest.sha512 !== bundleSubject.digest.sha512) { + throw new Error('Provenance subject digest does not match the package') + } + + await sigstore.verify(provenanceBundle) + return provenanceBundle +} + +const extractProvenance = (bundle) => { + if (!bundle?.dsseEnvelope?.payload) { + throw new Error('No dsseEnvelope with payload found in sigstore bundle') + } + try { + return JSON.parse(Buffer.from(bundle.dsseEnvelope.payload, 'base64').toString('utf8')) + } catch (err) { + err.message = `Failed to parse payload from dsseEnvelope: ${err.message}` + throw err + } +} + module.exports = { generateProvenance, + verifyProvenance, } diff --git a/deps/npm/node_modules/libnpmpublish/lib/publish.js b/deps/npm/node_modules/libnpmpublish/lib/publish.js index 79c00eb68ad0c8..3749c3cebfdc8b 100644 --- a/deps/npm/node_modules/libnpmpublish/lib/publish.js +++ b/deps/npm/node_modules/libnpmpublish/lib/publish.js @@ -7,7 +7,7 @@ const { URL } = require('url') const ssri = require('ssri') const ciInfo = require('ci-info') -const { generateProvenance } = require('./provenance') +const { generateProvenance, verifyProvenance } = require('./provenance') const TLOG_BASE_URL = 'https://search.sigstore.dev/' @@ -111,7 +111,7 @@ const patchManifest = (_manifest, opts) => { } const buildMetadata = async (registry, manifest, tarballData, spec, opts) => { - const { access, defaultTag, algorithms, provenance } = opts + const { access, defaultTag, algorithms, provenance, provenanceFile } = opts const root = { _id: manifest.name, name: manifest.name, @@ -154,66 +154,31 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => { // Handle case where --provenance flag was set to true let transparencyLogUrl - if (provenance === true) { + if (provenance === true || provenanceFile) { + let provenanceBundle const subject = { name: npa.toPurl(spec), digest: { sha512: integrity.sha512[0].hexDigest() }, } - // Ensure that we're running in GHA, currently the only supported build environment - if (ciInfo.name !== 'GitHub Actions') { - throw Object.assign( - new Error('Automatic provenance generation not supported outside of GitHub Actions'), - { code: 'EUSAGE' } - ) - } - - // Ensure that the GHA OIDC token is available - if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) { - throw Object.assign( - /* eslint-disable-next-line max-len */ - new Error('Provenance generation in GitHub Actions requires "write" access to the "id-token" permission'), - { code: 'EUSAGE' } - ) - } - - // Some registries (e.g. GH packages) require auth to check visibility, - // and always return 404 when no auth is supplied. In this case we assume - // the package is always private and require `--access public` to publish - // with provenance. - let visibility = { public: false } - if (opts.provenance === true && opts.access !== 'public') { - try { - const res = await npmFetch - .json(`${registry}/-/package/${spec.escapedName}/visibility`, opts) - visibility = res - } catch (err) { - if (err.code !== 'E404') { - throw err - } + if (provenance === true) { + await ensureProvenanceGeneration(registry, spec, opts) + provenanceBundle = await generateProvenance([subject], opts) + + /* eslint-disable-next-line max-len */ + log.notice('publish', 'Signed provenance statement with source and build information from GitHub Actions') + + const tlogEntry = provenanceBundle?.verificationMaterial?.tlogEntries[0] + /* istanbul ignore else */ + if (tlogEntry) { + transparencyLogUrl = `${TLOG_BASE_URL}?logIndex=${tlogEntry.logIndex}` + log.notice( + 'publish', + `Provenance statement published to transparency log: ${transparencyLogUrl}` + ) } - } - - if (!visibility.public && opts.provenance === true && opts.access !== 'public') { - throw Object.assign( - /* eslint-disable-next-line max-len */ - new Error("Can't generate provenance for new or private package, you must set `access` to public."), - { code: 'EUSAGE' } - ) - } - const provenanceBundle = await generateProvenance([subject], opts) - - /* eslint-disable-next-line max-len */ - log.notice('publish', 'Signed provenance statement with source and build information from GitHub Actions') - - const tlogEntry = provenanceBundle?.verificationMaterial?.tlogEntries[0] - /* istanbul ignore else */ - if (tlogEntry) { - transparencyLogUrl = `${TLOG_BASE_URL}?logIndex=${tlogEntry.logIndex}` - log.notice( - 'publish', - `Provenance statement published to transparency log: ${transparencyLogUrl}` - ) + } else { + provenanceBundle = await verifyProvenance(subject, provenanceFile) } const serializedBundle = JSON.stringify(provenanceBundle) @@ -275,4 +240,49 @@ const patchMetadata = (current, newData) => { return current } +// Check that all the prereqs are met for provenance generation +const ensureProvenanceGeneration = async (registry, spec, opts) => { + // Ensure that we're running in GHA, currently the only supported build environment + if (ciInfo.name !== 'GitHub Actions') { + throw Object.assign( + new Error('Automatic provenance generation not supported outside of GitHub Actions'), + { code: 'EUSAGE' } + ) + } + + // Ensure that the GHA OIDC token is available + if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) { + throw Object.assign( + /* eslint-disable-next-line max-len */ + new Error('Provenance generation in GitHub Actions requires "write" access to the "id-token" permission'), + { code: 'EUSAGE' } + ) + } + + // Some registries (e.g. GH packages) require auth to check visibility, + // and always return 404 when no auth is supplied. In this case we assume + // the package is always private and require `--access public` to publish + // with provenance. + let visibility = { public: false } + if (true && opts.access !== 'public') { + try { + const res = await npmFetch + .json(`${registry}/-/package/${spec.escapedName}/visibility`, opts) + visibility = res + } catch (err) { + if (err.code !== 'E404') { + throw err + } + } + } + + if (!visibility.public && opts.provenance === true && opts.access !== 'public') { + throw Object.assign( + /* eslint-disable-next-line max-len */ + new Error("Can't generate provenance for new or private package, you must set `access` to public."), + { code: 'EUSAGE' } + ) + } +} + module.exports = publish diff --git a/deps/npm/node_modules/libnpmpublish/package.json b/deps/npm/node_modules/libnpmpublish/package.json index a4adbe2a50f154..0e86861893e070 100644 --- a/deps/npm/node_modules/libnpmpublish/package.json +++ b/deps/npm/node_modules/libnpmpublish/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpublish", - "version": "7.2.0", + "version": "7.3.0", "description": "Programmatic API for the bits behind npm publish and unpublish", "author": "GitHub Inc.", "main": "lib/index.js", @@ -24,6 +24,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", + "@npmcli/mock-globals": "^1.0.0", "@npmcli/mock-registry": "^1.0.0", "@npmcli/template-oss": "4.14.1", "lodash.clonedeep": "^4.5.0", diff --git a/deps/npm/node_modules/npm-audit-report/lib/colors.js b/deps/npm/node_modules/npm-audit-report/lib/colors.js index 2fbf5c36093ded..e6688f2f1c8c69 100644 --- a/deps/npm/node_modules/npm-audit-report/lib/colors.js +++ b/deps/npm/node_modules/npm-audit-report/lib/colors.js @@ -1,16 +1,14 @@ -const chalk = require('chalk') -module.exports = color => { - const identity = x => x - const green = color ? s => chalk.green.bold(s) : identity - const red = color ? s => chalk.red.bold(s) : identity - const magenta = color ? s => chalk.magenta.bold(s) : identity - const yellow = color ? s => chalk.yellow.bold(s) : identity - const white = color ? s => chalk.bold(s) : identity +module.exports = (chalk) => { + const green = s => chalk.green.bold(s) + const red = s => chalk.red.bold(s) + const magenta = s => chalk.magenta.bold(s) + const yellow = s => chalk.yellow.bold(s) + const white = s => chalk.bold(s) const severity = (sev, s) => sev.toLowerCase() === 'moderate' ? yellow(s || sev) : sev.toLowerCase() === 'high' ? red(s || sev) : sev.toLowerCase() === 'critical' ? magenta(s || sev) : white(s || sev) - const dim = color ? s => chalk.dim(s) : identity + const dim = s => chalk.dim(s) return { dim, diff --git a/deps/npm/node_modules/npm-audit-report/lib/index.js b/deps/npm/node_modules/npm-audit-report/lib/index.js index 63063f92526a1b..d0ced01efefec9 100644 --- a/deps/npm/node_modules/npm-audit-report/lib/index.js +++ b/deps/npm/node_modules/npm-audit-report/lib/index.js @@ -12,7 +12,7 @@ const exitCode = require('./exit-code.js') module.exports = Object.assign((data, options = {}) => { const { reporter = 'install', - color = true, + chalk, unicode = true, indent = 2, } = options @@ -35,7 +35,7 @@ module.exports = Object.assign((data, options = {}) => { } return { - report: reporters[reporter](data, { color, unicode, indent }), + report: reporters[reporter](data, { chalk, unicode, indent }), exitCode: exitCode(data, auditLevel), } }, { reporters }) diff --git a/deps/npm/node_modules/npm-audit-report/lib/reporters/detail.js b/deps/npm/node_modules/npm-audit-report/lib/reporters/detail.js index ba2f013836d9da..6dde8ec88de447 100644 --- a/deps/npm/node_modules/npm-audit-report/lib/reporters/detail.js +++ b/deps/npm/node_modules/npm-audit-report/lib/reporters/detail.js @@ -3,14 +3,14 @@ const colors = require('../colors.js') const install = require('./install.js') -module.exports = (data, { color }) => { - const summary = install.summary(data, { color }) +module.exports = (data, { chalk }) => { + const summary = install.summary(data, { chalk }) const none = data.metadata.vulnerabilities.total === 0 - return none ? summary : fullReport(data, { color, summary }) + return none ? summary : fullReport(data, { chalk, summary }) } -const fullReport = (data, { color, summary }) => { - const c = colors(color) +const fullReport = (data, { chalk, summary }) => { + const c = colors(chalk) const output = [c.white('# npm audit report'), ''] const printed = new Set() diff --git a/deps/npm/node_modules/npm-audit-report/lib/reporters/install.js b/deps/npm/node_modules/npm-audit-report/lib/reporters/install.js index cb8a249691e299..0a1e82533e657c 100644 --- a/deps/npm/node_modules/npm-audit-report/lib/reporters/install.js +++ b/deps/npm/node_modules/npm-audit-report/lib/reporters/install.js @@ -1,7 +1,7 @@ const colors = require('../colors.js') -const calculate = (data, { color }) => { - const c = colors(color) +const calculate = (data, { chalk }) => { + const c = colors(chalk) const output = [] const { metadata: { vulnerabilities } } = data const vulnCount = vulnerabilities.total diff --git a/deps/npm/node_modules/npm-audit-report/package.json b/deps/npm/node_modules/npm-audit-report/package.json index 8779f4c1d2c7e2..492071c1faf902 100644 --- a/deps/npm/node_modules/npm-audit-report/package.json +++ b/deps/npm/node_modules/npm-audit-report/package.json @@ -1,6 +1,6 @@ { "name": "npm-audit-report", - "version": "4.0.0", + "version": "5.0.0", "description": "Given a response from the npm security api, render it into a variety of security reports", "main": "lib/index.js", "scripts": { @@ -28,13 +28,10 @@ ], "author": "GitHub Inc.", "license": "ISC", - "dependencies": { - "chalk": "^4.0.0" - }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "4.5.1", - "require-inject": "^1.4.4", + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.14.1", + "chalk": "^5.2.0", "tap": "^16.0.0" }, "directories": { @@ -58,6 +55,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.5.1" + "version": "4.14.1" } } diff --git a/deps/npm/node_modules/supports-color/browser.js b/deps/npm/node_modules/supports-color/browser.js deleted file mode 100644 index 62afa3a7425dc6..00000000000000 --- a/deps/npm/node_modules/supports-color/browser.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; -module.exports = { - stdout: false, - stderr: false -}; diff --git a/deps/npm/node_modules/supports-color/index.js b/deps/npm/node_modules/supports-color/index.js deleted file mode 100644 index 6fada390fb88d8..00000000000000 --- a/deps/npm/node_modules/supports-color/index.js +++ /dev/null @@ -1,135 +0,0 @@ -'use strict'; -const os = require('os'); -const tty = require('tty'); -const hasFlag = require('has-flag'); - -const {env} = process; - -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false') || - hasFlag('color=never')) { - forceColor = 0; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = 1; -} - -if ('FORCE_COLOR' in env) { - if (env.FORCE_COLOR === 'true') { - forceColor = 1; - } else if (env.FORCE_COLOR === 'false') { - forceColor = 0; - } else { - forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); - } -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor(haveStream, streamIsTTY) { - if (forceColor === 0) { - return 0; - } - - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } - - const min = forceColor || 0; - - if (env.TERM === 'dumb') { - return min; - } - - if (process.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - return min; -} - -function getSupportLevel(stream) { - const level = supportsColor(stream, stream && stream.isTTY); - return translateLevel(level); -} - -module.exports = { - supportsColor: getSupportLevel, - stdout: translateLevel(supportsColor(true, tty.isatty(1))), - stderr: translateLevel(supportsColor(true, tty.isatty(2))) -}; diff --git a/deps/npm/node_modules/supports-color/license b/deps/npm/node_modules/supports-color/license deleted file mode 100644 index e7af2f77107d73..00000000000000 --- a/deps/npm/node_modules/supports-color/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/supports-color/package.json b/deps/npm/node_modules/supports-color/package.json deleted file mode 100644 index f7182edcea2baa..00000000000000 --- a/deps/npm/node_modules/supports-color/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "supports-color", - "version": "7.2.0", - "description": "Detect whether a terminal supports color", - "license": "MIT", - "repository": "chalk/supports-color", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava" - }, - "files": [ - "index.js", - "browser.js" - ], - "keywords": [ - "color", - "colour", - "colors", - "terminal", - "console", - "cli", - "ansi", - "styles", - "tty", - "rgb", - "256", - "shell", - "xterm", - "command-line", - "support", - "supports", - "capability", - "detect", - "truecolor", - "16m" - ], - "dependencies": { - "has-flag": "^4.0.0" - }, - "devDependencies": { - "ava": "^1.4.1", - "import-fresh": "^3.0.0", - "xo": "^0.24.0" - }, - "browser": "browser.js" -} diff --git a/deps/npm/package.json b/deps/npm/package.json index 148a2a3b9e56a4..f417d60fbab8c2 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,10 +1,11 @@ { - "version": "9.6.7", + "version": "9.7.1", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ "docs", "smoke-tests", + "mock-globals", "mock-registry", "workspaces/*" ], @@ -54,14 +55,14 @@ "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^6.2.9", - "@npmcli/config": "^6.1.7", + "@npmcli/config": "^6.2.0", "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^3.1.0", + "@npmcli/package-json": "^3.1.1", "@npmcli/run-script": "^6.0.2", "abbrev": "^2.0.0", "archy": "~1.0.0", "cacache": "^17.1.2", - "chalk": "^4.1.2", + "chalk": "^5.2.0", "ci-info": "^3.8.0", "cli-columns": "^4.0.0", "cli-table3": "^0.6.3", @@ -77,12 +78,12 @@ "json-parse-even-better-errors": "^3.0.0", "libnpmaccess": "^7.0.2", "libnpmdiff": "^5.0.17", - "libnpmexec": "^5.0.17", + "libnpmexec": "^6.0.0", "libnpmfund": "^4.0.17", "libnpmhook": "^9.0.3", "libnpmorg": "^5.0.4", "libnpmpack": "^5.0.17", - "libnpmpublish": "^7.2.0", + "libnpmpublish": "^7.3.0", "libnpmsearch": "^6.0.2", "libnpmteam": "^5.0.3", "libnpmversion": "^4.0.2", @@ -93,7 +94,7 @@ "ms": "^2.1.2", "node-gyp": "^9.3.1", "nopt": "^7.1.0", - "npm-audit-report": "^4.0.0", + "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.1.1", "npm-package-arg": "^10.1.0", "npm-pick-manifest": "^8.0.1", @@ -107,9 +108,8 @@ "proc-log": "^3.0.0", "qrcode-terminal": "^0.12.0", "read": "^2.1.0", - "read-package-json": "^6.0.3", - "read-package-json-fast": "^3.0.2", "semver": "^7.5.1", + "sigstore": "^1.5.0", "ssri": "^10.0.4", "tar": "^6.1.14", "text-table": "~0.2.0", @@ -175,9 +175,8 @@ "proc-log", "qrcode-terminal", "read", - "read-package-json", - "read-package-json-fast", "semver", + "sigstore", "ssri", "tar", "text-table", @@ -191,10 +190,12 @@ "@npmcli/docs": "^1.0.0", "@npmcli/eslint-config": "^4.0.0", "@npmcli/fs": "^3.1.0", - "@npmcli/git": "^4.0.4", + "@npmcli/git": "^4.1.0", + "@npmcli/mock-globals": "^1.0.0", "@npmcli/mock-registry": "^1.0.0", "@npmcli/promise-spawn": "^6.0.2", "@npmcli/template-oss": "4.14.1", + "@tufjs/repo-mock": "^1.3.1", "licensee": "^10.0.0", "nock": "^13.3.0", "npm-packlist": "^7.0.4", @@ -238,13 +239,15 @@ "--exclude", "smoke-tests/**", "--exclude", + "mock-globals/**", + "--exclude", "mock-registry/**", "--exclude", "workspaces/**", "--exclude", "tap-snapshots/**" ], - "test-ignore": "^(docs|smoke-tests|mock-registry|workspaces)/" + "test-ignore": "^(docs|smoke-tests|mock-globals|mock-registry|workspaces)/" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", diff --git a/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs index 4fec8f86c5baa0..7611191688268c 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs @@ -175,6 +175,20 @@ audited 1 package in xxx ` +exports[`test/lib/commands/audit.js TAP audit signatures third-party registry with sub-path (trailing slash) > must match snapshot 1`] = ` +audited 1 package in xxx + +1 package has a verified registry signature + +` + +exports[`test/lib/commands/audit.js TAP audit signatures third-party registry with sub-path > must match snapshot 1`] = ` +audited 1 package in xxx + +1 package has a verified registry signature + +` + exports[`test/lib/commands/audit.js TAP audit signatures with both invalid and missing signatures > must match snapshot 1`] = ` audited 2 packages in xxx @@ -230,6 +244,13 @@ Someone might have tampered with this package since it was published on the regi ` +exports[`test/lib/commands/audit.js TAP audit signatures with key fallback to legacy API > must match snapshot 1`] = ` +audited 1 package in xxx + +1 package has a verified registry signature + +` + exports[`test/lib/commands/audit.js TAP audit signatures with keys but missing signature > must match snapshot 1`] = ` audited 1 package in xxx diff --git a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs index c88888b7cd7d15..93ac959ce44059 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -111,12 +111,14 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "package-lock-only": false, "pack-destination": ".", "parseable": false, + "prefer-dedupe": false, "prefer-offline": false, "prefer-online": false, "preid": "", "production": null, "progress": true, "provenance": false, + "provenance-file": null, "proxy": null, "read-only": false, "rebuild-bundle": true, @@ -265,6 +267,7 @@ package = [] package-lock = true package-lock-only = false parseable = false +prefer-dedupe = false prefer-offline = false prefer-online = false ; prefix = "{REALGLOBALREFIX}" ; overridden by cli @@ -272,6 +275,7 @@ preid = "" production = null progress = true provenance = false +provenance-file = null proxy = null read-only = false rebuild-bundle = true diff --git a/deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs index 533b4f196e6616..e87086d7d9b8fb 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs @@ -33,7 +33,7 @@ index v0.1.0..v1.0.0 100644 +++ b/package.json @@ -1,4 +1,4 @@ { - "name": "foo", + "name": "@npmcli/foo", - "version": "0.1.0" + "version": "1.0.0" } diff --git a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs index 7cb836226a76b1..54dd0098597575 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -99,6 +99,148 @@ exports[`test/lib/commands/publish.js TAP json > new package json 1`] = ` } ` +exports[`test/lib/commands/publish.js TAP manifest > manifest 1`] = ` +Object { + "_id": "npm@{VERSION}", + "author": Object { + "name": "GitHub Inc.", + }, + "bin": Object { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js", + }, + "bugs": Object { + "url": "https://github.com/npm/cli/issues", + }, + "description": "a package manager for JavaScript", + "directories": Object { + "bin": "./bin", + "doc": "./doc", + "lib": "./lib", + "man": "./man", + }, + "exports": Object { + ".": Array [ + Object { + "default": "./index.js", + }, + "./index.js", + ], + "./package.json": "./package.json", + }, + "files": Array [ + "bin/", + "lib/", + "index.js", + "docs/content/", + "docs/output/", + "man/", + ], + "homepage": "https://docs.npmjs.com/", + "keywords": Array [ + "install", + "modules", + "package manager", + "package.json", + ], + "license": "Artistic-2.0", + "main": "./index.js", + "man": Array [ + "man/man1/npm-access.1", + "man/man1/npm-adduser.1", + "man/man1/npm-audit.1", + "man/man1/npm-bugs.1", + "man/man1/npm-cache.1", + "man/man1/npm-ci.1", + "man/man1/npm-completion.1", + "man/man1/npm-config.1", + "man/man1/npm-dedupe.1", + "man/man1/npm-deprecate.1", + "man/man1/npm-diff.1", + "man/man1/npm-dist-tag.1", + "man/man1/npm-docs.1", + "man/man1/npm-doctor.1", + "man/man1/npm-edit.1", + "man/man1/npm-exec.1", + "man/man1/npm-explain.1", + "man/man1/npm-explore.1", + "man/man1/npm-find-dupes.1", + "man/man1/npm-fund.1", + "man/man1/npm-help-search.1", + "man/man1/npm-help.1", + "man/man1/npm-hook.1", + "man/man1/npm-init.1", + "man/man1/npm-install-ci-test.1", + "man/man1/npm-install-test.1", + "man/man1/npm-install.1", + "man/man1/npm-link.1", + "man/man1/npm-login.1", + "man/man1/npm-logout.1", + "man/man1/npm-ls.1", + "man/man1/npm-org.1", + "man/man1/npm-outdated.1", + "man/man1/npm-owner.1", + "man/man1/npm-pack.1", + "man/man1/npm-ping.1", + "man/man1/npm-pkg.1", + "man/man1/npm-prefix.1", + "man/man1/npm-profile.1", + "man/man1/npm-prune.1", + "man/man1/npm-publish.1", + "man/man1/npm-query.1", + "man/man1/npm-rebuild.1", + "man/man1/npm-repo.1", + "man/man1/npm-restart.1", + "man/man1/npm-root.1", + "man/man1/npm-run-script.1", + "man/man1/npm-search.1", + "man/man1/npm-shrinkwrap.1", + "man/man1/npm-star.1", + "man/man1/npm-stars.1", + "man/man1/npm-start.1", + "man/man1/npm-stop.1", + "man/man1/npm-team.1", + "man/man1/npm-test.1", + "man/man1/npm-token.1", + "man/man1/npm-uninstall.1", + "man/man1/npm-unpublish.1", + "man/man1/npm-unstar.1", + "man/man1/npm-update.1", + "man/man1/npm-version.1", + "man/man1/npm-view.1", + "man/man1/npm-whoami.1", + "man/man1/npm.1", + "man/man1/npx.1", + "man/man5/folders.5", + "man/man5/install.5", + "man/man5/npm-global.5", + "man/man5/npm-json.5", + "man/man5/npm-shrinkwrap-json.5", + "man/man5/npmrc.5", + "man/man5/package-json.5", + "man/man5/package-lock-json.5", + "man/man7/config.7", + "man/man7/dependency-selectors.7", + "man/man7/developers.7", + "man/man7/logging.7", + "man/man7/orgs.7", + "man/man7/package-spec.7", + "man/man7/registry.7", + "man/man7/removal.7", + "man/man7/scope.7", + "man/man7/scripts.7", + "man/man7/workspaces.7", + ], + "name": "npm", + "readmeFilename": "README.md", + "repository": Object { + "type": "git", + "url": "git+https://github.com/npm/cli.git", + }, + "version": "{VERSION}", +} +` + exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot 1`] = ` + test-package@1.0.0 ` diff --git a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs index d7a943500e49e5..bd5aa05991ab2d 100644 --- a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs @@ -24,7 +24,7 @@ All commands: Specify configs in the ini-formatted file: - /some/config/file/.npmrc + {USERCONFIG} or on the command line via: npm --key=value More configuration info: npm help config @@ -165,6 +165,10 @@ Array [ ] ` +exports[`test/lib/docs.js TAP command list > deref 1`] = ` +Function deref(c) +` + exports[`test/lib/docs.js TAP config > all definitions 1`] = ` #### \`_auth\` @@ -179,6 +183,8 @@ Warning: This should generally not be set via a command-line option. It is safer to use a registry-provided authentication bearer token stored in the ~/.npmrc file by running \`npm login\`. + + #### \`access\` * Default: 'public' for new packages, existing packages it will not change the @@ -195,6 +201,8 @@ packages. Specifying a value of \`restricted\` or \`public\` during publish will change the access for an existing package the same way that \`npm access set status\` would. + + #### \`all\` * Default: false @@ -204,6 +212,8 @@ When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show all outdated or installed packages, rather than only those directly depended upon by the current project. + + #### \`allow-same-version\` * Default: false @@ -212,6 +222,8 @@ upon by the current project. Prevents throwing an error when \`npm version\` is used to set the new version to the same value as the current version. + + #### \`audit\` * Default: true @@ -222,6 +234,8 @@ default registry and all registries configured for scopes. See the documentation for [\`npm audit\`](/commands/npm-audit) for details on what is submitted. + + #### \`audit-level\` * Default: null @@ -230,6 +244,8 @@ submitted. The minimum level of vulnerability for \`npm audit\` to exit with a non-zero exit code. + + #### \`auth-type\` * Default: "web" @@ -238,6 +254,8 @@ exit code. What authentication strategy to use with \`login\`. Note that if an \`otp\` config is given, this value will always be set to \`legacy\`. + + #### \`before\` * Default: null @@ -253,6 +271,8 @@ If the requested version is a \`dist-tag\` and the given tag does not pass the will be used. For example, \`foo@latest\` might install \`foo@1.2\` even though \`latest\` is \`2.0\`. + + #### \`bin-links\` * Default: true @@ -265,6 +285,8 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. + + #### \`browser\` * Default: OS X: \`"open"\`, Windows: \`"start"\`, Others: \`"xdg-open"\` @@ -277,6 +299,8 @@ terminal. Set to \`true\` to use default system URL opener. + + #### \`ca\` * Default: null @@ -303,6 +327,8 @@ ca[]="..." See also the \`strict-ssl\` config. + + #### \`cache\` * Default: Windows: \`%LocalAppData%\\npm-cache\`, Posix: \`~/.npm\` @@ -310,6 +336,8 @@ See also the \`strict-ssl\` config. The location of npm's cache directory. + + #### \`cafile\` * Default: null @@ -319,6 +347,8 @@ A path to a file containing one or multiple Certificate Authority signing certificates. Similar to the \`ca\` setting, but allows for multiple CA's, as well as for the CA information to be stored in a file on disk. + + #### \`call\` * Default: "" @@ -332,6 +362,7 @@ npm exec --package yo --package generator-node --call "yo node" \`\`\` + #### \`cidr\` * Default: null @@ -340,6 +371,8 @@ npm exec --package yo --package generator-node --call "yo node" This is a list of CIDR address to be used when configuring limited access tokens with the \`npm token create\` command. + + #### \`color\` * Default: true unless the NO_COLOR environ is set to something other than '0' @@ -348,6 +381,8 @@ tokens with the \`npm token create\` command. If false, never shows colors. If \`"always"\` then always shows colors. If true, then only prints color codes for tty file descriptors. + + #### \`commit-hooks\` * Default: true @@ -355,6 +390,8 @@ true, then only prints color codes for tty file descriptors. Run git commit hooks when using the \`npm version\` command. + + #### \`depth\` * Default: \`Infinity\` if \`--all\` is set, otherwise \`1\` @@ -365,6 +402,8 @@ The depth to go when recursing packages for \`npm ls\`. If not set, \`npm ls\` will show only the immediate dependencies of the root project. If \`--all\` is set, then npm will show all dependencies by default. + + #### \`description\` * Default: true @@ -372,6 +411,8 @@ project. If \`--all\` is set, then npm will show all dependencies by default. Show the description in \`npm search\` + + #### \`diff\` * Default: @@ -379,6 +420,8 @@ Show the description in \`npm search\` Define arguments to compare in \`npm diff\`. + + #### \`diff-dst-prefix\` * Default: "b/" @@ -386,6 +429,8 @@ Define arguments to compare in \`npm diff\`. Destination prefix to be used in \`npm diff\` output. + + #### \`diff-ignore-all-space\` * Default: false @@ -393,6 +438,8 @@ Destination prefix to be used in \`npm diff\` output. Ignore whitespace when comparing lines in \`npm diff\`. + + #### \`diff-name-only\` * Default: false @@ -400,6 +447,8 @@ Ignore whitespace when comparing lines in \`npm diff\`. Prints only filenames when using \`npm diff\`. + + #### \`diff-no-prefix\` * Default: false @@ -410,6 +459,8 @@ Do not show any source or destination prefix in \`npm diff\` output. Note: this causes \`npm diff\` to ignore the \`--diff-src-prefix\` and \`--diff-dst-prefix\` configs. + + #### \`diff-src-prefix\` * Default: "a/" @@ -417,6 +468,8 @@ Note: this causes \`npm diff\` to ignore the \`--diff-src-prefix\` and Source prefix to be used in \`npm diff\` output. + + #### \`diff-text\` * Default: false @@ -424,6 +477,8 @@ Source prefix to be used in \`npm diff\` output. Treat all files as text in \`npm diff\`. + + #### \`diff-unified\` * Default: 3 @@ -431,6 +486,8 @@ Treat all files as text in \`npm diff\`. The number of lines of context to print in \`npm diff\`. + + #### \`dry-run\` * Default: false @@ -444,6 +501,8 @@ commands that modify your local installation, eg, \`install\`, \`update\`, Note: This is NOT honored by other network related commands, eg \`dist-tags\`, \`owner\`, etc. + + #### \`editor\` * Default: The EDITOR or VISUAL environment variables, or @@ -452,6 +511,8 @@ Note: This is NOT honored by other network related commands, eg \`dist-tags\`, The command to run for \`npm edit\` and \`npm config edit\`. + + #### \`engine-strict\` * Default: false @@ -463,6 +524,8 @@ Node.js version. This can be overridden by setting the \`--force\` flag. + + #### \`fetch-retries\` * Default: 2 @@ -474,6 +537,8 @@ from the registry. npm will retry idempotent read requests to the registry in the case of network failures or 5xx HTTP errors. + + #### \`fetch-retry-factor\` * Default: 10 @@ -481,6 +546,8 @@ network failures or 5xx HTTP errors. The "factor" config for the \`retry\` module to use when fetching packages. + + #### \`fetch-retry-maxtimeout\` * Default: 60000 (1 minute) @@ -489,6 +556,8 @@ The "factor" config for the \`retry\` module to use when fetching packages. The "maxTimeout" config for the \`retry\` module to use when fetching packages. + + #### \`fetch-retry-mintimeout\` * Default: 10000 (10 seconds) @@ -497,6 +566,8 @@ packages. The "minTimeout" config for the \`retry\` module to use when fetching packages. + + #### \`fetch-timeout\` * Default: 300000 (5 minutes) @@ -504,6 +575,8 @@ packages. The maximum amount of time to wait for HTTP requests to complete. + + #### \`force\` * Default: false @@ -530,6 +603,8 @@ mistakes, unnecessary performance degradation, and malicious input. If you don't have a clear idea of what you want to do, it is strongly recommended that you do not use this option! + + #### \`foreground-scripts\` * Default: false @@ -542,6 +617,8 @@ input, output, and error with the main npm process. Note that this will generally make installs run slower, and be much noisier, but can be useful for debugging. + + #### \`format-package-lock\` * Default: true @@ -550,6 +627,8 @@ but can be useful for debugging. Format \`package-lock.json\` or \`npm-shrinkwrap.json\` as a human readable file. + + #### \`fund\` * Default: true @@ -559,6 +638,8 @@ When "true" displays the message at the end of each \`npm install\` acknowledging the number of dependencies looking for funding. See [\`npm fund\`](/commands/npm-fund) for details. + + #### \`git\` * Default: "git" @@ -567,6 +648,8 @@ fund\`](/commands/npm-fund) for details. The command to use for git commands. If git is installed on the computer, but is not in the \`PATH\`, then set this to the full path to the git binary. + + #### \`git-tag-version\` * Default: true @@ -575,6 +658,8 @@ but is not in the \`PATH\`, then set this to the full path to the git binary. Tag the commit when using the \`npm version\` command. Setting this to false results in no commit being made at all. + + #### \`global\` * Default: false @@ -589,6 +674,8 @@ folder instead of the current working directory. See * bin files are linked to \`{prefix}/bin\` * man pages are linked to \`{prefix}/share/man\` + + #### \`globalconfig\` * Default: The global --prefix setting plus 'etc/npmrc'. For example, @@ -597,6 +684,8 @@ folder instead of the current working directory. See The config file to read for global config options. + + #### \`heading\` * Default: "npm" @@ -604,6 +693,8 @@ The config file to read for global config options. The string that starts all the debugging log output. + + #### \`https-proxy\` * Default: null @@ -614,6 +705,8 @@ A proxy to use for outgoing https requests. If the \`HTTPS_PROXY\` or proxy settings will be honored by the underlying \`make-fetch-happen\` library. + + #### \`if-present\` * Default: false @@ -640,6 +733,8 @@ Note that commands explicitly intended to run a particular script, such as will still run their intended script if \`ignore-scripts\` is set, but they will *not* run any pre- or post-scripts. + + #### \`include\` * Default: @@ -652,6 +747,8 @@ This is the inverse of \`--omit=\`. Dependency types specified in \`--include\` will not be omitted, regardless of the order in which omit/include are specified on the command-line. + + #### \`include-staged\` * Default: false @@ -662,6 +759,8 @@ Allow installing "staged" published packages, as defined by [npm RFC PR This is experimental, and not implemented by the npm public registry. + + #### \`include-workspace-root\` * Default: false @@ -682,6 +781,8 @@ This value is not exported to the environment for child processes. The value \`npm init\` should use by default for the package author's email. + + #### \`init-author-name\` * Default: "" @@ -689,6 +790,8 @@ The value \`npm init\` should use by default for the package author's email. The value \`npm init\` should use by default for the package author's name. + + #### \`init-author-url\` * Default: "" @@ -697,6 +800,8 @@ The value \`npm init\` should use by default for the package author's name. The value \`npm init\` should use by default for the package author's homepage. + + #### \`init-license\` * Default: "ISC" @@ -704,6 +809,8 @@ homepage. The value \`npm init\` should use by default for the package license. + + #### \`init-module\` * Default: "~/.npm-init.js" @@ -714,6 +821,8 @@ documentation for the [init-package-json](https://github.com/npm/init-package-json) module for more information, or [npm init](/commands/npm-init). + + #### \`init-version\` * Default: "1.0.0" @@ -722,6 +831,8 @@ more information, or [npm init](/commands/npm-init). The value that \`npm init\` should use by default for the package version number, if not already set in package.json. + + #### \`install-links\` * Default: false @@ -731,6 +842,8 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. + + #### \`install-strategy\` * Default: "hoisted" @@ -743,6 +856,8 @@ place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. + + #### \`json\` * Default: false @@ -755,6 +870,8 @@ Whether or not to output JSON data, rather than the normal output. Not supported by all npm commands. + + #### \`legacy-peer-deps\` * Default: false @@ -773,6 +890,8 @@ This differs from \`--omit=peer\`, in that \`--omit=peer\` will avoid unpacking Use of \`legacy-peer-deps\` is not recommended, as it will not enforce the \`peerDependencies\` contract that meta-dependencies may rely on. + + #### \`link\` * Default: false @@ -780,6 +899,8 @@ Use of \`legacy-peer-deps\` is not recommended, as it will not enforce the Used with \`npm ls\`, limiting output to only those packages that are linked. + + #### \`local-address\` * Default: null @@ -788,6 +909,8 @@ Used with \`npm ls\`, limiting output to only those packages that are linked. The IP address of the local interface to use when making connections to the npm registry. Must be IPv4 in versions of Node prior to 0.12. + + #### \`location\` * Default: "user" unless \`--global\` is passed, which will also set this value @@ -805,6 +928,8 @@ instead of the current working directory. See * bin files are linked to \`{prefix}/bin\` * man pages are linked to \`{prefix}/share/man\` + + #### \`lockfile-version\` * Default: Version 3 if no lockfile, auto-converting v1 lockfiles to v3, @@ -827,6 +952,8 @@ determinism and interoperability, at the expense of more bytes on disk. disk than lockfile version 2, but not interoperable with older npm versions. Ideal if all users are on npm version 7 and higher. + + #### \`loglevel\` * Default: "notice" @@ -841,6 +968,8 @@ Any logs of a higher level than the setting are shown. The default is See also the \`foreground-scripts\` config. + + #### \`logs-dir\` * Default: A directory named \`_logs\` inside the cache @@ -849,6 +978,8 @@ See also the \`foreground-scripts\` config. The location of npm's log directory. See [\`npm logging\`](/using-npm/logging) for more information. + + #### \`logs-max\` * Default: 10 @@ -858,6 +989,8 @@ The maximum number of log files to store. If set to 0, no log files will be written for the current run. + + #### \`long\` * Default: false @@ -865,6 +998,8 @@ If set to 0, no log files will be written for the current run. Show extended information in \`ls\`, \`search\`, and \`help-search\`. + + #### \`maxsockets\` * Default: 15 @@ -873,6 +1008,8 @@ Show extended information in \`ls\`, \`search\`, and \`help-search\`. The maximum number of connections to use per origin (protocol/host/port combination). + + #### \`message\` * Default: "%s" @@ -882,6 +1019,8 @@ Commit message which is used by \`npm version\` when creating version commit. Any "%s" in the message will be replaced with the version number. + + #### \`node-options\` * Default: null @@ -891,6 +1030,8 @@ Options to pass through to Node.js via the \`NODE_OPTIONS\` environment variable. This does not impact how npm itself is executed but it does impact how lifecycle scripts are called. + + #### \`noproxy\` * Default: The value of the NO_PROXY environment variable @@ -900,6 +1041,8 @@ Domain extensions that should bypass any proxies. Also accepts a comma-delimited string. + + #### \`offline\` * Default: false @@ -908,6 +1051,8 @@ Also accepts a comma-delimited string. Force offline mode: no network requests will be done during install. To allow the CLI to fill in missing cache data, see \`--prefer-offline\`. + + #### \`omit\` * Default: 'dev' if the \`NODE_ENV\` environment variable is set to @@ -926,6 +1071,8 @@ it will be included. If the resulting omit list includes \`'dev'\`, then the \`NODE_ENV\` environment variable will be set to \`'production'\` for all lifecycle scripts. + + #### \`omit-lockfile-registry-resolved\` * Default: false @@ -936,6 +1083,8 @@ registry dependencies. Subsequent installs will need to resolve tarball endpoints with the configured registry, likely resulting in a longer install time. + + #### \`otp\` * Default: null @@ -947,6 +1096,8 @@ when publishing or changing package permissions with \`npm access\`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. + + #### \`pack-destination\` * Default: "." @@ -954,6 +1105,8 @@ password, npm will prompt on the command line for one. Directory in which \`npm pack\` will save tarballs. + + #### \`package\` * Default: @@ -961,6 +1114,8 @@ Directory in which \`npm pack\` will save tarballs. The package or packages to install for [\`npm exec\`](/commands/npm-exec) + + #### \`package-lock\` * Default: true @@ -969,7 +1124,7 @@ The package or packages to install for [\`npm exec\`](/commands/npm-exec) If set to false, then ignore \`package-lock.json\` files when installing. This will also prevent _writing_ \`package-lock.json\` if \`save\` is true. -This configuration does not affect \`npm ci\`. + #### \`package-lock-only\` @@ -985,6 +1140,8 @@ instead of checking \`node_modules\` and downloading dependencies. For \`list\` this means the output will be based on the tree described by the \`package-lock.json\`, rather than the contents of \`node_modules\`. + + #### \`parseable\` * Default: false @@ -993,6 +1150,18 @@ For \`list\` this means the output will be based on the tree described by the Output parseable results from commands that write to standard output. For \`npm search\`, this will be tab-separated table format. + + +#### \`prefer-dedupe\` + +* Default: false +* Type: Boolean + +Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency. + + + #### \`prefer-offline\` * Default: false @@ -1002,6 +1171,8 @@ If true, staleness checks for cached data will be bypassed, but missing data will be requested from the server. To force full offline mode, use \`--offline\`. + + #### \`prefer-online\` * Default: false @@ -1010,6 +1181,8 @@ will be requested from the server. To force full offline mode, use If true, staleness checks for cached data will be forced, making the CLI look for updates immediately even for fresh package data. + + #### \`prefix\` * Default: In global mode, the folder where the node executable is installed. @@ -1020,6 +1193,8 @@ look for updates immediately even for fresh package data. The location to install global items. If set on the command line, then it forces non-global commands to run in the specified folder. + + #### \`preid\` * Default: "" @@ -1028,6 +1203,8 @@ forces non-global commands to run in the specified folder. The "prerelease identifier" to use as a prefix for the "prerelease" part of a semver. Like the \`rc\` in \`1.2.0-rc.8\`. + + #### \`progress\` * Default: \`true\` unless running in a known CI system @@ -1038,6 +1215,8 @@ operations, if \`process.stderr\` is a TTY. Set to \`false\` to suppress the progress bar. + + #### \`provenance\` * Default: false @@ -1046,6 +1225,17 @@ Set to \`false\` to suppress the progress bar. When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it was built and published from. +This config can not be used with: \`provenance-file\` + +#### \`provenance-file\` + +* Default: null +* Type: Path + +When publishing, the provenance bundle at the given path will be used. + +This config can not be used with: \`provenance\` + #### \`proxy\` * Default: null @@ -1055,6 +1245,8 @@ A proxy to use for outgoing http requests. If the \`HTTP_PROXY\` or \`http_proxy\` environment variables are set, proxy settings will be honored by the underlying \`request\` library. + + #### \`read-only\` * Default: false @@ -1063,6 +1255,8 @@ by the underlying \`request\` library. This is used to mark a token as unable to publish when configuring limited access tokens with the \`npm token create\` command. + + #### \`rebuild-bundle\` * Default: true @@ -1070,6 +1264,8 @@ access tokens with the \`npm token create\` command. Rebuild bundled dependencies after installation. + + #### \`registry\` * Default: "https://registry.npmjs.org/" @@ -1077,6 +1273,8 @@ Rebuild bundled dependencies after installation. The base URL of the npm registry. + + #### \`replace-registry-host\` * Default: "npmjs" @@ -1092,6 +1290,8 @@ registry host with the configured host every time. You may also specify a bare hostname (e.g., "registry.npmjs.org"). + + #### \`save\` * Default: \`true\` unless when using \`npm update\` where it defaults to \`false\` @@ -1104,6 +1304,8 @@ When used with the \`npm rm\` command, removes the dependency from Will also prevent writing to \`package-lock.json\` if set to \`false\`. + + #### \`save-bundle\` * Default: false @@ -1115,6 +1317,8 @@ If a package would be saved at install time by the use of \`--save\`, Ignored if \`--save-peer\` is set, since peerDependencies cannot be bundled. + + #### \`save-dev\` * Default: false @@ -1122,6 +1326,8 @@ Ignored if \`--save-peer\` is set, since peerDependencies cannot be bundled. Save installed packages to a package.json file as \`devDependencies\`. + + #### \`save-exact\` * Default: false @@ -1130,6 +1336,8 @@ Save installed packages to a package.json file as \`devDependencies\`. Dependencies saved to package.json will be configured with an exact version rather than using npm's default semver range operator. + + #### \`save-optional\` * Default: false @@ -1137,6 +1345,8 @@ rather than using npm's default semver range operator. Save installed packages to a package.json file as \`optionalDependencies\`. + + #### \`save-peer\` * Default: false @@ -1144,6 +1354,8 @@ Save installed packages to a package.json file as \`optionalDependencies\`. Save installed packages to a package.json file as \`peerDependencies\` + + #### \`save-prefix\` * Default: "^" @@ -1157,6 +1369,8 @@ to \`^1.2.3\` which allows minor upgrades for that package, but after \`npm config set save-prefix='~'\` it would be set to \`~1.2.3\` which only allows patch upgrades. + + #### \`save-prod\` * Default: false @@ -1169,6 +1383,8 @@ you want to move it to be a non-optional production dependency. This is the default behavior if \`--save\` is true, and neither \`--save-dev\` or \`--save-optional\` are true. + + #### \`scope\` * Default: the scope of the current project, if any, or "" @@ -1199,6 +1415,7 @@ npm init --scope=@foo --yes \`\`\` + #### \`script-shell\` * Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows @@ -1207,6 +1424,8 @@ npm init --scope=@foo --yes The shell to use for scripts run with the \`npm exec\`, \`npm run\` and \`npm init \` commands. + + #### \`searchexclude\` * Default: "" @@ -1214,6 +1433,8 @@ init \` commands. Space-separated options that limit the results from search. + + #### \`searchlimit\` * Default: 20 @@ -1222,6 +1443,8 @@ Space-separated options that limit the results from search. Number of items to limit search results to. Will not apply at all to legacy searches. + + #### \`searchopts\` * Default: "" @@ -1229,6 +1452,8 @@ searches. Space-separated options that are always passed to search. + + #### \`searchstaleness\` * Default: 900 @@ -1237,6 +1462,8 @@ Space-separated options that are always passed to search. The age of the cache, in seconds, before another registry request is made if using legacy search endpoint. + + #### \`shell\` * Default: SHELL environment variable, or "bash" on Posix, or "cmd.exe" on @@ -1245,6 +1472,8 @@ using legacy search endpoint. The shell to run for the \`npm explore\` command. + + #### \`sign-git-commit\` * Default: false @@ -1256,6 +1485,8 @@ version using \`-S\` to add a signature. Note that git requires you to have set up GPG keys in your git configs for this to work properly. + + #### \`sign-git-tag\` * Default: false @@ -1267,6 +1498,8 @@ If set to true, then the \`npm version\` command will tag the version using Note that git requires you to have set up GPG keys in your git configs for this to work properly. + + #### \`strict-peer-deps\` * Default: false @@ -1286,6 +1519,8 @@ When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \`--strict-peer-deps\` is set, then this warning is treated as a failure. + + #### \`strict-ssl\` * Default: true @@ -1296,6 +1531,8 @@ via https. See also the \`ca\` config. + + #### \`tag\` * Default: "latest" @@ -1310,6 +1547,8 @@ command, if no explicit tag is given. When used by the \`npm diff\` command, this is the tag used to fetch the tarball that will be compared with the local files by default. + + #### \`tag-version-prefix\` * Default: "v" @@ -1323,6 +1562,8 @@ Because other tools may rely on the convention that npm version tags look like \`v1.0.0\`, _only use this property if it is absolutely necessary_. In particular, use care when overriding this setting for public packages. + + #### \`timing\` * Default: false @@ -1337,6 +1578,8 @@ You can quickly view it with this [json](https://npm.im/json) command line: Timing information will also be reported in the terminal. To suppress this while still writing the timing file, use \`--silent\`. + + #### \`umask\` * Default: 0 @@ -1357,6 +1600,8 @@ Thus, the effective default umask value on most POSIX systems is 0o22, meaning that folders and executables are created with a mode of 0o755 and other files are created with a mode of 0o644. + + #### \`unicode\` * Default: false on windows, true on mac/unix systems with a unicode locale, @@ -1366,6 +1611,8 @@ other files are created with a mode of 0o644. When set to true, npm uses unicode characters in the tree output. When false, it uses ascii characters instead of unicode glyphs. + + #### \`update-notifier\` * Default: true @@ -1374,6 +1621,8 @@ false, it uses ascii characters instead of unicode glyphs. Set to false to suppress the update notification when using an older version of npm than the latest. + + #### \`usage\` * Default: false @@ -1381,6 +1630,8 @@ of npm than the latest. Show short usage output about the command specified. + + #### \`user-agent\` * Default: "npm/{npm-version} node/{node-version} {platform} {arch} @@ -1399,6 +1650,8 @@ their actual counterparts: * \`{ci}\` - The value of the \`ci-name\` config, if set, prefixed with \`ci/\`, or an empty string if \`ci-name\` is empty. + + #### \`userconfig\` * Default: "~/.npmrc" @@ -1410,6 +1663,8 @@ This may be overridden by the \`npm_config_userconfig\` environment variable or the \`--userconfig\` command line option, but may _not_ be overridden by settings in the \`globalconfig\` file. + + #### \`version\` * Default: false @@ -1419,6 +1674,8 @@ If true, output the npm version and exit successfully. Only relevant when specified explicitly on the command line. + + #### \`versions\` * Default: false @@ -1430,6 +1687,8 @@ exists, and exit successfully. Only relevant when specified explicitly on the command line. + + #### \`viewer\` * Default: "man" on Posix, "browser" on Windows @@ -1439,6 +1698,8 @@ The program to use to view help content. Set to \`"browser"\` to view html help content in the default web browser. + + #### \`which\` * Default: null @@ -1446,6 +1707,8 @@ Set to \`"browser"\` to view html help content in the default web browser. If there are multiple funding sources, which 1-indexed source URL to open. + + #### \`workspace\` * Default: @@ -1494,6 +1757,8 @@ This value is not exported to the environment for child processes. If set to true, the npm cli will run an update after operations that may possibly change the workspaces installed to the \`node_modules\` folder. + + #### \`yes\` * Default: null @@ -1502,6 +1767,8 @@ possibly change the workspaces installed to the \`node_modules\` folder. Automatically answer "yes" to any prompts that npm might print on the command line. + + #### \`also\` * Default: null @@ -1510,6 +1777,8 @@ command line. When set to \`dev\` or \`development\`, this is an alias for \`--include=dev\`. + + #### \`cache-max\` * Default: Infinity @@ -1518,6 +1787,8 @@ When set to \`dev\` or \`development\`, this is an alias for \`--include=dev\`. \`--cache-max=0\` is an alias for \`--prefer-online\` + + #### \`cache-min\` * Default: 0 @@ -1526,6 +1797,8 @@ When set to \`dev\` or \`development\`, this is an alias for \`--include=dev\`. \`--cache-min=9999 (or bigger)\` is an alias for \`--prefer-offline\`. + + #### \`cert\` * Default: null @@ -1547,6 +1820,8 @@ It is _not_ the path to a certificate file, though you can set a registry-scoped "certfile" path like "//other-registry.tld/:certfile=/path/to/cert.pem". + + #### \`ci-name\` * Default: The name of the current CI system, or \`null\` when not on a known CI @@ -1559,6 +1834,8 @@ The name of a continuous integration system. If not set explicitly, npm will detect the current CI environment using the [\`ci-info\`](http://npm.im/ci-info) module. + + #### \`dev\` * Default: false @@ -1567,6 +1844,8 @@ detect the current CI environment using the Alias for \`--include=dev\`. + + #### \`global-style\` * Default: false @@ -1577,6 +1856,8 @@ Alias for \`--include=dev\`. Only install direct dependencies in the top level \`node_modules\`, but hoist on deeper dependencies. Sets \`--install-strategy=shallow\`. + + #### \`init.author.email\` * Default: "" @@ -1585,6 +1866,8 @@ on deeper dependencies. Sets \`--install-strategy=shallow\`. Alias for \`--init-author-email\` + + #### \`init.author.name\` * Default: "" @@ -1593,6 +1876,8 @@ Alias for \`--init-author-email\` Alias for \`--init-author-name\` + + #### \`init.author.url\` * Default: "" @@ -1601,6 +1886,8 @@ Alias for \`--init-author-name\` Alias for \`--init-author-url\` + + #### \`init.license\` * Default: "ISC" @@ -1609,6 +1896,8 @@ Alias for \`--init-author-url\` Alias for \`--init-license\` + + #### \`init.module\` * Default: "~/.npm-init.js" @@ -1617,6 +1906,8 @@ Alias for \`--init-license\` Alias for \`--init-module\` + + #### \`init.version\` * Default: "1.0.0" @@ -1625,6 +1916,8 @@ Alias for \`--init-module\` Alias for \`--init-version\` + + #### \`key\` * Default: null @@ -1644,6 +1937,8 @@ key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----" It is _not_ the path to a key file, though you can set a registry-scoped "keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem". + + #### \`legacy-bundling\` * Default: false @@ -1656,6 +1951,8 @@ the same manner that they are depended on. This may cause very deep directory structures and duplicate package installs as there is no de-duplicating. Sets \`--install-strategy=nested\`. + + #### \`only\` * Default: null @@ -1664,6 +1961,8 @@ de-duplicating. Sets \`--install-strategy=nested\`. When set to \`prod\` or \`production\`, this is an alias for \`--omit=dev\`. + + #### \`optional\` * Default: null @@ -1675,6 +1974,8 @@ Default value does install optional deps unless otherwise omitted. Alias for --include=optional or --omit=optional + + #### \`production\` * Default: null @@ -1683,6 +1984,8 @@ Alias for --include=optional or --omit=optional Alias for \`--omit=dev\` + + #### \`shrinkwrap\` * Default: true @@ -1691,6 +1994,8 @@ Alias for \`--omit=dev\` Alias for --package-lock + + #### \`tmp\` * Default: The value returned by the Node.js \`os.tmpdir()\` method @@ -1702,6 +2007,8 @@ Alias for --package-lock Historically, the location where temporary files were stored. No longer relevant. + + ` exports[`test/lib/docs.js TAP config > all keys 1`] = ` @@ -1804,6 +2111,7 @@ Array [ "package-lock-only", "pack-destination", "parseable", + "prefer-dedupe", "prefer-offline", "prefer-online", "prefix", @@ -1811,6 +2119,7 @@ Array [ "production", "progress", "provenance", + "provenance-file", "proxy", "read-only", "rebuild-bundle", @@ -1940,12 +2249,14 @@ Array [ "package-lock-only", "pack-destination", "parseable", + "prefer-dedupe", "prefer-offline", "prefer-online", "preid", "production", "progress", "provenance", + "provenance-file", "proxy", "read-only", "rebuild-bundle", @@ -2015,6 +2326,129 @@ Array [ ] ` +exports[`test/lib/docs.js TAP flat options > full flat options object 1`] = ` +Object { + "_auth": null, + "access": null, + "all": false, + "allowSameVersion": false, + "audit": true, + "auditLevel": null, + "authType": "web", + "before": null, + "binLinks": true, + "browser": null, + "ca": null, + "cache": "{CWD}/cache/_cacache", + "call": "", + "cert": null, + "cidr": null, + "ciName": "{ci}", + "color": false, + "commitHooks": true, + "defaultTag": "latest", + "depth": null, + "diff": Array [], + "diffDstPrefix": "b/", + "diffIgnoreAllSpace": false, + "diffNameOnly": false, + "diffNoPrefix": false, + "diffSrcPrefix": "a/", + "diffText": false, + "diffUnified": 3, + "dryRun": false, + "editor": "{EDITOR}", + "engineStrict": false, + "force": false, + "foregroundScripts": false, + "formatPackageLock": true, + "fund": true, + "git": "git", + "gitTagVersion": true, + "global": false, + "globalconfig": "{CWD}/global/etc/npmrc", + "hashAlgorithm": "sha1", + "heading": "npm", + "httpsProxy": null, + "ifPresent": false, + "ignoreScripts": false, + "includeStaged": false, + "includeWorkspaceRoot": false, + "installLinks": false, + "installStrategy": "hoisted", + "json": false, + "key": null, + "legacyPeerDeps": false, + "localAddress": null, + "location": "user", + "lockfileVersion": null, + "logColor": false, + "maxSockets": 15, + "message": "%s", + "nodeBin": "{NODE}", + "nodeVersion": "2.2.2", + "noProxy": "", + "npmBin": "{CWD}/{TESTDIR}/docs.js", + "npmCommand": "version", + "npmVersion": "1.1.1", + "npxCache": "{CWD}/cache/_npx", + "offline": false, + "omit": Array [], + "omitLockfileRegistryResolved": false, + "otp": null, + "package": Array [], + "packageLock": true, + "packageLockOnly": false, + "packDestination": ".", + "parseable": false, + "preferDedupe": false, + "preferOffline": false, + "preferOnline": false, + "preid": "", + "progress": false, + "projectScope": "", + "provenance": false, + "provenanceFile": null, + "proxy": null, + "readOnly": false, + "rebuildBundle": true, + "registry": "https://registry.npmjs.org/", + "replaceRegistryHost": "npmjs", + "retry": Object { + "factor": 10, + "maxTimeout": 60000, + "minTimeout": 10000, + "retries": 0, + }, + "save": true, + "saveBundle": false, + "savePrefix": "^", + "scope": "", + "scriptShell": undefined, + "search": Object { + "description": true, + "exclude": "", + "limit": 20, + "opts": Null Object {}, + "staleness": 900, + }, + "shell": "{SHELL}", + "signGitCommit": false, + "signGitTag": false, + "silent": false, + "strictPeerDeps": false, + "strictSSL": true, + "tagVersionPrefix": "v", + "timeout": 300000, + "tufCache": "{CWD}/cache/_tuf", + "umask": 0, + "unicode": false, + "userAgent": "npm/1.1.1 node/2.2.2 {PLATFORM} {ARCH} workspaces/false ci/{ci}", + "workspacesEnabled": true, + "workspacesUpdate": true, +} +` + exports[`test/lib/docs.js TAP shorthands > docs 1`] = ` * \`-a\`: \`--all\` * \`--enjoy-by\`: \`--before\` @@ -2215,8 +2649,8 @@ npm ci Options: [--install-strategy ] [--legacy-bundling] [--global-style] [--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] -[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] +[--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit] +[--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] [--include-workspace-root] [--install-links] @@ -2235,7 +2669,6 @@ aliases: clean-install, ic, install-clean, isntall-clean #### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` -#### \`package-lock\` #### \`foreground-scripts\` #### \`ignore-scripts\` #### \`audit\` @@ -2641,6 +3074,9 @@ Get a value from the npm configuration Usage: npm get [ ...] (See \`npm config\`) +Options: +[-l|--long] + Run "npm help get" for more info \`\`\`bash @@ -2649,7 +3085,7 @@ npm get [ ...] (See \`npm config\`) Note: This command is unaware of workspaces. -NO PARAMS +#### \`long\` ` exports[`test/lib/docs.js TAP usage help > must match snapshot 1`] = ` @@ -2766,7 +3202,7 @@ Options: [-E|--save-exact] [-g|--global] [--install-strategy ] [--legacy-bundling] [--global-style] [--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] +[--strict-peer-deps] [--prefer-dedupe] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] [--include-workspace-root] [--install-links] @@ -2789,6 +3225,7 @@ aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall #### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` +#### \`prefer-dedupe\` #### \`package-lock\` #### \`foreground-scripts\` #### \`ignore-scripts\` @@ -2811,8 +3248,8 @@ npm install-ci-test Options: [--install-strategy ] [--legacy-bundling] [--global-style] [--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] -[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] +[--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit] +[--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] [--include-workspace-root] [--install-links] @@ -2831,7 +3268,6 @@ aliases: cit, clean-install-test, sit #### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` -#### \`package-lock\` #### \`foreground-scripts\` #### \`ignore-scripts\` #### \`audit\` @@ -2855,7 +3291,7 @@ Options: [-E|--save-exact] [-g|--global] [--install-strategy ] [--legacy-bundling] [--global-style] [--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] +[--strict-peer-deps] [--prefer-dedupe] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] [--include-workspace-root] [--install-links] @@ -2878,6 +3314,7 @@ alias: it #### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` +#### \`prefer-dedupe\` #### \`package-lock\` #### \`foreground-scripts\` #### \`ignore-scripts\` @@ -3328,7 +3765,8 @@ npm publish Options: [--tag ] [--access ] [--dry-run] [--otp ] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--provenance] +[-ws|--workspaces] [--include-workspace-root] +[--provenance|--provenance-file ] Run "npm help publish" for more info @@ -3344,6 +3782,7 @@ npm publish #### \`workspaces\` #### \`include-workspace-root\` #### \`provenance\` +#### \`provenance-file\` ` exports[`test/lib/docs.js TAP usage query > must match snapshot 1`] = ` @@ -3535,6 +3974,9 @@ Set a value in the npm configuration Usage: npm set = [= ...] (See \`npm config\`) +Options: +[-g|--global] [-L|--location ] + Run "npm help set" for more info \`\`\`bash @@ -3543,7 +3985,8 @@ npm set = [= ...] (See \`npm config\`) Note: This command is unaware of workspaces. -NO PARAMS +#### \`global\` +#### \`location\` ` exports[`test/lib/docs.js TAP usage shrinkwrap > must match snapshot 1`] = ` @@ -3733,6 +4176,7 @@ npm uninstall [<@scope>/]... Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] +[-g|--global] [-w|--workspace [-w|--workspace ...]] [-ws|--workspaces] [--include-workspace-root] [--install-links] @@ -3747,6 +4191,7 @@ aliases: unlink, remove, rm, r, un \`\`\` #### \`save\` +#### \`global\` #### \`workspace\` #### \`workspaces\` #### \`include-workspace-root\` diff --git a/deps/npm/tap-snapshots/test/lib/utils/config/definition.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/config/definition.js.test.cjs index ad506ae8e3585c..bf4dc30a041f77 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/config/definition.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/config/definition.js.test.cjs @@ -15,6 +15,8 @@ exports[`test/lib/utils/config/definition.js TAP basic definition > description it should not be used ever not even once. + + ` exports[`test/lib/utils/config/definition.js TAP basic definition > human-readable description 1`] = ` @@ -24,6 +26,8 @@ exports[`test/lib/utils/config/definition.js TAP basic definition > human-readab * Type: Number or String just a test thingie + + ` exports[`test/lib/utils/config/definition.js TAP long description > cols=-1 1`] = ` @@ -93,6 +97,7 @@ with (multiple) { } \`\`\` + ` exports[`test/lib/utils/config/definition.js TAP long description > cols=0 1`] = ` @@ -162,6 +167,7 @@ with (multiple) { } \`\`\` + ` exports[`test/lib/utils/config/definition.js TAP long description > cols=40 1`] = ` @@ -201,6 +207,7 @@ with (multiple) { } \`\`\` + ` exports[`test/lib/utils/config/definition.js TAP long description > cols=9000 1`] = ` @@ -231,6 +238,7 @@ with (multiple) { } \`\`\` + ` exports[`test/lib/utils/config/definition.js TAP long description > cols=NaN 1`] = ` @@ -261,4 +269,5 @@ with (multiple) { } \`\`\` + ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs index 8550617eb0a00a..876cc6552b7605 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs @@ -5,7 +5,7 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/utils/explain-dep.js TAP > ellipses test one 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic > ellipses test one 1`] = ` manydep@1.0.0 manydep@"1.0.0" from prod-dep@1.2.3 node_modules/prod-dep @@ -13,7 +13,7 @@ manydep@1.0.0 7 more (optdep, extra-neos, deep-dev, peer, the root project, ...) ` -exports[`test/lib/utils/explain-dep.js TAP > ellipses test two 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic > ellipses test two 1`] = ` manydep@1.0.0 manydep@"1.0.0" from prod-dep@1.2.3 node_modules/prod-dep @@ -21,29 +21,29 @@ manydep@1.0.0 6 more (optdep, extra-neos, deep-dev, peer, the root project, a package with a pretty long name) ` -exports[`test/lib/utils/explain-dep.js TAP bundled > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic bundled > explain color deep 1`] = ` bundle-of-joy@1.0.0 bundled node_modules/bundle-of-joy bundled prod-dep@"1.x" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP bundled > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic bundled > explain nocolor shallow 1`] = ` bundle-of-joy@1.0.0 bundled node_modules/bundle-of-joy bundled prod-dep@"1.x" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP bundled > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic bundled > print color 1`] = ` bundle-of-joy@1.0.0 bundled node_modules/bundle-of-joy ` -exports[`test/lib/utils/explain-dep.js TAP bundled > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic bundled > print nocolor 1`] = ` bundle-of-joy@1.0.0 bundled node_modules/bundle-of-joy ` -exports[`test/lib/utils/explain-dep.js TAP deepDev > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic deepDev > explain color deep 1`] = ` deep-dev@2.3.4 dev node_modules/deep-dev deep-dev@"2.x" from metadev@3.4.5 @@ -53,7 +53,7 @@ exports[`test/lib/utils/explain-dep.js TAP deepDev > explain color deep 1`] = ` dev topdev@"4.x" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP deepDev > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic deepDev > explain nocolor shallow 1`] = ` deep-dev@2.3.4 dev node_modules/deep-dev deep-dev@"2.x" from metadev@3.4.5 @@ -62,37 +62,37 @@ node_modules/deep-dev node_modules/topdev ` -exports[`test/lib/utils/explain-dep.js TAP deepDev > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic deepDev > print color 1`] = ` deep-dev@2.3.4 dev node_modules/deep-dev ` -exports[`test/lib/utils/explain-dep.js TAP deepDev > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic deepDev > print nocolor 1`] = ` deep-dev@2.3.4 dev node_modules/deep-dev ` -exports[`test/lib/utils/explain-dep.js TAP extraneous > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic extraneous > explain color deep 1`] = ` extra-neos@1337.420.69-lol extraneous node_modules/extra-neos ` -exports[`test/lib/utils/explain-dep.js TAP extraneous > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic extraneous > explain nocolor shallow 1`] = ` extra-neos@1337.420.69-lol extraneous node_modules/extra-neos ` -exports[`test/lib/utils/explain-dep.js TAP extraneous > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic extraneous > print color 1`] = ` extra-neos@1337.420.69-lol extraneous node_modules/extra-neos ` -exports[`test/lib/utils/explain-dep.js TAP extraneous > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic extraneous > print nocolor 1`] = ` extra-neos@1337.420.69-lol extraneous node_modules/extra-neos ` -exports[`test/lib/utils/explain-dep.js TAP manyDeps > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > explain color deep 1`] = ` manydep@1.0.0 manydep@"1.0.0" from prod-dep@1.2.3 node_modules/prod-dep @@ -118,7 +118,7 @@ exports[`test/lib/utils/explain-dep.js TAP manyDeps > explain color deep 1`] = ` manydep@"1" from yet another a package with a pretty long name@1.2.3 ` -exports[`test/lib/utils/explain-dep.js TAP manyDeps > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > explain nocolor shallow 1`] = ` manydep@1.0.0 manydep@"1.0.0" from prod-dep@1.2.3 node_modules/prod-dep @@ -126,103 +126,103 @@ manydep@1.0.0 8 more (optdep, extra-neos, deep-dev, peer, the root project, ...) ` -exports[`test/lib/utils/explain-dep.js TAP manyDeps > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > print color 1`] = ` manydep@1.0.0 ` -exports[`test/lib/utils/explain-dep.js TAP manyDeps > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > print nocolor 1`] = ` manydep@1.0.0 ` -exports[`test/lib/utils/explain-dep.js TAP optional > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic optional > explain color deep 1`] = ` optdep@1.0.0 optional node_modules/optdep optional optdep@"1.0.0" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP optional > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic optional > explain nocolor shallow 1`] = ` optdep@1.0.0 optional node_modules/optdep optional optdep@"1.0.0" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP optional > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic optional > print color 1`] = ` optdep@1.0.0 optional node_modules/optdep ` -exports[`test/lib/utils/explain-dep.js TAP optional > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic optional > print nocolor 1`] = ` optdep@1.0.0 optional node_modules/optdep ` -exports[`test/lib/utils/explain-dep.js TAP overridden > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic overridden > explain color deep 1`] = ` overridden-root@1.0.0 overridden node_modules/overridden-root overridden overridden-dep@"1.0.0" (was "^2.0.0") from the root project ` -exports[`test/lib/utils/explain-dep.js TAP overridden > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic overridden > explain nocolor shallow 1`] = ` overridden-root@1.0.0 overridden node_modules/overridden-root overridden overridden-dep@"1.0.0" (was "^2.0.0") from the root project ` -exports[`test/lib/utils/explain-dep.js TAP overridden > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic overridden > print color 1`] = ` overridden-root@1.0.0 overridden node_modules/overridden-root ` -exports[`test/lib/utils/explain-dep.js TAP overridden > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic overridden > print nocolor 1`] = ` overridden-root@1.0.0 overridden node_modules/overridden-root ` -exports[`test/lib/utils/explain-dep.js TAP peer > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic peer > explain color deep 1`] = ` peer@1.0.0 peer node_modules/peer peer peer@"1.0.0" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP peer > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic peer > explain nocolor shallow 1`] = ` peer@1.0.0 peer node_modules/peer peer peer@"1.0.0" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP peer > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic peer > print color 1`] = ` peer@1.0.0 peer node_modules/peer ` -exports[`test/lib/utils/explain-dep.js TAP peer > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic peer > print nocolor 1`] = ` peer@1.0.0 peer node_modules/peer ` -exports[`test/lib/utils/explain-dep.js TAP prodDep > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic prodDep > explain color deep 1`] = ` prod-dep@1.2.3 node_modules/prod-dep prod-dep@"1.x" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP prodDep > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic prodDep > explain nocolor shallow 1`] = ` prod-dep@1.2.3 node_modules/prod-dep prod-dep@"1.x" from the root project ` -exports[`test/lib/utils/explain-dep.js TAP prodDep > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic prodDep > print color 1`] = ` prod-dep@1.2.3 node_modules/prod-dep ` -exports[`test/lib/utils/explain-dep.js TAP prodDep > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic prodDep > print nocolor 1`] = ` prod-dep@1.2.3 node_modules/prod-dep ` -exports[`test/lib/utils/explain-dep.js TAP workspaces > explain color deep 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic workspaces > explain color deep 1`] = ` a@1.0.0 a a@1.0.0 @@ -230,7 +230,7 @@ exports[`test/lib/utils/explain-dep.js TAP workspaces > explain color deep 1`] = workspace a from the root project ` -exports[`test/lib/utils/explain-dep.js TAP workspaces > explain nocolor shallow 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic workspaces > explain nocolor shallow 1`] = ` a@1.0.0 a a@1.0.0 @@ -238,12 +238,12 @@ a workspace a from the root project ` -exports[`test/lib/utils/explain-dep.js TAP workspaces > print color 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic workspaces > print color 1`] = ` a@1.0.0 a ` -exports[`test/lib/utils/explain-dep.js TAP workspaces > print nocolor 1`] = ` +exports[`test/lib/utils/explain-dep.js TAP basic workspaces > print nocolor 1`] = ` a@1.0.0 a ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs index 99ad5c0f31e900..3d73019d3e45b9 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs @@ -5,7 +5,7 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/utils/explain-eresolve.js TAP chain-conflict > explain with color, depth of 2 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > explain with color, depth of 2 1`] = ` While resolving: project@1.2.3 Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-d @@ -17,7 +17,7 @@ Could not resolve dependency: @isaacs/testing-peer-dep-conflict-chain-c@"1" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP chain-conflict > explain with no color, depth of 6 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > explain with no color, depth of 6 1`] = ` While resolving: project@1.2.3 Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-d @@ -29,7 +29,7 @@ node_modules/@isaacs/testing-peer-dep-conflict-chain-c @isaacs/testing-peer-dep-conflict-chain-c@"1" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP chain-conflict > report from color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > report from color 1`] = ` # npm resolution error report While resolving: project@1.2.3 @@ -47,7 +47,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP chain-conflict > report with color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > report with color 1`] = ` While resolving: project@1.2.3 Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-d @@ -63,7 +63,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP chain-conflict > report with no color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > report with no color 1`] = ` While resolving: project@1.2.3 Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-d @@ -79,7 +79,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP cycleNested > explain with color, depth of 2 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic cycleNested > explain with color, depth of 2 1`] = ` Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c @isaacs/peer-dep-cycle-c@"2.x" from the root project @@ -97,7 +97,7 @@ Conflicting peer dependency: @isaacs/peer-dep-cycle-c@1.0.0[2 node_modules/@isaacs/peer-dep-cycle-a ` -exports[`test/lib/utils/explain-eresolve.js TAP cycleNested > explain with no color, depth of 6 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic cycleNested > explain with no color, depth of 6 1`] = ` Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c @isaacs/peer-dep-cycle-c@"2.x" from the root project @@ -116,7 +116,7 @@ node_modules/@isaacs/peer-dep-cycle-c @isaacs/peer-dep-cycle-a@"1.x" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP cycleNested > report from color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic cycleNested > report from color 1`] = ` # npm resolution error report Found: @isaacs/peer-dep-cycle-c@2.0.0 @@ -141,7 +141,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP cycleNested > report with color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic cycleNested > report with color 1`] = ` Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c @isaacs/peer-dep-cycle-c@"2.x" from the root project @@ -164,7 +164,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP cycleNested > report with no color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic cycleNested > report with no color 1`] = ` Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c @isaacs/peer-dep-cycle-c@"2.x" from the root project @@ -187,7 +187,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP eslint-plugin case > explain with color, depth of 2 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > explain with color, depth of 2 1`] = ` While resolving: eslint-plugin-react@7.24.0 Found: eslint@6.8.0 node_modules/eslint @@ -204,7 +204,7 @@ Conflicting peer dependency: eslint@7.31.0 dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP eslint-plugin case > explain with no color, depth of 6 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > explain with no color, depth of 6 1`] = ` While resolving: eslint-plugin-react@7.24.0 Found: eslint@6.8.0 node_modules/eslint @@ -227,7 +227,7 @@ node_modules/eslint dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP eslint-plugin case > report from color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > report from color 1`] = ` # npm resolution error report While resolving: eslint-plugin-react@7.24.0 @@ -261,7 +261,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP eslint-plugin case > report with color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > report with color 1`] = ` While resolving: eslint-plugin-react@7.24.0 Found: eslint@6.8.0 node_modules/eslint @@ -285,7 +285,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP eslint-plugin case > report with no color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > report with no color 1`] = ` While resolving: eslint-plugin-react@7.24.0 Found: eslint@6.8.0 node_modules/eslint @@ -309,7 +309,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP gatsby > explain with color, depth of 2 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic gatsby > explain with color, depth of 2 1`] = ` While resolving: gatsby-recipes@0.2.31 Found: ink@3.0.0-7 node_modules/ink @@ -325,7 +325,7 @@ Could not resolve dependency: node_modules/gatsby-recipes ` -exports[`test/lib/utils/explain-eresolve.js TAP gatsby > explain with no color, depth of 6 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic gatsby > explain with no color, depth of 6 1`] = ` While resolving: gatsby-recipes@0.2.31 Found: ink@3.0.0-7 node_modules/ink @@ -349,7 +349,7 @@ node_modules/ink-box gatsby@"" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP gatsby > report from color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic gatsby > report from color 1`] = ` # npm resolution error report While resolving: gatsby-recipes@0.2.31 @@ -379,7 +379,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP gatsby > report with color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic gatsby > report with color 1`] = ` While resolving: gatsby-recipes@0.2.31 Found: ink@3.0.0-7 node_modules/ink @@ -406,7 +406,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP gatsby > report with no color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic gatsby > report with no color 1`] = ` While resolving: gatsby-recipes@0.2.31 Found: ink@3.0.0-7 node_modules/ink @@ -433,7 +433,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, but has current edge > explain with color, depth of 2 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > explain with color, depth of 2 1`] = ` While resolving: eslint@7.22.0 Found: dev eslint@"file:." from the root project @@ -443,7 +443,7 @@ Could not resolve dependency: dev eslint-plugin-jsdoc@"^22.1.0" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, but has current edge > explain with no color, depth of 6 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > explain with no color, depth of 6 1`] = ` While resolving: eslint@7.22.0 Found: dev eslint@"file:." from the root project @@ -453,7 +453,7 @@ node_modules/eslint-plugin-jsdoc dev eslint-plugin-jsdoc@"^22.1.0" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, but has current edge > report from color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > report from color 1`] = ` # npm resolution error report While resolving: eslint@7.22.0 @@ -469,7 +469,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, but has current edge > report with color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > report with color 1`] = ` While resolving: eslint@7.22.0 Found: dev eslint@"file:." from the root project @@ -483,7 +483,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, but has current edge > report with no color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > report with no color 1`] = ` While resolving: eslint@7.22.0 Found: dev eslint@"file:." from the root project @@ -497,7 +497,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, no current edge, idk > explain with color, depth of 2 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > explain with color, depth of 2 1`] = ` While resolving: eslint@7.22.0 Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc @@ -509,7 +509,7 @@ Could not resolve dependency: dev eslint-plugin-jsdoc@"^22.1.0" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, no current edge, idk > explain with no color, depth of 6 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > explain with no color, depth of 6 1`] = ` While resolving: eslint@7.22.0 Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc @@ -521,7 +521,7 @@ node_modules/eslint-plugin-jsdoc dev eslint-plugin-jsdoc@"^22.1.0" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, no current edge, idk > report from color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > report from color 1`] = ` # npm resolution error report While resolving: eslint@7.22.0 @@ -539,7 +539,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, no current edge, idk > report with color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > report with color 1`] = ` While resolving: eslint@7.22.0 Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc @@ -555,7 +555,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP no current node, no current edge, idk > report with no color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > report with no color 1`] = ` While resolving: eslint@7.22.0 Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc @@ -571,7 +571,7 @@ this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP withShrinkwrap > explain with color, depth of 2 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic withShrinkwrap > explain with color, depth of 2 1`] = ` While resolving: @isaacs/peer-dep-cycle-b@1.0.0 Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c @@ -584,7 +584,7 @@ Could not resolve dependency: node_modules/@isaacs/peer-dep-cycle-a ` -exports[`test/lib/utils/explain-eresolve.js TAP withShrinkwrap > explain with no color, depth of 6 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic withShrinkwrap > explain with no color, depth of 6 1`] = ` While resolving: @isaacs/peer-dep-cycle-b@1.0.0 Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c @@ -598,7 +598,7 @@ node_modules/@isaacs/peer-dep-cycle-b @isaacs/peer-dep-cycle-a@"1.x" from the root project ` -exports[`test/lib/utils/explain-eresolve.js TAP withShrinkwrap > report from color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic withShrinkwrap > report from color 1`] = ` # npm resolution error report While resolving: @isaacs/peer-dep-cycle-b@1.0.0 @@ -618,7 +618,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP withShrinkwrap > report with color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic withShrinkwrap > report with color 1`] = ` While resolving: @isaacs/peer-dep-cycle-b@1.0.0 Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c @@ -636,7 +636,7 @@ this command with --no-strict-peer-deps, --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. ` -exports[`test/lib/utils/explain-eresolve.js TAP withShrinkwrap > report with no color 1`] = ` +exports[`test/lib/utils/explain-eresolve.js TAP basic withShrinkwrap > report with no color 1`] = ` While resolving: @isaacs/peer-dep-cycle-b@1.0.0 Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c diff --git a/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs index 8af3c475c7720c..968b14a20d90f5 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs @@ -6,20 +6,10 @@ */ 'use strict' exports[`test/lib/utils/open-url-prompt.js TAP opens a url > must match snapshot 1`] = ` -Array [ - Array [ - String( - npm home: - https://www.npmjs.com - ), - ], -] +npm home: +https://www.npmjs.com ` exports[`test/lib/utils/open-url-prompt.js TAP prints json output > must match snapshot 1`] = ` -Array [ - Array [ - "{\\"title\\":\\"npm home\\",\\"url\\":\\"https://www.npmjs.com\\"}", - ], -] +{"title":"npm home","url":"https://www.npmjs.com"} ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/reify-finish.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/reify-finish.js.test.cjs deleted file mode 100644 index a82905a399679a..00000000000000 --- a/deps/npm/tap-snapshots/test/lib/utils/reify-finish.js.test.cjs +++ /dev/null @@ -1,15 +0,0 @@ -/* IMPORTANT - * This snapshot file is auto-generated, but designed for humans. - * It should be checked into source control and tracked carefully. - * Re-generate by setting TAP_SNAPSHOT=1 and running tests. - * Make sure to inspect the output below. Do not ignore changes! - */ -'use strict' -exports[`test/lib/utils/reify-finish.js TAP should write if everything above passes > written config 1`] = ` -hasBuiltinConfig=true -x=y - -[nested] -foo=bar - -` diff --git a/deps/npm/test/bin/npx-cli.js b/deps/npm/test/bin/npx-cli.js index 5670f24f07b77a..67a8d3319fc18d 100644 --- a/deps/npm/test/bin/npx-cli.js +++ b/deps/npm/test/bin/npx-cli.js @@ -1,5 +1,5 @@ const t = require('tap') -const mockGlobals = require('../fixtures/mock-globals') +const mockGlobals = require('@npmcli/mock-globals') const tmock = require('../fixtures/tmock') const npm = require.resolve('../../bin/npm-cli.js') diff --git a/deps/npm/test/fixtures/libnpmsearch-stream-result.js b/deps/npm/test/fixtures/libnpmsearch-stream-result.js index b2ec20f59efebc..1ec8b7b113d6b8 100644 --- a/deps/npm/test/fixtures/libnpmsearch-stream-result.js +++ b/deps/npm/test/fixtures/libnpmsearch-stream-result.js @@ -216,7 +216,7 @@ module.exports = [ version: '1.0.1', description: 'Retrieves a name:pathname Map for a given workspaces config', keywords: [ - 'npm', + '\x1B[33mnpm\x1B[39m', 'npmcli', 'libnpm', 'cli', @@ -240,10 +240,10 @@ module.exports = [ ], }, { - name: 'libnpmversion', + name: '\x1B[31mlibnpmversion\x1B[39m', scope: 'unscoped', version: '1.0.7', - description: "library to do the things that 'npm version' does", + description: "library to do the things that '\x1B[32mnpm version\x1B[39m' does", date: '2020-11-04T00:21:41.069Z', links: { npm: 'https://www.npmjs.com/package/libnpmversion', @@ -259,7 +259,7 @@ module.exports = [ }, publisher: { username: 'isaacs', email: 'i@izs.me' }, maintainers: [ - { username: 'nlf', email: 'quitlahok@gmail.com' }, + { username: '\x1B[34mnlf\x1B[39m', email: 'quitlahok@gmail.com' }, { username: 'ruyadorno', email: 'ruyadorno@hotmail.com' }, { username: 'darcyclarke', email: 'darcy@darcyclarke.me' }, { username: 'isaacs', email: 'i@izs.me' }, diff --git a/deps/npm/test/fixtures/mock-globals.js b/deps/npm/test/fixtures/mock-globals.js deleted file mode 100644 index aec8a83963687a..00000000000000 --- a/deps/npm/test/fixtures/mock-globals.js +++ /dev/null @@ -1,236 +0,0 @@ -// An initial implementation for a feature that will hopefully exist in tap -// https://github.com/tapjs/node-tap/issues/789 -// This file is only used in tests but it is still tested itself. -// Hopefully it can be removed for a feature in tap in the future - -const sep = '.' -const escapeSep = '"' -const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k) -const opd = (o, k) => Object.getOwnPropertyDescriptor(o, k) -const po = (o) => Object.getPrototypeOf(o) -const pojo = (o) => Object.prototype.toString.call(o) === '[object Object]' -const last = (arr) => arr[arr.length - 1] -const dupes = (arr) => arr.filter((k, i) => arr.indexOf(k) !== i) -const dupesStartsWith = (arr) => arr.filter((k1) => arr.some((k2) => k2.startsWith(k1 + sep))) - -const splitLastSep = (str) => { - let escaped = false - for (let i = str.length - 1; i >= 0; i--) { - const c = str[i] - const cp = str[i + 1] - const cn = str[i - 1] - if (!escaped && c === escapeSep && (cp == null || cp === sep)) { - escaped = true - continue - } - if (escaped && c === escapeSep && cn === sep) { - escaped = false - continue - } - if (!escaped && c === sep) { - return [ - str.slice(0, i), - str.slice(i + 1).replace(new RegExp(`^${escapeSep}(.*)${escapeSep}$`), '$1'), - ] - } - } - return [str] -} - -// A weird getter that can look up keys on nested objects but also -// match keys with dots in their names, eg { 'process.env': { TERM: 'a' } } -// can be looked up with the key 'process.env.TERM' -const get = (obj, key, childKey = '') => { - if (has(obj, key)) { - return childKey ? get(obj[key], childKey) : obj[key] - } - const split = splitLastSep(key) - if (split.length === 2) { - const [parentKey, prefix] = split - return get( - obj, - parentKey, - prefix + (childKey && sep + childKey) - ) - } -} - -// Map an object to an array of nested keys separated by dots -// { a: 1, b: { c: 2, d: [1] } } => ['a', 'b.c', 'b.d'] -const getKeys = (values, p = '', acc = []) => - Object.entries(values).reduce((memo, [k, value]) => { - const key = p ? [p, k].join(sep) : k - return pojo(value) ? getKeys(value, key, memo) : memo.concat(key) - }, acc) - -// Walk prototype chain to get first available descriptor. This is necessary -// to get the current property descriptor for things like `process.on`. -// Since `opd(process, 'on') === undefined` but if you -// walk up the prototype chain you get the original descriptor -// `opd(po(po(process)), 'on') === { value, ... }` -const protoDescriptor = (obj, key) => { - let descriptor - // i always wanted to assign variables in a while loop's condition - // i thought it would feel better than this - while (!(descriptor = opd(obj, key))) { - if (!(obj = po(obj))) { - break - } - } - return descriptor -} - -// Path can be different cases across platform so get the original case -// of the path before anything is changed -// XXX: other special cases to handle? -const specialCaseKeys = (() => { - const originalKeys = { - PATH: process.env.PATH ? 'PATH' : process.env.Path ? 'Path' : 'path', - } - return (key) => { - switch (key.toLowerCase()) { - case 'process.env.path': - return originalKeys.PATH - } - } -})() - -const _setGlobal = Symbol('setGlobal') -const _nextDescriptor = Symbol('nextDescriptor') - -class DescriptorStack { - #stack = [] - #global = null - #valueKey = null - #defaultDescriptor = { configurable: true, writable: true, enumerable: true } - #delete = () => ({ DELETE: true }) - #isDelete = (o) => o && o.DELETE === true - - constructor (key) { - const keys = splitLastSep(key) - this.#global = keys.length === 1 ? global : get(global, keys[0]) - this.#valueKey = specialCaseKeys(key) || last(keys) - // If the global object doesnt return a descriptor for the key - // then we mark it for deletion on teardown - this.#stack = [ - protoDescriptor(this.#global, this.#valueKey) || this.#delete(), - ] - } - - add (value) { - // This must be a unique object so we can find it later via indexOf - // That's why delete/nextDescriptor create new objects - const nextDescriptor = this[_nextDescriptor](value) - this.#stack.push(this[_setGlobal](nextDescriptor)) - - return () => { - const index = this.#stack.indexOf(nextDescriptor) - // If the stack doesnt contain the descriptor anymore - // than do nothing. This keeps the reset function indempotent - if (index > -1) { - // Resetting removes a descriptor from the stack - this.#stack.splice(index, 1) - // But we always reset to what is now the most recent in case - // resets are being called manually out of order - this[_setGlobal](last(this.#stack)) - } - } - } - - reset () { - // Everything could be reset manually so only - // teardown if we have an initial descriptor left - // and then delete the rest of the stack - if (this.#stack.length) { - this[_setGlobal](this.#stack[0]) - this.#stack.length = 0 - } - } - - [_setGlobal] (d) { - if (this.#isDelete(d)) { - delete this.#global[this.#valueKey] - } else { - Object.defineProperty(this.#global, this.#valueKey, d) - } - return d - } - - [_nextDescriptor] (value) { - if (value === undefined) { - return this.#delete() - } - const d = last(this.#stack) - return { - // If the previous descriptor was one to delete the property - // then use the default descriptor as the base - ...(this.#isDelete(d) ? this.#defaultDescriptor : d), - ...(d && d.get ? { get: () => value } : { value }), - } - } -} - -class MockGlobals { - #descriptors = {} - - register (globals, { replace = false } = {}) { - // Replace means dont merge in object values but replace them instead - // so we only get top level keys instead of walking the obj - const keys = replace ? Object.keys(globals) : getKeys(globals) - - // An error state where due to object mode there are multiple global - // values to be set with the same key - const duplicates = dupes(keys) - if (duplicates.length) { - throw new Error(`mockGlobals was called with duplicate keys: ${duplicates}`) - } - - // Another error where when in replace mode overlapping keys are set like - // process and process.stdout which would cause unexpected behavior - const overlapping = dupesStartsWith(keys) - if (overlapping.length) { - const message = overlapping - .map((k) => `${k} -> ${keys.filter((kk) => kk.startsWith(k + sep))}`) - throw new Error(`mockGlobals was called with overlapping keys: ${message}`) - } - - // Set each property passed in and return fns to reset them - // Return an object with each path as a key for manually resetting in each test - return keys.reduce((acc, key) => { - const desc = this.#descriptors[key] || (this.#descriptors[key] = new DescriptorStack(key)) - acc[key] = desc.add(get(globals, key)) - return acc - }, {}) - } - - teardown (key) { - if (!key) { - Object.values(this.#descriptors).forEach((d) => d.reset()) - return - } - this.#descriptors[key].reset() - } -} - -// Each test has one instance of MockGlobals so it can be called multiple times per test -// Its a weak map so that it can be garbage collected along with the tap tests without -// needing to explicitly call cache.delete -const cache = new WeakMap() - -module.exports = (t, globals, options) => { - let instance = cache.get(t) - if (!instance) { - instance = cache.set(t, new MockGlobals()).get(t) - // Teardown only needs to be initialized once. The instance - // will keep track of its own state during the test - t.teardown(() => instance.teardown()) - } - - return { - // Reset contains only the functions to reset the globals - // set by this function call - reset: instance.register(globals, options), - // Teardown will reset across all calls tied to this test - teardown: () => instance.teardown(), - } -} diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js index a2d35c2479d733..b91ee8a3933a39 100644 --- a/deps/npm/test/fixtures/mock-npm.js +++ b/deps/npm/test/fixtures/mock-npm.js @@ -4,7 +4,7 @@ const path = require('path') const tap = require('tap') const errorMessage = require('../../lib/utils/error-message') const mockLogs = require('./mock-logs') -const mockGlobals = require('./mock-globals') +const mockGlobals = require('@npmcli/mock-globals') const tmock = require('./tmock') const defExitCode = process.exitCode @@ -113,6 +113,7 @@ const setupMockNpm = async (t, { // preload a command command = null, // string name of the command exec = null, // optionally exec the command before returning + setCmd = false, // test dirs prefixDir = {}, homeDir = {}, @@ -212,7 +213,7 @@ const setupMockNpm = async (t, { return acc }, { argv: [...rawArgv], env: {}, config: {} }) - mockGlobals(t, { + const mockedGlobals = mockGlobals(t, { 'process.env.HOME': dirs.home, // global prefix cannot be (easily) set via argv so this is the easiest way // to set it that also closely mimics the behavior a user would see since it @@ -251,16 +252,25 @@ const setupMockNpm = async (t, { const mockCommand = {} if (command) { - const cmd = await npm.cmd(command) - const usage = await cmd.usage - mockCommand.cmd = cmd + const Cmd = mockNpm.Npm.cmd(command) + if (setCmd) { + // XXX(hack): This is a hack to allow fake-ish tests to set the currently + // running npm command without running exec. Generally, we should rely on + // actually exec-ing the command to asserting the state of the world + // through what is printed/on disk/etc. This is a stop-gap to allow tests + // that are time intensive to convert to continue setting the npm command + // this way. TODO: remove setCmd from all tests and remove the setCmd + // method from `lib/npm.js` + npm.setCmd(command) + } + mockCommand.cmd = new Cmd(npm) mockCommand[command] = { - usage, + usage: Cmd.describeUsage, exec: (args) => npm.exec(command, args), - completion: (args) => cmd.completion(args), + completion: (args) => Cmd.completion(args, npm), } if (exec) { - await mockCommand[command].exec(exec) + await mockCommand[command].exec(exec === true ? [] : exec) // assign string output to the command now that we have it // for easier testing mockCommand[command].output = mockNpm.joinedOutput() @@ -269,6 +279,7 @@ const setupMockNpm = async (t, { return { npm, + mockedGlobals, ...mockNpm, ...dirs, ...mockCommand, diff --git a/deps/npm/test/fixtures/sandbox.js b/deps/npm/test/fixtures/sandbox.js index 460609628c8abb..01a5e562fd9b26 100644 --- a/deps/npm/test/fixtures/sandbox.js +++ b/deps/npm/test/fixtures/sandbox.js @@ -328,8 +328,8 @@ class Sandbox extends EventEmitter { this[_npm].output = (...args) => this[_output].push(args) await this[_npm].load() - const impl = await this[_npm].cmd(command) - return impl.completion({ + const Cmd = Npm.cmd(command) + return Cmd.completion({ partialWord: partial, conf: { argv: { diff --git a/deps/npm/test/lib/cli-entry.js b/deps/npm/test/lib/cli-entry.js new file mode 100644 index 00000000000000..b436304c30047a --- /dev/null +++ b/deps/npm/test/lib/cli-entry.js @@ -0,0 +1,168 @@ +const t = require('tap') +const { load: loadMockNpm } = require('../fixtures/mock-npm.js') +const tmock = require('../fixtures/tmock.js') +const validateEngines = require('../../lib/es6/validate-engines.js') + +const cliMock = async (t, opts) => { + let exitHandlerArgs = null + let npm = null + const exitHandlerMock = (...args) => { + exitHandlerArgs = args + npm.unload() + } + exitHandlerMock.setNpm = _npm => npm = _npm + + const { Npm, outputs, logMocks, logs } = await loadMockNpm(t, { ...opts, init: false }) + const cli = tmock(t, '{LIB}/cli-entry.js', { + '{LIB}/npm.js': Npm, + '{LIB}/utils/exit-handler.js': exitHandlerMock, + ...logMocks, + }) + + return { + Npm, + cli: (p) => validateEngines(p, () => cli), + outputs, + exitHandlerCalled: () => exitHandlerArgs, + exitHandlerNpm: () => npm, + logs, + logsBy: (title) => logs.verbose.filter(([p]) => p === title).map(([p, ...rest]) => rest), + } +} + +t.test('print the version, and treat npm_g as npm -g', async t => { + const { logsBy, logs, cli, Npm, outputs, exitHandlerCalled } = await cliMock(t, { + globals: { 'process.argv': ['node', 'npm_g', '-v'] }, + }) + await cli(process) + + t.strictSame(process.argv, ['node', 'npm', '-g', '-v'], 'system process.argv was rewritten') + t.strictSame(logsBy('cli'), [['node npm']]) + t.strictSame(logsBy('title'), [['npm']]) + t.match(logsBy('argv'), [['"--global" "--version"']]) + t.strictSame(logs.info, [ + ['using', 'npm@%s', Npm.version], + ['using', 'node@%s', process.version], + ]) + t.equal(outputs.length, 1) + t.strictSame(outputs, [[Npm.version]]) + t.strictSame(exitHandlerCalled(), []) +}) + +t.test('calling with --versions calls npm version with no args', async t => { + const { logsBy, cli, outputs, exitHandlerCalled } = await cliMock(t, { + globals: { + 'process.argv': ['node', 'npm', 'install', 'or', 'whatever', '--versions'], + }, + }) + await cli(process) + + t.equal(process.title, 'npm install or whatever') + t.strictSame(logsBy('cli'), [['node npm']]) + t.strictSame(logsBy('title'), [['npm install or whatever']]) + t.match(logsBy('argv'), [['"install" "or" "whatever" "--versions"']]) + t.equal(outputs.length, 1) + t.match(outputs[0][0], { npm: String, node: String, v8: String }) + t.strictSame(exitHandlerCalled(), []) +}) + +t.test('logged argv is sanitized', async t => { + const { logsBy, cli } = await cliMock(t, { + globals: { + 'process.argv': [ + 'node', + 'npm', + 'version', + '--registry', + 'https://u:password@npmjs.org/password', + ], + }, + }) + + await cli(process) + t.equal(process.title, 'npm version') + t.strictSame(logsBy('cli'), [['node npm']]) + t.strictSame(logsBy('title'), [['npm version']]) + t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/password"']]) +}) + +t.test('logged argv is sanitized with equals', async t => { + const { logsBy, cli } = await cliMock(t, { + globals: { + 'process.argv': [ + 'node', + 'npm', + 'version', + '--registry=https://u:password@npmjs.org', + ], + }, + }) + await cli(process) + + t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/"']]) +}) + +t.test('print usage if no params provided', async t => { + const { cli, outputs, exitHandlerCalled, exitHandlerNpm } = await cliMock(t, { + globals: { + 'process.argv': ['node', 'npm'], + }, + }) + await cli(process) + + t.match(outputs[0][0], 'Usage:', 'outputs npm usage') + t.match(exitHandlerCalled(), [], 'should call exitHandler with no args') + t.ok(exitHandlerNpm(), 'exitHandler npm is set') + t.match(process.exitCode, 1) +}) + +t.test('print usage if non-command param provided', async t => { + const { cli, outputs, exitHandlerCalled, exitHandlerNpm } = await cliMock(t, { + globals: { + 'process.argv': ['node', 'npm', 'tset'], + }, + }) + await cli(process) + + t.match(outputs[0][0], 'Unknown command: "tset"') + t.match(outputs[0][0], 'Did you mean this?') + t.match(exitHandlerCalled(), [], 'should call exitHandler with no args') + t.ok(exitHandlerNpm(), 'exitHandler npm is set') + t.match(process.exitCode, 1) +}) + +t.test('load error calls error handler', async t => { + const err = new Error('test load error') + const { cli, exitHandlerCalled } = await cliMock(t, { + mocks: { + '{LIB}/utils/config/index.js': { + definitions: null, + flatten: null, + shorthands: null, + }, + '@npmcli/config': class BadConfig { + async load () { + throw err + } + }, + }, + globals: { + 'process.argv': ['node', 'npm', 'asdf'], + }, + }) + await cli(process) + t.strictSame(exitHandlerCalled(), [err]) +}) + +t.test('unsupported node version', async t => { + const { cli, logs } = await cliMock(t, { + globals: { + 'process.version': '12.6.0', + }, + }) + await cli(process) + t.match( + logs.warn[0][1], + /npm v.* does not support Node\.js 12\.6\.0\./ + ) +}) diff --git a/deps/npm/test/lib/cli.js b/deps/npm/test/lib/cli.js index cafd13feabe93d..a6cb576e886ee9 100644 --- a/deps/npm/test/lib/cli.js +++ b/deps/npm/test/lib/cli.js @@ -1,167 +1,10 @@ const t = require('tap') -const { load: loadMockNpm } = require('../fixtures/mock-npm.js') const tmock = require('../fixtures/tmock') -const cliMock = async (t, opts) => { - let exitHandlerArgs = null - let npm = null - const exitHandlerMock = (...args) => { - exitHandlerArgs = args - npm.unload() - } - exitHandlerMock.setNpm = _npm => npm = _npm - - const { Npm, outputs, logMocks, logs } = await loadMockNpm(t, { ...opts, init: false }) +t.test('returns cli-entry function', async t => { const cli = tmock(t, '{LIB}/cli.js', { - '{LIB}/npm.js': Npm, - '{LIB}/utils/exit-handler.js': exitHandlerMock, - ...logMocks, - }) - - return { - Npm, - cli, - outputs, - exitHandlerCalled: () => exitHandlerArgs, - exitHandlerNpm: () => npm, - logs, - logsBy: (title) => logs.verbose.filter(([p]) => p === title).map(([p, ...rest]) => rest), - } -} - -t.test('print the version, and treat npm_g as npm -g', async t => { - const { logsBy, logs, cli, Npm, outputs, exitHandlerCalled } = await cliMock(t, { - globals: { 'process.argv': ['node', 'npm_g', '-v'] }, - }) - await cli(process) - - t.strictSame(process.argv, ['node', 'npm', '-g', '-v'], 'system process.argv was rewritten') - t.strictSame(logsBy('cli'), [['node npm']]) - t.strictSame(logsBy('title'), [['npm']]) - t.match(logsBy('argv'), [['"--global" "--version"']]) - t.strictSame(logs.info, [ - ['using', 'npm@%s', Npm.version], - ['using', 'node@%s', process.version], - ]) - t.equal(outputs.length, 1) - t.strictSame(outputs, [[Npm.version]]) - t.strictSame(exitHandlerCalled(), []) -}) - -t.test('calling with --versions calls npm version with no args', async t => { - const { logsBy, cli, outputs, exitHandlerCalled } = await cliMock(t, { - globals: { - 'process.argv': ['node', 'npm', 'install', 'or', 'whatever', '--versions'], - }, - }) - await cli(process) - - t.equal(process.title, 'npm install or whatever') - t.strictSame(logsBy('cli'), [['node npm']]) - t.strictSame(logsBy('title'), [['npm install or whatever']]) - t.match(logsBy('argv'), [['"install" "or" "whatever" "--versions"']]) - t.equal(outputs.length, 1) - t.match(outputs[0][0], { npm: String, node: String, v8: String }) - t.strictSame(exitHandlerCalled(), []) -}) - -t.test('logged argv is sanitized', async t => { - const { logsBy, cli } = await cliMock(t, { - globals: { - 'process.argv': [ - 'node', - 'npm', - 'version', - '--registry', - 'https://u:password@npmjs.org/password', - ], - }, - }) - - await cli(process) - t.equal(process.title, 'npm version') - t.strictSame(logsBy('cli'), [['node npm']]) - t.strictSame(logsBy('title'), [['npm version']]) - t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/password"']]) -}) - -t.test('logged argv is sanitized with equals', async t => { - const { logsBy, cli } = await cliMock(t, { - globals: { - 'process.argv': [ - 'node', - 'npm', - 'version', - '--registry=https://u:password@npmjs.org', - ], - }, - }) - await cli(process) - - t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/"']]) -}) - -t.test('print usage if no params provided', async t => { - const { cli, outputs, exitHandlerCalled, exitHandlerNpm } = await cliMock(t, { - globals: { - 'process.argv': ['node', 'npm'], - }, + '{LIB}/cli-entry.js': () => 'ENTRY', }) - await cli(process) - - t.match(outputs[0][0], 'Usage:', 'outputs npm usage') - t.match(exitHandlerCalled(), [], 'should call exitHandler with no args') - t.ok(exitHandlerNpm(), 'exitHandler npm is set') - t.match(process.exitCode, 1) -}) -t.test('print usage if non-command param provided', async t => { - const { cli, outputs, exitHandlerCalled, exitHandlerNpm } = await cliMock(t, { - globals: { - 'process.argv': ['node', 'npm', 'tset'], - }, - }) - await cli(process) - - t.match(outputs[0][0], 'Unknown command: "tset"') - t.match(outputs[0][0], 'Did you mean this?') - t.match(exitHandlerCalled(), [], 'should call exitHandler with no args') - t.ok(exitHandlerNpm(), 'exitHandler npm is set') - t.match(process.exitCode, 1) -}) - -t.test('load error calls error handler', async t => { - const err = new Error('test load error') - const { cli, exitHandlerCalled } = await cliMock(t, { - mocks: { - '{LIB}/utils/config/index.js': { - definitions: null, - flatten: null, - shorthands: null, - }, - '@npmcli/config': class BadConfig { - async load () { - throw err - } - }, - }, - globals: { - 'process.argv': ['node', 'npm', 'asdf'], - }, - }) - await cli(process) - t.strictSame(exitHandlerCalled(), [err]) -}) - -t.test('unsupported node version', async t => { - const { cli, logs } = await cliMock(t, { - globals: { - 'process.version': '12.6.0', - }, - }) - await cli(process) - t.match( - logs.warn[0][1], - /npm v.* does not support Node\.js 12\.6\.0\./ - ) + t.equal(cli(process), 'ENTRY') }) diff --git a/deps/npm/test/lib/commands/access.js b/deps/npm/test/lib/commands/access.js index d1839aaaef2199..7aec33701297ca 100644 --- a/deps/npm/test/lib/commands/access.js +++ b/deps/npm/test/lib/commands/access.js @@ -7,8 +7,7 @@ const token = 'test-auth-token' const auth = { '//registry.npmjs.org/:_authToken': 'test-auth-token' } t.test('completion', async t => { - const { npm } = await loadMockNpm(t) - const access = await npm.cmd('access') + const { access } = await loadMockNpm(t, { command: 'access' }) const testComp = (argv, expect) => { const res = access.completion({ conf: { argv: { remain: argv } } }) t.resolves(res, expect, argv.join(' ')) diff --git a/deps/npm/test/lib/commands/adduser.js b/deps/npm/test/lib/commands/adduser.js index ddfbb945b2fcf5..410e8c4987ca64 100644 --- a/deps/npm/test/lib/commands/adduser.js +++ b/deps/npm/test/lib/commands/adduser.js @@ -4,27 +4,47 @@ const path = require('path') const ini = require('ini') const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') -const mockGlobals = require('../../fixtures/mock-globals.js') +const mockGlobals = require('@npmcli/mock-globals') const MockRegistry = require('@npmcli/mock-registry') const stream = require('stream') +const mockAddUser = async (t, { stdin: stdinLines, registry: registryUrl, ...options } = {}) => { + let stdin + if (stdinLines) { + stdin = new stream.PassThrough() + for (const l of stdinLines) { + stdin.write(l + '\n') + } + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + } + const mock = await loadMockNpm(t, { + ...options, + command: 'adduser', + }) + const registry = new MockRegistry({ + tap: t, + registry: registryUrl ?? mock.npm.config.get('registry'), + }) + return { + registry, + stdin, + rc: () => ini.parse(fs.readFileSync(path.join(mock.home, '.npmrc'), 'utf8')), + ...mock, + } +} + t.test('usage', async t => { - const { npm } = await loadMockNpm(t) - const adduser = await npm.cmd('adduser') + const { adduser } = await loadMockNpm(t, { command: 'adduser' }) t.match(adduser.usage, 'adduser', 'usage has command name in it') }) t.test('legacy', async t => { t.test('simple adduser', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - stdin.write('test-email@npmjs.org\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm, home } = await loadMockNpm(t, { + const { npm, rc, registry, adduser } = await mockAddUser(t, { + stdin: ['test-user', 'test-password', 'test-email@npmjs.org'], config: { 'auth-type': 'legacy' }, homeDir: { '.npmrc': [ @@ -34,71 +54,48 @@ t.test('legacy', async t => { ].join('\n'), }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.couchadduser({ username: 'test-user', password: 'test-password', email: 'test-email@npmjs.org', token: 'npm_test-token', }) - await npm.exec('adduser', []) + await adduser.exec([]) t.same(npm.config.get('email'), 'test-email-old@npmjs.org') t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '//registry.npmjs.org/:_authToken': 'npm_test-token', email: 'test-email-old@npmjs.org', }, 'should only have token and un-nerfed old email') }) t.test('scoped adduser', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - stdin.write('test-email@npmjs.org\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm, home } = await loadMockNpm(t, { + const { npm, rc, registry, adduser } = await mockAddUser(t, { + stdin: ['test-user', 'test-password', 'test-email@npmjs.org'], config: { 'auth-type': 'legacy', scope: '@myscope', }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.couchadduser({ username: 'test-user', password: 'test-password', email: 'test-email@npmjs.org', token: 'npm_test-token', }) - await npm.exec('adduser', []) + await adduser.exec([]) t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') t.same(npm.config.get('@myscope:registry'), 'https://registry.npmjs.org/') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '//registry.npmjs.org/:_authToken': 'npm_test-token', '@myscope:registry': 'https://registry.npmjs.org/', }, 'should only have token and scope:registry') }) t.test('scoped adduser with valid scoped registry config', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - stdin.write('test-email@npmjs.org\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm, home } = await loadMockNpm(t, { + const { npm, rc, registry, adduser } = await mockAddUser(t, { + stdin: ['test-user', 'test-password', 'test-email@npmjs.org'], + registry: 'https://diff-registry.npmjs.org', homeDir: { '.npmrc': '@myscope:registry=https://diff-registry.npmjs.org', }, @@ -107,106 +104,70 @@ t.test('legacy', async t => { scope: '@myscope', }, }) - const registry = new MockRegistry({ - tap: t, - registry: 'https://diff-registry.npmjs.org', - }) registry.couchadduser({ username: 'test-user', password: 'test-password', email: 'test-email@npmjs.org', token: 'npm_test-token', }) - await npm.exec('adduser', []) + await adduser.exec([]) t.same(npm.config.get('//diff-registry.npmjs.org/:_authToken'), 'npm_test-token') t.same(npm.config.get('@myscope:registry'), 'https://diff-registry.npmjs.org') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '@myscope:registry': 'https://diff-registry.npmjs.org', '//diff-registry.npmjs.org/:_authToken': 'npm_test-token', }, 'should only have token and scope:registry') }) t.test('save config failure', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - stdin.write('test-email@npmjs.org\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm } = await loadMockNpm(t, { + const { registry, adduser } = await mockAddUser(t, { + stdin: ['test-user', 'test-password', 'test-email@npmjs.org'], config: { 'auth-type': 'legacy' }, homeDir: { '.npmrc': {}, }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.couchadduser({ username: 'test-user', password: 'test-password', email: 'test-email@npmjs.org', token: 'npm_test-token', }) - await t.rejects(npm.exec('adduser', [])) + await t.rejects(adduser.exec([])) }) t.end() }) t.test('web', t => { t.test('basic adduser', async t => { - const { npm, home } = await loadMockNpm(t, { + const { npm, rc, registry, adduser } = await mockAddUser(t, { config: { 'auth-type': 'web' }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.webadduser({ token: 'npm_test-token' }) - await npm.exec('adduser', []) + await adduser.exec([]) t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '//registry.npmjs.org/:_authToken': 'npm_test-token', }) }) t.test('server error', async t => { - const { npm } = await loadMockNpm(t, { + const { adduser, registry } = await mockAddUser(t, { config: { 'auth-type': 'web' }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.nock.post(registry.fullPath('/-/v1/login')) .reply(503, {}) await t.rejects( - npm.exec('adduser', []), + adduser.exec([]), { message: /503/ } ) }) t.test('fallback', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - stdin.write('test-email@npmjs.org\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm } = await loadMockNpm(t, { + const { npm, registry, adduser } = await mockAddUser(t, { + stdin: ['test-user', 'test-password', 'test-email@npmjs.org'], config: { 'auth-type': 'web' }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.nock.post(registry.fullPath('/-/v1/login')) .reply(404, {}) registry.couchadduser({ @@ -215,7 +176,7 @@ t.test('web', t => { email: 'test-email@npmjs.org', token: 'npm_test-token', }) - await npm.exec('adduser', []) + await adduser.exec([]) t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') }) t.end() diff --git a/deps/npm/test/lib/commands/audit.js b/deps/npm/test/lib/commands/audit.js index 5c82fa14de32c1..4014e733873519 100644 --- a/deps/npm/test/lib/commands/audit.js +++ b/deps/npm/test/lib/commands/audit.js @@ -3,6 +3,7 @@ const zlib = require('zlib') const path = require('path') const t = require('tap') +const { default: tufmock } = require('@tufjs/repo-mock') const { load: loadMockNpm } = require('../../fixtures/mock-npm') const MockRegistry = require('@npmcli/mock-registry') @@ -210,8 +211,7 @@ t.test('audit fix - bulk endpoint', async t => { }) t.test('completion', async t => { - const { npm } = await loadMockNpm(t) - const audit = await npm.cmd('audit') + const { audit } = await loadMockNpm(t, { command: 'audit' }) t.test('fix', async t => { await t.resolveMatch( audit.completion({ conf: { argv: { remain: ['npm', 'audit'] } } }), @@ -247,28 +247,69 @@ t.test('audit signatures', async t => { }], } - const MISMATCHING_REGISTRY_KEYS = { + const TUF_VALID_REGISTRY_KEYS = { keys: [{ - expires: null, - keyid: 'SHA256:2l3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', - keytype: 'ecdsa-sha2-nistp256', - scheme: 'ecdsa-sha2-nistp256', - key: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + + keyId: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', + keyUsage: 'npm:signatures', + publicKey: { + rawBytes: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + 'IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==', + keyDetails: 'PKIX_ECDSA_P256_SHA_256', + validFor: { + start: '1999-01-01T00:00:00.000Z', + }, + }, }], } - const EXPIRED_REGISTRY_KEYS = { + const TUF_MISMATCHING_REGISTRY_KEYS = { keys: [{ - expires: '2021-01-11T15:45:42.144Z', - keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', - keytype: 'ecdsa-sha2-nistp256', - scheme: 'ecdsa-sha2-nistp256', - key: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + + keyId: 'SHA256:2l3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', + keyUsage: 'npm:signatures', + publicKey: { + rawBytes: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + + 'IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==', + keyDetails: 'PKIX_ECDSA_P256_SHA_256', + validFor: { + start: '1999-01-01T00:00:00.000Z', + }, + }, + }], + } + + const TUF_EXPIRED_REGISTRY_KEYS = { + keys: [{ + keyId: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', + keyUsage: 'npm:signatures', + publicKey: { + rawBytes: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + 'IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==', + keyDetails: 'PKIX_ECDSA_P256_SHA_256', + validFor: { + start: '1999-01-01T00:00:00.000Z', + end: '2021-01-11T15:45:42.144Z', + }, + }, }], } + const TUF_VALID_KEYS_TARGET = { + name: 'registry.npmjs.org/keys.json', + content: JSON.stringify(TUF_VALID_REGISTRY_KEYS), + } + + const TUF_MISMATCHING_KEYS_TARGET = { + name: 'registry.npmjs.org/keys.json', + content: JSON.stringify(TUF_MISMATCHING_REGISTRY_KEYS), + } + + const TUF_EXPIRED_KEYS_TARGET = { + name: 'registry.npmjs.org/keys.json', + content: JSON.stringify(TUF_EXPIRED_REGISTRY_KEYS), + } + + const TUF_TARGET_NOT_FOUND = [] + const installWithValidSigs = { 'package.json': JSON.stringify({ name: 'test-dep', @@ -882,13 +923,22 @@ t.test('audit signatures', async t => { await registry.package({ manifest }) } + function mockTUF ({ target, npm }) { + const opts = { + baseURL: 'https://tuf-repo-cdn.sigstore.dev', + metadataPathPrefix: '', + cachePath: path.join(npm.cache, '_tuf'), + } + return tufmock(target, opts) + } + t.test('with valid signatures', async t => { const { npm, joinedOutput } = await loadMockNpm(t, { prefixDir: installWithValidSigs, }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -921,6 +971,22 @@ t.test('audit signatures', async t => { }], }) await registry.package({ manifest }) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) + + await npm.exec('audit', ['signatures']) + + t.notOk(process.exitCode, 'should exit successfully') + t.match(joinedOutput(), /audited 1 package/) + t.matchSnapshot(joinedOutput()) + }) + + t.test('with key fallback to legacy API', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: installWithValidSigs, + }) + const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) + await manifestWithValidSigs({ registry }) + mockTUF({ npm, target: TUF_TARGET_NOT_FOUND }) registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) await npm.exec('audit', ['signatures']) @@ -1027,7 +1093,7 @@ t.test('audit signatures', async t => { }) await registry.package({ manifest: asyncManifest }) await manifestWithInvalidSigs({ registry, name: 'node-fetch', version: '1.6.0' }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1044,7 +1110,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1059,7 +1125,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithInvalidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1076,7 +1142,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) await manifestWithoutSigs({ registry, name: 'async', version: '1.1.1' }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1094,7 +1160,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithInvalidSigs({ registry }) await manifestWithoutSigs({ registry, name: 'async', version: '1.1.1' }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1112,7 +1178,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithInvalidSigs({ registry, name: 'kms-demo', version: '1.0.0' }) await manifestWithInvalidSigs({ registry, name: 'async', version: '1.1.1' }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1127,7 +1193,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithoutSigs({ registry, name: 'kms-demo', version: '1.0.0' }) await manifestWithoutSigs({ registry, name: 'async', version: '1.1.1' }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1141,6 +1207,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) + mockTUF({ npm, target: TUF_TARGET_NOT_FOUND }) registry.nock.get('/-/npm/v1/keys').reply(404) await t.rejects( @@ -1156,7 +1223,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, EXPIRED_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_EXPIRED_KEYS_TARGET }) await t.rejects( npm.exec('audit', ['signatures']), @@ -1171,7 +1238,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, MISMATCHING_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_MISMATCHING_KEYS_TARGET }) await t.rejects( npm.exec('audit', ['signatures']), @@ -1186,7 +1253,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithoutSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1204,7 +1271,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithoutSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1225,7 +1292,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1243,7 +1310,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithInvalidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1261,7 +1328,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithInvalidSigs({ registry }) await manifestWithoutSigs({ registry, name: 'async', version: '1.1.1' }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1278,7 +1345,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1309,6 +1376,7 @@ t.test('audit signatures', async t => { }], }) await registry.package({ manifest }) + mockTUF({ npm, target: TUF_TARGET_NOT_FOUND }) registry.nock.get('/-/npm/v1/keys').reply(404) await t.rejects( @@ -1339,6 +1407,7 @@ t.test('audit signatures', async t => { }], }) await registry.package({ manifest }) + mockTUF({ npm, target: TUF_TARGET_NOT_FOUND }) registry.nock.get('/-/npm/v1/keys').reply(400) await t.rejects( @@ -1377,17 +1446,11 @@ t.test('audit signatures', async t => { }], }) await registry.package({ manifest }) - registry.nock.get('/-/npm/v1/keys') - .reply(200, { - keys: [{ - expires: null, - keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', - keytype: 'ecdsa-sha2-nistp256', - scheme: 'ecdsa-sha2-nistp256', - key: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + - 'IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==', - }], - }) + mockTUF({ npm, + target: { + name: 'verdaccio-clone.org/keys.json', + content: JSON.stringify(TUF_VALID_REGISTRY_KEYS), + } }) await npm.exec('audit', ['signatures']) @@ -1425,17 +1488,11 @@ t.test('audit signatures', async t => { }], }) await registry.package({ manifest }) - registry.nock.get('/-/npm/v1/keys') - .reply(200, { - keys: [{ - expires: null, - keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', - keytype: 'ecdsa-sha2-nistp256', - scheme: 'ecdsa-sha2-nistp256', - key: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + - 'IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==', - }], - }) + mockTUF({ npm, + target: { + name: 'verdaccio-clone.org/keys.json', + content: JSON.stringify(TUF_VALID_REGISTRY_KEYS), + } }) await npm.exec('audit', ['signatures']) @@ -1467,17 +1524,11 @@ t.test('audit signatures', async t => { }], }) await registry.package({ manifest }) - registry.nock.get('/-/npm/v1/keys') - .reply(200, { - keys: [{ - expires: null, - keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', - keytype: 'ecdsa-sha2-nistp256', - scheme: 'ecdsa-sha2-nistp256', - key: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+' + - 'IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==', - }], - }) + mockTUF({ npm, + target: { + name: 'verdaccio-clone.org/keys.json', + content: JSON.stringify(TUF_VALID_REGISTRY_KEYS), + } }) await npm.exec('audit', ['signatures']) @@ -1486,6 +1537,94 @@ t.test('audit signatures', async t => { t.matchSnapshot(joinedOutput()) }) + t.test('third-party registry with sub-path', async t => { + const registryUrl = 'https://verdaccio-clone.org/npm' + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: installWithThirdPartyRegistry, + config: { + scope: '@npmcli', + registry: registryUrl, + }, + }) + const registry = new MockRegistry({ tap: t, registry: registryUrl }) + + const manifest = registry.manifest({ + name: '@npmcli/arborist', + packuments: [{ + version: '1.0.14', + dist: { + tarball: 'https://registry.npmjs.org/@npmcli/arborist/-/@npmcli/arborist-1.0.14.tgz', + integrity: 'sha512-caa8hv5rW9VpQKk6tyNRvSaVDySVjo9GkI7Wj/wcsFyxPm3tYrE' + + 'sFyTjSnJH8HCIfEGVQNjqqKXaXLFVp7UBag==', + signatures: [ + { + keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', + sig: 'MEUCIAvNpR3G0j7WOPUuVMhE0ZdM8PnDNcsoeFD8Iwz9YWIMAiEAn8cicDC2' + + 'Sf9MFQydqTv6S5XYsAh9Af1sig1nApNI11M=', + }, + ], + }, + }], + }) + await registry.package({ manifest }) + + mockTUF({ npm, + target: { + name: 'verdaccio-clone.org/npm/keys.json', + content: JSON.stringify(TUF_VALID_REGISTRY_KEYS), + } }) + + await npm.exec('audit', ['signatures']) + + t.notOk(process.exitCode, 'should exit successfully') + t.match(joinedOutput(), /audited 1 package/) + t.matchSnapshot(joinedOutput()) + }) + + t.test('third-party registry with sub-path (trailing slash)', async t => { + const registryUrl = 'https://verdaccio-clone.org/npm/' + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: installWithThirdPartyRegistry, + config: { + scope: '@npmcli', + registry: registryUrl, + }, + }) + const registry = new MockRegistry({ tap: t, registry: registryUrl }) + + const manifest = registry.manifest({ + name: '@npmcli/arborist', + packuments: [{ + version: '1.0.14', + dist: { + tarball: 'https://registry.npmjs.org/@npmcli/arborist/-/@npmcli/arborist-1.0.14.tgz', + integrity: 'sha512-caa8hv5rW9VpQKk6tyNRvSaVDySVjo9GkI7Wj/wcsFyxPm3tYrE' + + 'sFyTjSnJH8HCIfEGVQNjqqKXaXLFVp7UBag==', + signatures: [ + { + keyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA', + sig: 'MEUCIAvNpR3G0j7WOPUuVMhE0ZdM8PnDNcsoeFD8Iwz9YWIMAiEAn8cicDC2' + + 'Sf9MFQydqTv6S5XYsAh9Af1sig1nApNI11M=', + }, + ], + }, + }], + }) + await registry.package({ manifest }) + + mockTUF({ npm, + target: { + name: 'verdaccio-clone.org/npm/keys.json', + content: JSON.stringify(TUF_VALID_REGISTRY_KEYS), + } }) + + await npm.exec('audit', ['signatures']) + + t.notOk(process.exitCode, 'should exit successfully') + t.match(joinedOutput(), /audited 1 package/) + t.matchSnapshot(joinedOutput()) + }) + t.test('multiple registries with keys and signatures', async t => { const registryUrl = 'https://verdaccio-clone.org' const { npm, joinedOutput } = await loadMockNpm(t, { @@ -1500,7 +1639,7 @@ t.test('audit signatures', async t => { registry: registryUrl, }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) const manifest = thirdPartyRegistry.manifest({ name: '@npmcli/arborist', @@ -1556,11 +1695,36 @@ t.test('audit signatures', async t => { ) }) + t.test('errors when TUF errors', async t => { + const { npm } = await loadMockNpm(t, { + prefixDir: installWithMultipleDeps, + mocks: { + sigstore: { + sigstore: { + tuf: { + client: async () => ({ + getTarget: async () => { + throw new Error('error refreshing TUF metadata') + }, + }), + }, + }, + }, + }, + }) + + await t.rejects( + npm.exec('audit', ['signatures']), + /error refreshing TUF metadata/ + ) + }) + t.test('errors when the keys endpoint errors', async t => { const { npm } = await loadMockNpm(t, { prefixDir: installWithMultipleDeps, }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) + mockTUF({ npm, target: TUF_TARGET_NOT_FOUND }) registry.nock.get('/-/npm/v1/keys') .reply(500, { error: 'keys broke' }) @@ -1577,7 +1741,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1590,8 +1754,7 @@ t.test('audit signatures', async t => { const { npm } = await loadMockNpm(t, { prefixDir: noInstall, }) - const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await t.rejects( npm.exec('audit', ['signatures']), @@ -1612,8 +1775,7 @@ t.test('audit signatures', async t => { node_modules: {}, }, }) - const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await t.rejects( npm.exec('audit', ['signatures']), @@ -1641,6 +1803,7 @@ t.test('audit signatures', async t => { }, }, }) + mockTUF({ npm, target: TUF_TARGET_NOT_FOUND }) await t.rejects( npm.exec('audit', ['signatures']), @@ -1669,8 +1832,7 @@ t.test('audit signatures', async t => { }, }) - const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await t.rejects( npm.exec('audit', ['signatures']), @@ -1697,7 +1859,7 @@ t.test('audit signatures', async t => { }) const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithInvalidSigs({ registry }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1728,7 +1890,7 @@ t.test('audit signatures', async t => { 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1761,7 +1923,7 @@ t.test('audit signatures', async t => { ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture1) registry.nock.get('/-/npm/v1/attestations/tuf-js@1.0.0').reply(200, fixture2) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1791,7 +1953,7 @@ t.test('audit signatures', async t => { 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1828,7 +1990,7 @@ t.test('audit signatures', async t => { 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1865,7 +2027,7 @@ t.test('audit signatures', async t => { ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture1) registry.nock.get('/-/npm/v1/attestations/tuf-js@1.0.0').reply(200, fixture2) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1922,7 +2084,7 @@ t.test('audit signatures', async t => { }) await registry.package({ manifest: asyncManifest }) await registry.package({ manifest: lightCycleManifest }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) @@ -1975,7 +2137,7 @@ t.test('audit signatures', async t => { }) await registry.package({ manifest: asyncManifest }) await registry.package({ manifest: lightCycleManifest }) - registry.nock.get('/-/npm/v1/keys').reply(200, VALID_REGISTRY_KEYS) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) await npm.exec('audit', ['signatures']) diff --git a/deps/npm/test/lib/commands/bugs.js b/deps/npm/test/lib/commands/bugs.js index bf45b9eee81ab3..953c8e6345a2a7 100644 --- a/deps/npm/test/lib/commands/bugs.js +++ b/deps/npm/test/lib/commands/bugs.js @@ -43,8 +43,7 @@ const pacote = { } t.test('usage', async (t) => { - const { npm } = await loadMockNpm(t) - const bugs = await npm.cmd('bugs') + const { bugs } = await loadMockNpm(t, { command: 'bugs' }) t.match(bugs.usage, 'bugs', 'usage has command name in it') }) diff --git a/deps/npm/test/lib/commands/cache.js b/deps/npm/test/lib/commands/cache.js index fe2854f9aa6269..15ee4dc80aa1aa 100644 --- a/deps/npm/test/lib/commands/cache.js +++ b/deps/npm/test/lib/commands/cache.js @@ -1,7 +1,6 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') const MockRegistry = require('@npmcli/mock-registry') -const mockGlobals = require('../../fixtures/mock-globals') const cacache = require('cacache') const fs = require('fs') @@ -267,8 +266,9 @@ t.test('cache verify', async t => { }) t.test('cache verify as part of home', async t => { - const { npm, joinedOutput, prefix } = await loadMockNpm(t) - mockGlobals(t, { 'process.env.HOME': path.dirname(prefix) }) + const { npm, joinedOutput } = await loadMockNpm(t, { + globals: ({ prefix }) => ({ 'process.env.HOME': path.dirname(prefix) }), + }) await npm.exec('cache', ['verify']) t.match(joinedOutput(), 'Cache verified and compressed (~', 'contains ~ shorthand') }) @@ -302,8 +302,7 @@ t.test('cache verify w/ extra output', async t => { }) t.test('cache completion', async t => { - const { npm } = await loadMockNpm(t) - const cache = await npm.cmd('cache') + const { cache } = await loadMockNpm(t, { command: 'cache' }) const { completion } = cache const testComp = (argv, expect) => { diff --git a/deps/npm/test/lib/commands/completion.js b/deps/npm/test/lib/commands/completion.js index 6cc1677552e8a7..904d9410fdd6c7 100644 --- a/deps/npm/test/lib/commands/completion.js +++ b/deps/npm/test/lib/commands/completion.js @@ -1,30 +1,26 @@ const t = require('tap') const fs = require('fs') const path = require('path') +const { load: loadMockNpm } = require('../../fixtures/mock-npm') const completionScript = fs .readFileSync(path.resolve(__dirname, '../../../lib/utils/completion.sh'), { encoding: 'utf8' }) .replace(/^#!.*?\n/, '') -const { load: loadMockNpm } = require('../../fixtures/mock-npm') -const mockGlobals = require('../../fixtures/mock-globals') - const loadMockCompletion = async (t, o = {}) => { const { globals = {}, windows, ...options } = o - let resetGlobals = {} - resetGlobals = mockGlobals(t, { - 'process.platform': windows ? 'win32' : 'posix', - 'process.env.term': 'notcygwin', - 'process.env.msystem': 'nogmingw', - ...globals, - }).reset const res = await loadMockNpm(t, { + command: 'completion', ...options, + globals: (dirs) => ({ + 'process.platform': windows ? 'win32' : 'posix', + 'process.env.term': 'notcygwin', + 'process.env.msystem': 'nogmingw', + ...(typeof globals === 'function' ? globals(dirs) : globals), + }), }) - const completion = await res.npm.cmd('completion') return { - resetGlobals, - completion, + resetGlobals: res.mockedGlobals.reset, ...res, } } @@ -40,21 +36,26 @@ const loadMockCompletionComp = async (t, word, line) => t.test('completion', async t => { t.test('completion completion', async t => { - const { outputs, completion, prefix } = await loadMockCompletion(t, { + const { outputs, completion } = await loadMockCompletion(t, { prefixDir: { '.bashrc': 'aaa', '.zshrc': 'aaa', }, + globals: ({ prefix }) => ({ + 'process.env.HOME': prefix, + }), }) - mockGlobals(t, { 'process.env.HOME': prefix }) await completion.completion({ w: 2 }) t.matchSnapshot(outputs, 'both shells') }) t.test('completion completion no known shells', async t => { - const { outputs, completion, prefix } = await loadMockCompletion(t) - mockGlobals(t, { 'process.env.HOME': prefix }) + const { outputs, completion } = await loadMockCompletion(t, { + globals: ({ prefix }) => ({ + 'process.env.HOME': prefix, + }), + }) await completion.completion({ w: 2 }) t.matchSnapshot(outputs, 'no responses') @@ -86,7 +87,7 @@ t.test('completion', async t => { }, }) - await completion.exec({}) + await completion.exec() t.equal(data, completionScript, 'wrote the completion script') }) @@ -111,7 +112,7 @@ t.test('completion', async t => { }, }) - await completion.exec({}) + await completion.exec() t.equal(data, completionScript, 'wrote the completion script') }) @@ -190,7 +191,7 @@ t.test('completion', async t => { t.test('windows without bash', async t => { const { outputs, completion } = await loadMockCompletion(t, { windows: true }) await t.rejects( - completion.exec({}), + completion.exec(), { code: 'ENOTSUP', message: /completion supported only in MINGW/ }, 'returns the correct error' ) diff --git a/deps/npm/test/lib/commands/deprecate.js b/deps/npm/test/lib/commands/deprecate.js index 48513c7303a015..4ae146fd3aee0d 100644 --- a/deps/npm/test/lib/commands/deprecate.js +++ b/deps/npm/test/lib/commands/deprecate.js @@ -12,13 +12,13 @@ const versions = ['1.0.0', '1.0.1', '1.0.1-pre'] const packages = { foo: 'write', bar: 'write', baz: 'write', buzz: 'read' } t.test('completion', async t => { - const { npm } = await loadMockNpm(t, { + const { npm, deprecate } = await loadMockNpm(t, { + command: 'deprecate', config: { ...auth, }, }) - const deprecate = await npm.cmd('deprecate') const testComp = async (argv, expect) => { const res = await deprecate.completion({ conf: { argv: { remain: argv } } }) diff --git a/deps/npm/test/lib/commands/diff.js b/deps/npm/test/lib/commands/diff.js index d9ff9e5dad0e6a..36a9e4bc17d9f1 100644 --- a/deps/npm/test/lib/commands/diff.js +++ b/deps/npm/test/lib/commands/diff.js @@ -25,7 +25,9 @@ const mockDiff = async (t, { ...opts } = {}) => { const tarballFixtures = Object.entries(tarballs).reduce((acc, [spec, fixture]) => { - const [name, version] = spec.split('@') + const lastAt = spec.lastIndexOf('@') + const name = spec.slice(0, lastAt) + const version = spec.slice(lastAt + 1) acc[name] = acc[name] || {} acc[name][version] = fixture if (!acc[name][version]['package.json']) { @@ -39,6 +41,7 @@ const mockDiff = async (t, { const { prefixDir, globalPrefixDir, otherDirs, config, ...rest } = opts const { npm, ...res } = await loadMockNpm(t, { + command: 'diff', prefixDir: jsonifyTestdir(prefixDir), otherDirs: jsonifyTestdir({ tarballs: tarballFixtures, ...otherDirs }), globalPrefixDir: jsonifyTestdir(globalPrefixDir), @@ -75,7 +78,7 @@ const mockDiff = async (t, { } if (exec) { - await npm.exec('diff', exec) + await res.diff.exec(exec) res.output = res.joinedOutput() } @@ -98,13 +101,13 @@ const assertFoo = async (t, arg) => { const { output } = await mockDiff(t, { diff, prefixDir: { - 'package.json': { name: 'foo', version: '1.0.0' }, + 'package.json': { name: '@npmcli/foo', version: '1.0.0' }, 'index.js': 'const version = "1.0.0"', 'a.js': 'const a = "a@1.0.0"', 'b.js': 'const b = "b@1.0.0"', }, tarballs: { - 'foo@0.1.0': { + '@npmcli/foo@0.1.0': { 'index.js': 'const version = "0.1.0"', 'a.js': 'const a = "a@0.1.0"', 'b.js': 'const b = "b@0.1.0"', @@ -162,17 +165,17 @@ t.test('no args', async t => { t.test('single arg', async t => { t.test('spec using cwd package name', async t => { - await assertFoo(t, 'foo@0.1.0') + await assertFoo(t, '@npmcli/foo@0.1.0') }) t.test('unknown spec, no package.json', async t => { await rejectDiff(t, /Needs multiple arguments to compare or run from a project dir./, { - diff: ['foo@1.0.0'], + diff: ['@npmcli/foo@1.0.0'], }) }) t.test('spec using semver range', async t => { - await assertFoo(t, 'foo@~0.1.0') + await assertFoo(t, '@npmcli/foo@~0.1.0') }) t.test('version', async t => { @@ -429,17 +432,17 @@ t.test('single arg', async t => { t.test('use project name in project dir', async t => { const { output } = await mockDiff(t, { - diff: 'foo', + diff: '@npmcli/foo', prefixDir: { - 'package.json': { name: 'foo', version: '1.0.0' }, + 'package.json': { name: '@npmcli/foo', version: '1.0.0' }, }, tarballs: { - 'foo@2.2.2': {}, + '@npmcli/foo@2.2.2': {}, }, exec: [], }) - t.match(output, 'foo') + t.match(output, '@npmcli/foo') t.match(output, /-\s*"version": "2\.2\.2"/) t.match(output, /\+\s*"version": "1\.0\.0"/) }) @@ -448,17 +451,17 @@ t.test('single arg', async t => { const { output } = await mockDiff(t, { diff: '../other/other-pkg', prefixDir: { - 'package.json': { name: 'foo', version: '1.0.0' }, + 'package.json': { name: '@npmcli/foo', version: '1.0.0' }, }, otherDirs: { 'other-pkg': { - 'package.json': { name: 'foo', version: '2.0.0' }, + 'package.json': { name: '@npmcli/foo', version: '2.0.0' }, }, }, exec: [], }) - t.match(output, 'foo') + t.match(output, '@npmcli/foo') t.match(output, /-\s*"version": "2\.0\.0"/) t.match(output, /\+\s*"version": "1\.0\.0"/) }) diff --git a/deps/npm/test/lib/commands/dist-tag.js b/deps/npm/test/lib/commands/dist-tag.js index 4cc241f74582d1..1c63ce497d3fb2 100644 --- a/deps/npm/test/lib/commands/dist-tag.js +++ b/deps/npm/test/lib/commands/dist-tag.js @@ -77,22 +77,15 @@ const mockDist = async (t, { ...npmOpts } = {}) => { const mock = await mockNpm(t, { ...npmOpts, + command: 'dist-tag', mocks: { 'npm-registry-fetch': Object.assign(nrf, realFetch, { json: getTag }), }, }) - const usage = await mock.npm.cmd('dist-tag').then(c => c.usage) - return { ...mock, - distTag: { - exec: (args) => mock.npm.exec('dist-tag', args), - usage, - completion: (remain) => mock.npm.cmd('dist-tag').then(c => c.completion({ - conf: { argv: { remain } }, - })), - }, + distTag: mock['dist-tag'], fetchOpts: () => fetchOpts, result: () => mock.joinedOutput(), logs: () => { @@ -365,10 +358,10 @@ t.test('remove missing pkg name', async t => { t.test('completion', async t => { const { distTag } = await mockDist(t) - const match = distTag.completion(['npm', 'dist-tag']) + const match = distTag.completion({ conf: { argv: { remain: ['npm', 'dist-tag'] } } }) t.resolveMatch(match, ['add', 'rm', 'ls'], 'should list npm dist-tag commands for completion') - const noMatch = distTag.completion(['npm', 'dist-tag', 'foobar']) + const noMatch = distTag.completion({ conf: { argv: { remain: ['npm', 'dist-tag', 'foobar'] } } }) t.resolveMatch(noMatch, []) }) diff --git a/deps/npm/test/lib/commands/doctor.js b/deps/npm/test/lib/commands/doctor.js index d1a88299e69ae9..1682a6cccfa483 100644 --- a/deps/npm/test/lib/commands/doctor.js +++ b/deps/npm/test/lib/commands/doctor.js @@ -4,7 +4,7 @@ const path = require('path') const { load: loadMockNpm } = require('../../fixtures/mock-npm') const tnock = require('../../fixtures/tnock.js') -const mockGlobals = require('../../fixtures/mock-globals') +const mockGlobals = require('@npmcli/mock-globals') const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot.js') const cleanCacheSha = (str) => diff --git a/deps/npm/test/lib/commands/explain.js b/deps/npm/test/lib/commands/explain.js index 79c917a1cd4527..f4d898797bcbe4 100644 --- a/deps/npm/test/lib/commands/explain.js +++ b/deps/npm/test/lib/commands/explain.js @@ -4,6 +4,7 @@ const mockNpm = require('../../fixtures/mock-npm.js') const mockExplain = async (t, opts) => { const mock = await mockNpm(t, { + command: 'explain', mocks: { // keep the snapshots pared down a bit, since this has its own tests. '{LIB}/utils/explain-dep.js': { @@ -16,15 +17,7 @@ const mockExplain = async (t, opts) => { ...opts, }) - const usage = await mock.npm.cmd('explain').then(c => c.usage) - - return { - ...mock, - explain: { - usage, - exec: (args) => mock.npm.exec('explain', args), - }, - } + return mock } t.test('no args throws usage', async t => { diff --git a/deps/npm/test/lib/commands/explore.js b/deps/npm/test/lib/commands/explore.js index 786a34a8e29882..6988dca90fbfb0 100644 --- a/deps/npm/test/lib/commands/explore.js +++ b/deps/npm/test/lib/commands/explore.js @@ -3,18 +3,20 @@ const mockNpm = require('../../fixtures/mock-npm') const { cleanCwd } = require('../../fixtures/clean-snapshot') const mockExplore = async (t, exec, { - RPJ_ERROR = null, + PJ_ERROR = null, RUN_SCRIPT_ERROR = null, RUN_SCRIPT_EXIT_CODE = 0, RUN_SCRIPT_SIGNAL = null, } = {}) => { - let RPJ_CALLED = '' - const mockRPJ = async path => { - if (RPJ_ERROR) { - throw RPJ_ERROR - } - RPJ_CALLED = cleanCwd(path) - return { some: 'package' } + let PJ_CALLED = '' + const mockPJ = { + normalize: async path => { + if (PJ_ERROR) { + throw PJ_ERROR + } + PJ_CALLED = cleanCwd(path) + return { content: { some: 'package' } } + }, } let RUN_SCRIPT_EXEC = null @@ -41,7 +43,7 @@ const mockExplore = async (t, exec, { const mock = await mockNpm(t, { mocks: { - 'read-package-json-fast': mockRPJ, + '@npmcli/package-json': mockPJ, '@npmcli/run-script': mockRunScript, }, config: { @@ -53,7 +55,7 @@ const mockExplore = async (t, exec, { return { ...mock, - RPJ_CALLED, + PJ_CALLED, RUN_SCRIPT_EXEC, output: cleanCwd(mock.joinedOutput()).trim(), } @@ -62,11 +64,11 @@ const mockExplore = async (t, exec, { t.test('basic interactive', async t => { const { output, - RPJ_CALLED, + PJ_CALLED, RUN_SCRIPT_EXEC, } = await mockExplore(t, ['pkg']) - t.match(RPJ_CALLED, /\/pkg\/package.json$/) + t.ok(PJ_CALLED.endsWith('/pkg')) t.strictSame(RUN_SCRIPT_EXEC, 'shell-command') t.match(output, /Exploring \{CWD\}\/[\w-_/]+\nType 'exit' or \^D when finished/) }) @@ -75,11 +77,11 @@ t.test('interactive tracks exit code', async t => { t.test('code', async t => { const { output, - RPJ_CALLED, + PJ_CALLED, RUN_SCRIPT_EXEC, } = await mockExplore(t, ['pkg'], { RUN_SCRIPT_EXIT_CODE: 99 }) - t.match(RPJ_CALLED, /\/pkg\/package.json$/) + t.ok(PJ_CALLED.endsWith('/pkg')) t.strictSame(RUN_SCRIPT_EXEC, 'shell-command') t.match(output, /Exploring \{CWD\}\/[\w-_/]+\nType 'exit' or \^D when finished/) @@ -123,11 +125,11 @@ t.test('interactive tracks exit code', async t => { t.test('basic non-interactive', async t => { const { output, - RPJ_CALLED, + PJ_CALLED, RUN_SCRIPT_EXEC, } = await mockExplore(t, ['pkg', 'ls']) - t.match(RPJ_CALLED, /\/pkg\/package.json$/) + t.ok(PJ_CALLED.endsWith('/pkg')) t.strictSame(RUN_SCRIPT_EXEC, 'ls') t.strictSame(output, '') @@ -164,10 +166,10 @@ t.test('usage if no pkg provided', async t => { }) t.test('pkg not installed', async t => { - const RPJ_ERROR = new Error('plurple') + const PJ_ERROR = new Error('plurple') await t.rejects( - mockExplore(t, ['pkg', 'ls'], { RPJ_ERROR }), + mockExplore(t, ['pkg', 'ls'], { PJ_ERROR }), { message: 'plurple' } ) }) diff --git a/deps/npm/test/lib/commands/get.js b/deps/npm/test/lib/commands/get.js index 597cccc3ff0ba4..dec634f835172e 100644 --- a/deps/npm/test/lib/commands/get.js +++ b/deps/npm/test/lib/commands/get.js @@ -2,10 +2,11 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm') t.test('should retrieve values from config', async t => { - const { joinedOutput, npm } = await loadMockNpm(t) const name = 'editor' const value = 'vigor' - npm.config.set(name, value) + const { joinedOutput, npm } = await loadMockNpm(t, { + config: { [name]: value }, + }) await npm.exec('get', [name]) t.equal( joinedOutput(), diff --git a/deps/npm/test/lib/commands/help-search.js b/deps/npm/test/lib/commands/help-search.js index ce6e5f7cf00b01..8da725fad76924 100644 --- a/deps/npm/test/lib/commands/help-search.js +++ b/deps/npm/test/lib/commands/help-search.js @@ -1,6 +1,5 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') -const chalk = require('chalk') /* eslint-disable max-len */ const docsFixtures = { @@ -70,6 +69,8 @@ t.test('npm help-search long output with color', async t => { }, }) + const chalk = await import('chalk').then(v => v.default) + const highlightedText = chalk.bgBlack.red('help-search') t.equal( output.split('\n').some(line => line.includes(highlightedText)), diff --git a/deps/npm/test/lib/commands/help.js b/deps/npm/test/lib/commands/help.js index e38f1bbce24d46..3fda9fb6e07fd3 100644 --- a/deps/npm/test/lib/commands/help.js +++ b/deps/npm/test/lib/commands/help.js @@ -61,18 +61,13 @@ const mockHelp = async (t, { mocks: { '@npmcli/promise-spawn': mockSpawn }, otherDirs: { ...manPages.fixtures }, config, + command: 'help', + exec: execArgs, ...opts, }) - const help = await npm.cmd('help') - const exec = execArgs - ? await npm.exec('help', execArgs) - : (...a) => npm.exec('help', a) - return { npm, - help, - exec, manPages: manPages.pages, getArgs: () => args, ...rest, @@ -80,8 +75,8 @@ const mockHelp = async (t, { } t.test('npm help', async t => { - const { exec, joinedOutput } = await mockHelp(t) - await exec() + const { help, joinedOutput } = await mockHelp(t) + await help.exec() t.match(joinedOutput(), 'npm ', 'showed npm usage') }) @@ -216,17 +211,17 @@ t.test('npm help - works in the presence of strange man pages', async t => { }) t.test('rejects with code', async t => { - const { exec } = await mockHelp(t, { + const { help } = await mockHelp(t, { spawnErr: Object.assign(new Error('errrrr'), { code: 'SPAWN_ERR' }), }) - await t.rejects(exec('whoami'), /help process exited with code: SPAWN_ERR/) + await t.rejects(help.exec(['whoami']), /help process exited with code: SPAWN_ERR/) }) t.test('rejects with no code', async t => { - const { exec } = await mockHelp(t, { + const { help } = await mockHelp(t, { spawnErr: new Error('errrrr'), }) - await t.rejects(exec('whoami'), /errrrr/) + await t.rejects(help.exec(['whoami']), /errrrr/) }) diff --git a/deps/npm/test/lib/commands/hook.js b/deps/npm/test/lib/commands/hook.js index 01da9dc720dae5..e4e1214b812f3b 100644 --- a/deps/npm/test/lib/commands/hook.js +++ b/deps/npm/test/lib/commands/hook.js @@ -51,6 +51,7 @@ const mockHook = async (t, { hookResponse, ...npmOpts } = {}) => { const mock = await mockNpm(t, { ...npmOpts, + command: 'hook', mocks: { libnpmhook, ...npmOpts.mocks, @@ -60,7 +61,6 @@ const mockHook = async (t, { hookResponse, ...npmOpts } = {}) => { return { ...mock, now, - hook: { exec: (args) => mock.npm.exec('hook', args) }, hookArgs: () => hookArgs, } } diff --git a/deps/npm/test/lib/commands/init.js b/deps/npm/test/lib/commands/init.js index 00caf90d0ec9b6..cb708303f405a4 100644 --- a/deps/npm/test/lib/commands/init.js +++ b/deps/npm/test/lib/commands/init.js @@ -6,13 +6,12 @@ const { cleanTime } = require('../../fixtures/clean-snapshot') t.cleanSnapshot = cleanTime -const mockNpm = async (t, { noLog, libnpmexec, initPackageJson, packageJson, ...opts } = {}) => { +const mockNpm = async (t, { noLog, libnpmexec, initPackageJson, ...opts } = {}) => { const res = await _mockNpm(t, { ...opts, mocks: { ...(libnpmexec ? { libnpmexec } : {}), ...(initPackageJson ? { 'init-package-json': initPackageJson } : {}), - ...(packageJson ? { '@npmcli/package-json': packageJson } : {}), }, globals: { // init-package-json prints directly to console.log @@ -313,14 +312,7 @@ t.test('workspaces', async t => { await t.test('fail parsing top-level package.json to set workspace', async t => { const { npm } = await mockNpm(t, { prefixDir: { - 'package.json': JSON.stringify({ - name: 'top-level', - }), - }, - packageJson: { - async load () { - throw new Error('ERR') - }, + 'package.json': 'not json[', }, config: { workspace: 'a', yes: true }, noLog: true, @@ -328,8 +320,7 @@ t.test('workspaces', async t => { await t.rejects( npm.exec('init', []), - /ERR/, - 'should exit with error' + { code: 'EJSONPARSE' } ) }) diff --git a/deps/npm/test/lib/commands/install.js b/deps/npm/test/lib/commands/install.js index 1be42d6e6125f0..f40b62edde17cc 100644 --- a/deps/npm/test/lib/commands/install.js +++ b/deps/npm/test/lib/commands/install.js @@ -355,31 +355,32 @@ t.test('completion', async t => { t.test('location detection and audit', async (t) => { await t.test('audit false without package.json', async t => { const { npm } = await loadMockNpm(t, { + command: 'install', prefixDir: { // no package.json 'readme.txt': 'just a file', 'other-dir': { a: 'a' }, }, }) - const install = await npm.cmd('install') - t.equal(install.npm.config.get('location'), 'user') - t.equal(install.npm.config.get('audit'), false) + t.equal(npm.config.get('location'), 'user') + t.equal(npm.config.get('audit'), false) }) await t.test('audit true with package.json', async t => { const { npm } = await loadMockNpm(t, { + command: 'install', prefixDir: { 'package.json': '{ "name": "testpkg", "version": "1.0.0" }', 'readme.txt': 'just a file', }, }) - const install = await npm.cmd('install') - t.equal(install.npm.config.get('location'), 'user') - t.equal(install.npm.config.get('audit'), true) + t.equal(npm.config.get('location'), 'user') + t.equal(npm.config.get('audit'), true) }) await t.test('audit true without package.json when set', async t => { const { npm } = await loadMockNpm(t, { + command: 'install', prefixDir: { // no package.json 'readme.txt': 'just a file', @@ -389,13 +390,13 @@ t.test('location detection and audit', async (t) => { audit: true, }, }) - const install = await npm.cmd('install') - t.equal(install.npm.config.get('location'), 'user') - t.equal(install.npm.config.get('audit'), true) + t.equal(npm.config.get('location'), 'user') + t.equal(npm.config.get('audit'), true) }) await t.test('audit true in root config without package.json', async t => { const { npm } = await loadMockNpm(t, { + command: 'install', prefixDir: { // no package.json 'readme.txt': 'just a file', @@ -405,13 +406,13 @@ t.test('location detection and audit', async (t) => { otherDirs: { npmrc: 'audit=true' }, npm: ({ other }) => ({ npmRoot: other }), }) - const install = await npm.cmd('install') - t.equal(install.npm.config.get('location'), 'user') - t.equal(install.npm.config.get('audit'), true) + t.equal(npm.config.get('location'), 'user') + t.equal(npm.config.get('audit'), true) }) await t.test('test for warning when --global & --audit', async t => { const { npm, logs } = await loadMockNpm(t, { + command: 'install', prefixDir: { // no package.json 'readme.txt': 'just a file', @@ -422,9 +423,8 @@ t.test('location detection and audit', async (t) => { global: true, }, }) - const install = await npm.cmd('install') - t.equal(install.npm.config.get('location'), 'user') - t.equal(install.npm.config.get('audit'), true) + t.equal(npm.config.get('location'), 'user') + t.equal(npm.config.get('audit'), true) t.equal(logs.warn[0][0], 'config') t.equal(logs.warn[0][1], 'includes both --global and --audit, which is currently unsupported.') }) diff --git a/deps/npm/test/lib/commands/link.js b/deps/npm/test/lib/commands/link.js index feae75a4b9096f..65792fd141acba 100644 --- a/deps/npm/test/lib/commands/link.js +++ b/deps/npm/test/lib/commands/link.js @@ -10,6 +10,7 @@ t.cleanSnapshot = (str) => cleanCwd(str) const mockLink = async (t, { globalPrefixDir, ...opts } = {}) => { const mock = await mockNpm(t, { ...opts, + command: 'link', globalPrefixDir, mocks: { ...opts.mocks, @@ -36,10 +37,6 @@ const mockLink = async (t, { globalPrefixDir, ...opts } = {}) => { return { ...mock, - link: { - exec: (args = []) => mock.npm.exec('link', args), - completion: (o) => mock.npm.cmd('link').then(c => c.completion(o)), - }, printLinks, } } diff --git a/deps/npm/test/lib/commands/login.js b/deps/npm/test/lib/commands/login.js index 63666670712ef0..b42d3001ebb903 100644 --- a/deps/npm/test/lib/commands/login.js +++ b/deps/npm/test/lib/commands/login.js @@ -4,26 +4,47 @@ const path = require('path') const ini = require('ini') const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') -const mockGlobals = require('../../fixtures/mock-globals.js') +const mockGlobals = require('@npmcli/mock-globals') const MockRegistry = require('@npmcli/mock-registry') const stream = require('stream') +const mockLogin = async (t, { stdin: stdinLines, registry: registryUrl, ...options } = {}) => { + let stdin + if (stdinLines) { + stdin = new stream.PassThrough() + for (const l of stdinLines) { + stdin.write(l + '\n') + } + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + } + const mock = await loadMockNpm(t, { + ...options, + command: 'login', + }) + const registry = new MockRegistry({ + tap: t, + registry: registryUrl ?? mock.npm.config.get('registry'), + }) + return { + registry, + stdin, + rc: () => ini.parse(fs.readFileSync(path.join(mock.home, '.npmrc'), 'utf8')), + ...mock, + } +} + t.test('usage', async t => { - const { npm } = await loadMockNpm(t) - const login = await npm.cmd('login') + const { login } = await loadMockNpm(t, { command: 'login' }) t.match(login.usage, 'login', 'usage has command name in it') }) t.test('legacy', t => { t.test('basic login', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm, home } = await loadMockNpm(t, { + const { npm, registry, login, rc } = await mockLogin(t, { + stdin: ['test-user', 'test-password'], config: { 'auth-type': 'legacy' }, homeDir: { '.npmrc': [ @@ -33,66 +54,45 @@ t.test('legacy', t => { ].join('\n'), }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.couchlogin({ username: 'test-user', password: 'test-password', token: 'npm_test-token', }) - await npm.exec('login', []) + await login.exec([]) t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '//registry.npmjs.org/:_authToken': 'npm_test-token', email: 'test-email-old@npmjs.org', }, 'should only have token and un-nerfed old email') }) t.test('scoped login default registry', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm, home } = await loadMockNpm(t, { + const { npm, registry, login, rc } = await mockLogin(t, { + stdin: ['test-user', 'test-password'], config: { 'auth-type': 'legacy', scope: '@npmcli', }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.couchlogin({ username: 'test-user', password: 'test-password', token: 'npm_test-token', }) - await npm.exec('login', []) + await login.exec([]) t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') t.same(npm.config.get('@npmcli:registry'), 'https://registry.npmjs.org/') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '//registry.npmjs.org/:_authToken': 'npm_test-token', '@npmcli:registry': 'https://registry.npmjs.org/', }, 'should only have token and scope:registry') }) t.test('scoped login scoped registry', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm, home } = await loadMockNpm(t, { + const { npm, registry, login, rc } = await mockLogin(t, { + stdin: ['test-user', 'test-password'], + registry: 'https://diff-registry.npmjs.org', config: { 'auth-type': 'legacy', scope: '@npmcli', @@ -101,20 +101,15 @@ t.test('legacy', t => { '.npmrc': '@npmcli:registry=https://diff-registry.npmjs.org', }, }) - const registry = new MockRegistry({ - tap: t, - registry: 'https://diff-registry.npmjs.org', - }) registry.couchlogin({ username: 'test-user', password: 'test-password', token: 'npm_test-token', }) - await npm.exec('login', []) + await login.exec([]) t.same(npm.config.get('//diff-registry.npmjs.org/:_authToken'), 'npm_test-token') t.same(npm.config.get('@npmcli:registry'), 'https://diff-registry.npmjs.org') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '@npmcli:registry': 'https://diff-registry.npmjs.org', '//diff-registry.npmjs.org/:_authToken': 'npm_test-token', }, 'should only have token and scope:registry') @@ -124,51 +119,32 @@ t.test('legacy', t => { t.test('web', t => { t.test('basic login', async t => { - const { npm, home } = await loadMockNpm(t, { + const { npm, registry, login, rc } = await mockLogin(t, { config: { 'auth-type': 'web' }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.weblogin({ token: 'npm_test-token' }) - await npm.exec('login', []) + await login.exec([]) t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') - const rc = ini.parse(fs.readFileSync(path.join(home, '.npmrc'), 'utf8')) - t.same(rc, { + t.same(rc(), { '//registry.npmjs.org/:_authToken': 'npm_test-token', }) }) t.test('server error', async t => { - const { npm } = await loadMockNpm(t, { + const { registry, login } = await mockLogin(t, { config: { 'auth-type': 'web' }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.nock.post(registry.fullPath('/-/v1/login')) .reply(503, {}) await t.rejects( - npm.exec('login', []), + login.exec([]), { message: /503/ } ) }) t.test('fallback', async t => { - const stdin = new stream.PassThrough() - stdin.write('test-user\n') - stdin.write('test-password\n') - mockGlobals(t, { - 'process.stdin': stdin, - 'process.stdout': new stream.PassThrough(), // to quiet readline - }, { replace: true }) - const { npm } = await loadMockNpm(t, { + const { npm, registry, login } = await mockLogin(t, { + stdin: ['test-user', 'test-password'], config: { 'auth-type': 'web' }, }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) registry.nock.post(registry.fullPath('/-/v1/login')) .reply(404, {}) registry.couchlogin({ @@ -176,7 +152,7 @@ t.test('web', t => { password: 'test-password', token: 'npm_test-token', }) - await npm.exec('login', []) + await login.exec([]) t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') }) t.end() diff --git a/deps/npm/test/lib/commands/logout.js b/deps/npm/test/lib/commands/logout.js index 0043bb4c57922a..4ff21665f30354 100644 --- a/deps/npm/test/lib/commands/logout.js +++ b/deps/npm/test/lib/commands/logout.js @@ -8,6 +8,7 @@ const mockLogout = async (t, { userRc = [], ...npmOpts } = {}) => { let result = null const mock = await mockNpm(t, { + command: 'logout', mocks: { // XXX: refactor to use mock registry 'npm-registry-fetch': Object.assign(async (url, opts) => { @@ -22,7 +23,6 @@ const mockLogout = async (t, { userRc = [], ...npmOpts } = {}) => { return { ...mock, - logout: { exec: (args) => mock.npm.exec('logout', args) }, result: () => result, // get only the message portion of the verbose log from the command logMsg: () => mock.logs.verbose.find(l => l[0] === 'logout')[1], diff --git a/deps/npm/test/lib/commands/org.js b/deps/npm/test/lib/commands/org.js index d3700304328eea..511251e1bb096e 100644 --- a/deps/npm/test/lib/commands/org.js +++ b/deps/npm/test/lib/commands/org.js @@ -30,6 +30,7 @@ const mockOrg = async (t, { orgSize = 1, orgList = {}, ...npmOpts } = {}) => { const mock = await mockNpm(t, { ...npmOpts, + command: 'org', mocks: { libnpmorg, ...npmOpts.mocks, @@ -38,11 +39,6 @@ const mockOrg = async (t, { orgSize = 1, orgList = {}, ...npmOpts } = {}) => { return { ...mock, - org: { - exec: (args) => mock.npm.exec('org', args), - completion: (arg) => mock.npm.cmd('org').then(c => c.completion(arg)), - usage: () => mock.npm.cmd('org').then(c => c.usage), - }, setArgs: () => setArgs, rmArgs: () => rmArgs, lsArgs: () => lsArgs, @@ -77,7 +73,7 @@ t.test('completion', async t => { t.test('npm org - invalid subcommand', async t => { const { org } = await mockOrg(t) - await t.rejects(org.exec(['foo']), org.usage()) + await t.rejects(org.exec(['foo']), org.usage) }) t.test('npm org add', async t => { diff --git a/deps/npm/test/lib/commands/outdated.js b/deps/npm/test/lib/commands/outdated.js index 02f2067c5480eb..7becc79d62e17d 100644 --- a/deps/npm/test/lib/commands/outdated.js +++ b/deps/npm/test/lib/commands/outdated.js @@ -234,6 +234,7 @@ const fixtures = { const mockNpm = async (t, { prefixDir, ...opts } = {}) => { const res = await _mockNpm(t, { + command: 'outdated', mocks: { pacote: { packument, @@ -255,151 +256,150 @@ const mockNpm = async (t, { prefixDir, ...opts } = {}) => { return { ...res, registry, - exec: (args) => res.npm.exec('outdated', args), } } t.test('should display outdated deps', async t => { await t.test('outdated global', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { globalPrefixDir: fixtures.global, config: { global: true }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { color: 'always', }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --omit=dev', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { omit: ['dev'], color: 'always', }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --omit=dev --omit=peer', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { omit: ['dev', 'peer'], color: 'always', }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --omit=prod', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { omit: ['prod'], color: 'always', }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --long', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { long: true, }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --json', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { json: true, }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --json --long', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { json: true, long: true, }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --parseable', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { parseable: true, }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --parseable --long', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { parseable: true, long: true, }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated --all', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, config: { all: true, }, }) - await exec([]) + await outdated.exec([]) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) await t.test('outdated specific dep', async t => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.local, }) - await exec(['cat']) + await outdated.exec(['cat']) t.equal(process.exitCode, 1) t.matchSnapshot(joinedOutput()) }) @@ -424,11 +424,11 @@ t.test('should return if no outdated deps', async t => { }, } - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: testDir, }) - await exec([]) + await outdated.exec([]) t.equal(joinedOutput(), '', 'no logs') }) @@ -451,11 +451,11 @@ t.test('throws if error with a dep', async t => { }, } - const { exec } = await mockNpm(t, { + const { outdated } = await mockNpm(t, { prefixDir: testDir, }) - await t.rejects(exec([]), 'There is an error with this package.') + await t.rejects(outdated.exec([]), 'There is an error with this package.') }) t.test('should skip missing non-prod deps', async t => { @@ -470,11 +470,11 @@ t.test('should skip missing non-prod deps', async t => { node_modules: {}, } - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: testDir, }) - await exec([]) + await outdated.exec([]) t.equal(joinedOutput(), '', 'no logs') }) @@ -498,10 +498,10 @@ t.test('should skip invalid pkg ranges', async t => { }, } - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: testDir, }) - await exec([]) + await outdated.exec([]) t.equal(joinedOutput(), '', 'no logs') }) @@ -524,21 +524,21 @@ t.test('should skip git specs', async t => { }, } - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: testDir, }) - await exec([]) + await outdated.exec([]) t.equal(joinedOutput(), '', 'no logs') }) t.test('workspaces', async t => { const mockWorkspaces = async (t, { exitCode = 1, ...config } = {}) => { - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: fixtures.workspaces, config, }) - await exec([]) + await outdated.exec([]) t.matchSnapshot(joinedOutput(), 'output') t.equal(process.exitCode, exitCode ?? undefined) @@ -603,10 +603,10 @@ t.test('aliases', async t => { }, } - const { exec, joinedOutput } = await mockNpm(t, { + const { outdated, joinedOutput } = await mockNpm(t, { prefixDir: testDir, }) - await exec([]) + await outdated.exec([]) t.matchSnapshot(joinedOutput(), 'should display aliased outdated dep output') t.equal(process.exitCode, 1) diff --git a/deps/npm/test/lib/commands/owner.js b/deps/npm/test/lib/commands/owner.js index f9399a60cdf81b..9329e8985e60c0 100644 --- a/deps/npm/test/lib/commands/owner.js +++ b/deps/npm/test/lib/commands/owner.js @@ -613,9 +613,10 @@ t.test('workspaces', async t => { }) t.test('completion', async t => { + const mockCompletion = (t, opts) => loadMockNpm(t, { command: 'owner', ...opts }) + t.test('basic commands', async t => { - const { npm } = await loadMockNpm(t) - const owner = await npm.cmd('owner') + const { owner } = await mockCompletion(t) const testComp = async (argv, expect) => { const res = await owner.completion({ conf: { argv: { remain: argv } } }) t.strictSame(res, expect, argv.join(' ')) @@ -631,10 +632,9 @@ t.test('completion', async t => { }) t.test('completion npm owner rm', async t => { - const { npm } = await loadMockNpm(t, { + const { npm, owner } = await mockCompletion(t, { prefixDir: { 'package.json': JSON.stringify({ name: packageName }) }, }) - const owner = await npm.cmd('owner') const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry'), @@ -649,26 +649,23 @@ t.test('completion', async t => { }) t.test('completion npm owner rm no cwd package', async t => { - const { npm } = await loadMockNpm(t) - const owner = await npm.cmd('owner') + const { owner } = await mockCompletion(t) const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, [], 'should have no owners to autocomplete if not cwd package') }) t.test('completion npm owner rm global', async t => { - const { npm } = await loadMockNpm(t, { + const { owner } = await mockCompletion(t, { config: { global: true }, }) - const owner = await npm.cmd('owner') const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, [], 'should have no owners to autocomplete if global') }) t.test('completion npm owner rm no owners found', async t => { - const { npm } = await loadMockNpm(t, { + const { npm, owner } = await mockCompletion(t, { prefixDir: { 'package.json': JSON.stringify({ name: packageName }) }, }) - const owner = await npm.cmd('owner') const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry'), diff --git a/deps/npm/test/lib/commands/pack.js b/deps/npm/test/lib/commands/pack.js index 3e7c0225c3068c..61296cc93a53ae 100644 --- a/deps/npm/test/lib/commands/pack.js +++ b/deps/npm/test/lib/commands/pack.js @@ -28,8 +28,8 @@ t.test('follows pack-destination config', async t => { }), 'tar-destination': {}, }, + config: ({ prefix }) => ({ 'pack-destination': path.join(prefix, 'tar-destination') }), }) - npm.config.set('pack-destination', path.join(npm.prefix, 'tar-destination')) await npm.exec('pack', []) const filename = 'test-package-1.0.0.tgz' t.strictSame(outputs, [[filename]]) @@ -59,8 +59,8 @@ t.test('should log output as valid json', async t => { version: '1.0.0', }), }, + config: { json: true }, }) - npm.config.set('json', true) await npm.exec('pack', []) const filename = 'test-package-1.0.0.tgz' t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json') @@ -76,8 +76,8 @@ t.test('should log scoped package output as valid json', async t => { version: '1.0.0', }), }, + config: { json: true }, }) - npm.config.set('json', true) await npm.exec('pack', []) const filename = 'myscope-test-package-1.0.0.tgz' t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json') @@ -93,8 +93,8 @@ t.test('dry run', async t => { version: '1.0.0', }), }, + config: { 'dry-run': true }, }) - npm.config.set('dry-run', true) await npm.exec('pack', []) const filename = 'test-package-1.0.0.tgz' t.strictSame(outputs, [[filename]]) diff --git a/deps/npm/test/lib/commands/prefix.js b/deps/npm/test/lib/commands/prefix.js index e8295cf6a5b3c3..4fc348843fa255 100644 --- a/deps/npm/test/lib/commands/prefix.js +++ b/deps/npm/test/lib/commands/prefix.js @@ -2,7 +2,7 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm') t.test('prefix', async t => { - const { joinedOutput, npm } = await loadMockNpm(t, { load: false }) + const { joinedOutput, npm } = await loadMockNpm(t) await npm.exec('prefix', []) t.equal( joinedOutput(), diff --git a/deps/npm/test/lib/commands/profile.js b/deps/npm/test/lib/commands/profile.js index 1152acfdc5c468..784523f7ccd8ad 100644 --- a/deps/npm/test/lib/commands/profile.js +++ b/deps/npm/test/lib/commands/profile.js @@ -24,6 +24,7 @@ const mockProfile = async (t, { npmProfile, readUserInfo, qrcode, config, ...opt const mock = await mockNpm(t, { ...opts, + command: 'profile', config: { color: false, ...config, @@ -37,10 +38,6 @@ const mockProfile = async (t, { npmProfile, readUserInfo, qrcode, config, ...opt return { ...mock, result: () => mock.joinedOutput(), - profile: { - exec: (args) => mock.npm.exec('profile', args), - usage: () => mock.npm.cmd('profile').then(c => c.usage), - }, } } @@ -61,7 +58,7 @@ const userProfile = { t.test('no args', async t => { const { profile } = await mockProfile(t) - await t.rejects(profile.exec([]), await profile.usage()) + await t.rejects(profile.exec([]), await profile.usage) }) t.test('profile get no args', async t => { @@ -1081,8 +1078,7 @@ t.test('unknown subcommand', async t => { t.test('completion', async t => { const testComp = async (t, { argv, expect, title } = {}) => { - const { npm } = await mockProfile(t) - const profile = await npm.cmd('profile') + const { profile } = await mockProfile(t) t.resolveMatch(profile.completion({ conf: { argv: { remain: argv } } }), expect, title) } @@ -1114,8 +1110,7 @@ t.test('completion', async t => { }) t.test('npm profile unknown subcommand autocomplete', async t => { - const { npm } = await mockProfile(t) - const profile = await npm.cmd('profile') + const { profile } = await mockProfile(t) t.rejects( profile.completion({ conf: { argv: { remain: ['npm', 'profile', 'asdf'] } } }), { message: 'asdf not recognized' }, diff --git a/deps/npm/test/lib/commands/prune.js b/deps/npm/test/lib/commands/prune.js index 81245bcfca1671..65cfba5e5c00ab 100644 --- a/deps/npm/test/lib/commands/prune.js +++ b/deps/npm/test/lib/commands/prune.js @@ -4,7 +4,6 @@ const { load: loadMockNpm } = require('../../fixtures/mock-npm') t.test('should prune using Arborist', async (t) => { t.plan(4) const { npm } = await loadMockNpm(t, { - load: false, mocks: { '@npmcli/arborist': function (args) { t.ok(args, 'gets options object') diff --git a/deps/npm/test/lib/commands/publish.js b/deps/npm/test/lib/commands/publish.js index 39696066130f9b..820760bb5704da 100644 --- a/deps/npm/test/lib/commands/publish.js +++ b/deps/npm/test/lib/commands/publish.js @@ -172,8 +172,7 @@ t.test('dry-run', async t => { }) t.test('shows usage with wrong set of arguments', async t => { - const { npm } = await loadMockNpm(t) - const publish = await npm.cmd('publish') + const { publish } = await loadMockNpm(t, { command: 'publish' }) await t.rejects(publish.exec(['a', 'b', 'c']), publish.usage) }) @@ -720,3 +719,54 @@ t.test('public access', async t => { t.matchSnapshot(joinedOutput(), 'new package version') t.matchSnapshot(logs.notice) }) + +t.test('manifest', async t => { + // https://github.com/npm/cli/pull/6470#issuecomment-1571234863 + + // snapshot test that was generated against v9.6.7 originally to ensure our + // own manifest does not change unexpectedly when publishing. this test + // asserts a bunch of keys are there that will change often and then snapshots + // the rest of the manifest. + + const root = path.resolve(__dirname, '../../..') + const npmPkg = require(path.join(root, 'package.json')) + + t.cleanSnapshot = (s) => s.replace(new RegExp(npmPkg.version, 'g'), '{VERSION}') + + let manifest = null + const { npm } = await loadMockNpm(t, { + config: { + ...auth, + }, + chdir: () => root, + mocks: { + libnpmpublish: { + publish: (m) => manifest = m, + }, + }, + }) + await npm.exec('publish', []) + + const okKeys = [ + 'contributors', + 'bundleDependencies', + 'dependencies', + 'devDependencies', + 'templateOSS', + 'scripts', + 'tap', + 'readme', + 'gitHead', + 'engines', + 'workspaces', + ] + + for (const k of okKeys) { + t.ok(manifest[k], k) + delete manifest[k] + } + + manifest.man.sort() + + t.matchSnapshot(manifest, 'manifest') +}) diff --git a/deps/npm/test/lib/commands/root.js b/deps/npm/test/lib/commands/root.js index a886b30c3ee485..506e2bc04eb84c 100644 --- a/deps/npm/test/lib/commands/root.js +++ b/deps/npm/test/lib/commands/root.js @@ -2,7 +2,7 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm') t.test('prefix', async (t) => { - const { joinedOutput, npm } = await loadMockNpm(t, { load: false }) + const { joinedOutput, npm } = await loadMockNpm(t) await npm.exec('root', []) t.equal( joinedOutput(), diff --git a/deps/npm/test/lib/commands/run-script.js b/deps/npm/test/lib/commands/run-script.js index 6e2bf22adddcf8..cb54a7f51e9002 100644 --- a/deps/npm/test/lib/commands/run-script.js +++ b/deps/npm/test/lib/commands/run-script.js @@ -11,6 +11,7 @@ const mockRs = async (t, { windows = false, runScript, ...opts } = {}) => { const mock = await mockNpm(t, { ...opts, + command: 'run-script', mocks: { '@npmcli/run-script': Object.assign( async rs => { @@ -28,18 +29,17 @@ const mockRs = async (t, { windows = false, runScript, ...opts } = {}) => { return { ...mock, RUN_SCRIPTS: () => RUN_SCRIPTS, - runScript: { exec: (args) => mock.npm.exec('run-script', args) }, + runScript: mock['run-script'], cleanLogs: () => mock.logs.error.flat().map(v => v.toString()).map(cleanCwd), } } t.test('completion', async t => { const completion = async (t, remain, pkg, isFish = false) => { - const { npm } = await mockRs(t, + const { runScript } = await mockRs(t, pkg ? { prefixDir: { 'package.json': JSON.stringify(pkg) } } : {} ) - const cmd = await npm.cmd('run-script') - return cmd.completion({ conf: { argv: { remain } }, isFish }) + return runScript.completion({ conf: { argv: { remain } }, isFish }) } t.test('already have a script name', async t => { diff --git a/deps/npm/test/lib/commands/stars.js b/deps/npm/test/lib/commands/stars.js index 124d2d344d8dae..d92ced950291f5 100644 --- a/deps/npm/test/lib/commands/stars.js +++ b/deps/npm/test/lib/commands/stars.js @@ -6,6 +6,8 @@ const noop = () => {} const mockStars = async (t, { npmFetch = noop, exec = true, ...opts }) => { const mock = await mockNpm(t, { + command: 'stars', + exec, mocks: { 'npm-registry-fetch': Object.assign(noop, realFetch, { json: npmFetch }), '{LIB}/utils/get-identity.js': async () => 'foo', @@ -13,16 +15,9 @@ const mockStars = async (t, { npmFetch = noop, exec = true, ...opts }) => { ...opts, }) - const stars = { exec: (args) => mock.npm.exec('stars', args) } - - if (exec) { - await stars.exec(Array.isArray(exec) ? exec : []) - mock.result = mock.joinedOutput() - } - return { ...mock, - stars, + result: mock.stars.output, logs: () => mock.logs.filter(l => l[1] === 'stars').map(l => l[2]), } } @@ -45,7 +40,7 @@ t.test('no args', async t => { } } - const { result } = await mockStars(t, { npmFetch, exec: true }) + const { result } = await mockStars(t, { npmFetch }) t.matchSnapshot( result, @@ -122,7 +117,7 @@ t.test('unexpected error', async t => { t.test('no pkg starred', async t => { const npmFetch = async () => ({ rows: [] }) - const { logs } = await mockStars(t, { npmFetch, exec: true }) + const { logs } = await mockStars(t, { npmFetch }) t.strictSame( logs(), diff --git a/deps/npm/test/lib/commands/team.js b/deps/npm/test/lib/commands/team.js index a13a56d986e35e..1a5480293edc9b 100644 --- a/deps/npm/test/lib/commands/team.js +++ b/deps/npm/test/lib/commands/team.js @@ -6,6 +6,7 @@ t.cleanSnapshot = s => s.trim().replace(/\n+/g, '\n') const mockTeam = async (t, { libnpmteam, ...opts } = {}) => { const mock = await mockNpm(t, { ...opts, + command: 'team', mocks: { // XXX: this should be refactored to use the mock registry libnpmteam: libnpmteam || { @@ -21,7 +22,6 @@ const mockTeam = async (t, { libnpmteam, ...opts } = {}) => { return { ...mock, - team: { exec: (args) => mock.npm.exec('team', args) }, result: () => mock.joinedOutput(), } } @@ -384,11 +384,10 @@ t.test('team rm ', async t => { }) t.test('completion', async t => { - const { npm } = await mockTeam(t) - const { completion } = await npm.cmd('team') + const { team } = await mockTeam(t) t.test('npm team autocomplete', async t => { - const res = await completion({ + const res = await team.completion({ conf: { argv: { remain: ['npm', 'team'], @@ -405,7 +404,7 @@ t.test('completion', async t => { t.test('npm team autocomplete', async t => { for (const subcmd of ['create', 'destroy', 'add', 'rm', 'ls']) { - const res = await completion({ + const res = await team.completion({ conf: { argv: { remain: ['npm', 'team', subcmd], @@ -421,7 +420,8 @@ t.test('completion', async t => { }) t.test('npm team unknown subcommand autocomplete', async t => { - t.rejects(completion({ conf: { argv: { remain: ['npm', 'team', 'missing-subcommand'] } } }), + t.rejects( + team.completion({ conf: { argv: { remain: ['npm', 'team', 'missing-subcommand'] } } }), { message: 'missing-subcommand not recognized' }, 'should throw a a not recognized error' ) diff --git a/deps/npm/test/lib/commands/token.js b/deps/npm/test/lib/commands/token.js index 1fd686a4427c9b..2bc4af4a81a3d1 100644 --- a/deps/npm/test/lib/commands/token.js +++ b/deps/npm/test/lib/commands/token.js @@ -14,6 +14,7 @@ const mockToken = async (t, { profile, getCredentialsByURI, readUserInfo, ...opt const mock = await mockNpm(t, { ...opts, + command: 'token', mocks, }) @@ -22,22 +23,14 @@ const mockToken = async (t, { profile, getCredentialsByURI, readUserInfo, ...opt mock.npm.config.getCredentialsByURI = getCredentialsByURI } - const token = { - exec: (args) => mock.npm.exec('token', args), - } - - return { - ...mock, - token, - } + return mock } t.test('completion', async t => { - const { npm } = await mockToken(t) - const { completion } = await npm.cmd('token') + const { token } = await mockToken(t) const testComp = (argv, expect) => { - t.resolveMatch(completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' ')) + t.resolveMatch(token.completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' ')) } testComp(['npm', 'token'], ['list', 'revoke', 'create']) @@ -45,7 +38,7 @@ t.test('completion', async t => { testComp(['npm', 'token', 'revoke'], []) testComp(['npm', 'token', 'create'], []) - t.rejects(completion({ conf: { argv: { remain: ['npm', 'token', 'foobar'] } } }), { + t.rejects(token.completion({ conf: { argv: { remain: ['npm', 'token', 'foobar'] } } }), { message: 'foobar not recognize', }) }) diff --git a/deps/npm/test/lib/commands/uninstall.js b/deps/npm/test/lib/commands/uninstall.js index 59a517d144d38a..ae116d44c208bf 100644 --- a/deps/npm/test/lib/commands/uninstall.js +++ b/deps/npm/test/lib/commands/uninstall.js @@ -188,19 +188,15 @@ t.test('no args global but no package.json', async t => { ) }) -t.test('unknown error reading from localPrefix package.json', async t => { +t.test('non ENOENT error reading from localPrefix package.json', async t => { const { uninstall } = await mockNpm(t, { config: { global: true }, - mocks: { - 'read-package-json-fast': async () => { - throw new Error('ERR') - }, - }, + prefixDir: { 'package.json': 'not[json]' }, }) await t.rejects( uninstall([]), - /ERR/, - 'should throw unknown error' + { code: 'EJSONPARSE' }, + 'should throw non ENOENT error' ) }) diff --git a/deps/npm/test/lib/commands/unpublish.js b/deps/npm/test/lib/commands/unpublish.js index 96c06bf3ffee69..6e898bd3d07e4b 100644 --- a/deps/npm/test/lib/commands/unpublish.js +++ b/deps/npm/test/lib/commands/unpublish.js @@ -58,7 +58,7 @@ t.test('no args --force error reading package.json', async t => { await t.rejects( npm.exec('unpublish', []), - /Failed to parse json/, + /Invalid package.json/, 'should throw error from reading package.json' ) }) @@ -427,13 +427,13 @@ t.test('scoped registry config', async t => { }) t.test('completion', async t => { - const { npm } = await loadMockNpm(t, { + const { npm, unpublish } = await loadMockNpm(t, { + command: 'unpublish', config: { ...auth, }, }) - const unpublish = await npm.cmd('unpublish') const testComp = async (t, { argv, partialWord, expect, title }) => { const res = await unpublish.completion( diff --git a/deps/npm/test/lib/commands/version.js b/deps/npm/test/lib/commands/version.js index c48ff827fa28cb..8aa6c088bfc9b5 100644 --- a/deps/npm/test/lib/commands/version.js +++ b/deps/npm/test/lib/commands/version.js @@ -2,11 +2,12 @@ const { readFileSync, statSync } = require('fs') const { resolve } = require('path') const t = require('tap') const _mockNpm = require('../../fixtures/mock-npm') -const mockGlobals = require('../../fixtures/mock-globals.js') +const mockGlobals = require('@npmcli/mock-globals') const mockNpm = async (t, opts = {}) => { const res = await _mockNpm(t, { ...opts, + command: 'version', mocks: { ...opts.mocks, '{ROOT}/package.json': { version: '1.0.0' }, @@ -14,7 +15,6 @@ const mockNpm = async (t, opts = {}) => { }) return { ...res, - version: { exec: (args) => res.npm.exec('version', args) }, result: () => res.outputs[0], } } @@ -55,8 +55,7 @@ t.test('node@1', async t => { }) t.test('completion', async t => { - const { npm } = await mockNpm(t) - const version = await npm.cmd('version') + const { version } = await mockNpm(t) const testComp = async (argv, expect) => { const res = await version.completion({ conf: { argv: { remain: argv } } }) t.strictSame(res, expect, argv.join(' ')) diff --git a/deps/npm/test/lib/commands/view.js b/deps/npm/test/lib/commands/view.js index 51bc130df24e5e..ca07ef9eec2ff6 100644 --- a/deps/npm/test/lib/commands/view.js +++ b/deps/npm/test/lib/commands/view.js @@ -576,8 +576,7 @@ t.test('workspaces', async t => { }) t.test('completion', async t => { - const { npm } = await loadMockNpm(t) - const view = await npm.cmd('view') + const { view } = await loadMockNpm(t, { command: 'view' }) const res = await view.completion({ conf: { argv: { remain: ['npm', 'view', 'green@1.0.0'] } }, }) @@ -585,8 +584,7 @@ t.test('completion', async t => { }) t.test('no package completion', async t => { - const { npm } = await loadMockNpm(t) - const view = await npm.cmd('view') + const { view } = await loadMockNpm(t, { command: 'view' }) const res = await view.completion({ conf: { argv: { remain: ['npm', 'view'] } } }) t.notOk(res, 'there is no package completion') t.end() diff --git a/deps/npm/test/lib/docs.js b/deps/npm/test/lib/docs.js index b8a1a4fc600747..5e7bfe45a93ccc 100644 --- a/deps/npm/test/lib/docs.js +++ b/deps/npm/test/lib/docs.js @@ -1,14 +1,14 @@ const t = require('tap') -const { join, resolve, basename, extname, dirname } = require('path') +const { join, resolve, basename, extname } = require('path') const fs = require('fs/promises') const localeCompare = require('@isaacs/string-locale-compare')('en') const docs = require('@npmcli/docs') const { load: loadMockNpm } = require('../fixtures/mock-npm.js') -const mockGlobals = require('../fixtures/mock-globals.js') const { definitions } = require('../../lib/utils/config/index.js') const cmdList = require('../../lib/utils/cmd-list.js') const pkg = require('../../package.json') +const { cleanCwd } = require('../fixtures/clean-snapshot.js') t.test('command list', async t => { for (const [key, value] of Object.entries(cmdList)) { @@ -30,23 +30,48 @@ t.test('config', async t => { t.matchSnapshot(docs.config(docs.TAGS.CONFIG, {}), 'all definitions') }) -t.test('basic usage', async t => { - mockGlobals(t, { process: { platform: 'posix' } }) +t.test('flat options', async t => { + t.cleanSnapshot = (s) => cleanCwd(s) + .split(cleanCwd(process.execPath)).join('{NODE}') - t.cleanSnapshot = str => str - .split(dirname(dirname(__dirname))).join('{BASEDIR}') - .split(pkg.version).join('{VERSION}') + const { npm } = await loadMockNpm(t, { + command: 'version', + exec: true, + globals: { + 'process.env': { + EDITOR: '{EDITOR}', + SHELL: '{SHELL}', + }, + 'process.version': '2.2.2', + 'process.platform': '{PLATFORM}', + 'process.arch': '{ARCH}', + }, + mocks: { + 'ci-info': { name: '{CI}' }, + '{ROOT}/package.json': { version: '1.1.1' }, + }, + }) + + t.matchSnapshot(npm.flatOptions, 'full flat options object') +}) +t.test('basic usage', async t => { // snapshot basic usage without commands since all the command snapshots // are generated in the following test const { npm } = await loadMockNpm(t, { mocks: { '{LIB}/utils/cmd-list.js': { commands: [] }, }, + config: { userconfig: '/some/config/file/.npmrc' }, + globals: { process: { platform: 'posix' } }, }) - npm.config.set('userconfig', '/some/config/file/.npmrc') - t.matchSnapshot(await npm.usage) + t.cleanSnapshot = str => str + .replace(npm.npmRoot, '{BASEDIR}') + .replace(npm.config.get('userconfig'), '{USERCONFIG}') + .split(pkg.version).join('{VERSION}') + + t.matchSnapshot(npm.usage) }) t.test('usage', async t => { @@ -81,9 +106,8 @@ t.test('usage', async t => { t.test(cmd, async t => { let output = null if (!bareCommands.includes(cmd)) { - const { npm } = await loadMockNpm(t) - const impl = await npm.cmd(cmd) - output = impl.usage + const mock = await loadMockNpm(t, { command: cmd }) + output = mock[cmd].usage } const usage = docs.usage(docs.TAGS.USAGE, { path: cmd }) diff --git a/deps/npm/test/lib/es6/validate-engines.js b/deps/npm/test/lib/es6/validate-engines.js new file mode 100644 index 00000000000000..0e6bce726af966 --- /dev/null +++ b/deps/npm/test/lib/es6/validate-engines.js @@ -0,0 +1,34 @@ +const t = require('tap') +const mockGlobals = require('@npmcli/mock-globals') +const tmock = require('../../fixtures/tmock') + +const mockValidateEngines = (t) => { + const validateEngines = tmock(t, '{LIB}/es6/validate-engines.js', { + '{ROOT}/package.json': { version: '1.2.3', engines: { node: '>=0' } }, + }) + mockGlobals(t, { 'process.version': 'v4.5.6' }) + return validateEngines(process, () => (_, r) => r) +} + +t.test('validate engines', async t => { + t.equal(process.listenerCount('uncaughtException'), 0) + t.equal(process.listenerCount('unhandledRejection'), 0) + + const result = mockValidateEngines(t) + + t.equal(process.listenerCount('uncaughtException'), 1) + t.equal(process.listenerCount('unhandledRejection'), 1) + + t.match(result, { + node: 'v4.5.6', + npm: 'v1.2.3', + engines: '>=0', + /* eslint-disable-next-line max-len */ + unsupportedMessage: 'npm v1.2.3 does not support Node.js v4.5.6. This version of npm supports the following node versions: `>=0`. You can find the latest version at https://nodejs.org/.', + }) + + result.off() + + t.equal(process.listenerCount('uncaughtException'), 0) + t.equal(process.listenerCount('unhandledRejection'), 0) +}) diff --git a/deps/npm/test/lib/fixtures/mock-globals.js b/deps/npm/test/lib/fixtures/mock-globals.js deleted file mode 100644 index 55418dd8e199d7..00000000000000 --- a/deps/npm/test/lib/fixtures/mock-globals.js +++ /dev/null @@ -1,331 +0,0 @@ -const t = require('tap') -const mockGlobals = require('../../fixtures/mock-globals') - -/* eslint-disable no-console */ -const originals = { - platform: process.platform, - error: console.error, - stderrOn: process.stderr.on, - stderrWrite: process.stderr.write, - shell: process.env.SHELL, - home: process.env.HOME, - argv: process.argv, - env: process.env, - setInterval, -} - -t.test('console', async t => { - await t.test('mocks', async (t) => { - const errors = [] - mockGlobals(t, { - 'console.error': (...args) => errors.push(...args), - }) - - console.error(1) - console.error(2) - console.error(3) - t.strictSame(errors, [1, 2, 3], 'i got my errors') - }) - - t.equal(console.error, originals.error) -}) -/* eslint-enable no-console */ - -t.test('platform', async (t) => { - t.equal(process.platform, originals.platform) - - await t.test('posix', async (t) => { - mockGlobals(t, { 'process.platform': 'posix' }) - t.equal(process.platform, 'posix') - - await t.test('win32 --> woo', async (t) => { - mockGlobals(t, { 'process.platform': 'win32' }) - t.equal(process.platform, 'win32') - - mockGlobals(t, { 'process.platform': 'woo' }) - t.equal(process.platform, 'woo') - }) - - t.equal(process.platform, 'posix') - }) - - t.equal(process.platform, originals.platform) -}) - -t.test('manual reset', async t => { - let errorHandler, data - - const { reset } = mockGlobals(t, { - 'process.stderr.on': (__, handler) => { - errorHandler = handler - reset['process.stderr.on']() - }, - 'process.stderr.write': (chunk, callback) => { - data = chunk - process.nextTick(() => { - errorHandler({ errno: 'EPIPE' }) - callback() - }) - reset['process.stderr.write']() - }, - }) - - await new Promise((res, rej) => { - process.stderr.on('error', er => er.errno === 'EPIPE' ? res() : rej(er)) - process.stderr.write('hey', res) - }) - - t.equal(process.stderr.on, originals.stderrOn) - t.equal(process.stderr.write, originals.stderrWrite) - t.equal(data, 'hey', 'handles EPIPE errors') - t.ok(errorHandler) -}) - -t.test('reset called multiple times', async (t) => { - await t.test('single reset', async t => { - const { reset } = mockGlobals(t, { 'process.platform': 'z' }) - t.equal(process.platform, 'z') - - reset['process.platform']() - t.equal(process.platform, originals.platform) - - reset['process.platform']() - reset['process.platform']() - reset['process.platform']() - t.equal(process.platform, originals.platform) - }) - - t.equal(process.platform, originals.platform) -}) - -t.test('object mode', async t => { - await t.test('mocks', async t => { - const home = t.testdir() - - mockGlobals(t, { - process: { - stderr: { - on: '1', - }, - env: { - HOME: home, - }, - }, - }) - - t.equal(process.stderr.on, '1') - t.equal(process.env.HOME, home) - }) - - t.equal(process.env.HOME, originals.home) - t.equal(process.stderr.write, originals.stderrWrite) -}) - -t.test('mixed object/string mode', async t => { - await t.test('mocks', async t => { - const home = t.testdir() - - mockGlobals(t, { - 'process.env': { - HOME: home, - TEST: '1', - }, - }) - - t.equal(process.env.HOME, home) - t.equal(process.env.TEST, '1') - }) - - t.equal(process.env.HOME, originals.home) - t.equal(process.env.TEST, undefined) -}) - -t.test('conflicting mixed object/string mode', async t => { - await t.test('same key', async t => { - t.throws( - () => mockGlobals(t, { - process: { - env: { - HOME: '1', - TEST: '1', - NODE_ENV: '1', - }, - stderr: { - write: '1', - }, - }, - 'process.env.HOME': '1', - 'process.stderr.write': '1', - }), - /process.env.HOME,process.stderr.write/ - ) - }) - - await t.test('partial overwrite with replace', async t => { - t.throws( - () => mockGlobals(t, { - process: { - env: { - HOME: '1', - TEST: '1', - NODE_ENV: '1', - }, - stderr: { - write: '1', - }, - }, - 'process.env.HOME': '1', - 'process.stderr.write': '1', - }, { replace: true }), - /process -> process.env.HOME,process.stderr.write/ - ) - }) -}) - -t.test('falsy values', async t => { - await t.test('undefined deletes', async t => { - mockGlobals(t, { 'process.platform': undefined }) - t.notOk(Object.prototype.hasOwnProperty.call(process, 'platform')) - t.equal(process.platform, undefined) - }) - - await t.test('null', async t => { - mockGlobals(t, { 'process.platform': null }) - t.ok(Object.prototype.hasOwnProperty.call(process, 'platform')) - t.equal(process.platform, null) - }) - - t.equal(process.platform, originals.platform) -}) - -t.test('date', async t => { - await t.test('mocks', async t => { - mockGlobals(t, { - 'Date.now': () => 100, - 'Date.prototype.toISOString': () => 'DDD', - }) - t.equal(Date.now(), 100) - t.equal(new Date().toISOString(), 'DDD') - }) - - t.ok(Date.now() > 100) - t.ok(new Date().toISOString().includes('T')) -}) - -t.test('argv', async t => { - await t.test('argv', async t => { - mockGlobals(t, { 'process.argv': ['node', 'woo'] }) - t.strictSame(process.argv, ['node', 'woo']) - }) - - t.strictSame(process.argv, originals.argv) -}) - -t.test('replace', async (t) => { - await t.test('env', async t => { - mockGlobals(t, { 'process.env': { HOME: '1' } }, { replace: true }) - t.strictSame(process.env, { HOME: '1' }) - t.equal(Object.keys(process.env).length, 1) - }) - - await t.test('setInterval', async t => { - mockGlobals(t, { setInterval: 0 }, { replace: true }) - t.strictSame(setInterval, 0) - }) - - t.strictSame(setInterval, originals.setInterval) - t.strictSame(process.env, originals.env) -}) - -t.test('dot key', async t => { - const dotKey = 'this.is.a.single.key' - mockGlobals(t, { - [`process.env."${dotKey}"`]: 'value', - }) - t.strictSame(process.env[dotKey], 'value') -}) - -t.test('multiple mocks and resets', async (t) => { - const initial = 'a' - const platforms = ['b', 'c', 'd', 'e', 'f', 'g'] - - await t.test('first in, first out', async t => { - mockGlobals(t, { 'process.platform': initial }) - t.equal(process.platform, initial) - - await t.test('platforms', async (t) => { - const resets = platforms.map((platform) => { - const { reset } = mockGlobals(t, { 'process.platform': platform }) - t.equal(process.platform, platform) - return reset['process.platform'] - }).reverse() - - ;[...platforms.reverse()].forEach((platform, index) => { - const reset = resets[index] - const nextPlatform = index === platforms.length - 1 ? initial : platforms[index + 1] - t.equal(process.platform, platform) - reset() - t.equal(process.platform, nextPlatform, 'first reset') - reset() - reset() - t.equal(process.platform, nextPlatform, 'multiple resets are indempotent') - }) - }) - - t.equal(process.platform, initial) - }) - - await t.test('last in,first out', async t => { - mockGlobals(t, { 'process.platform': initial }) - t.equal(process.platform, initial) - - await t.test('platforms', async (t) => { - const resets = platforms.map((platform) => { - const { reset } = mockGlobals(t, { 'process.platform': platform }) - t.equal(process.platform, platform) - return reset['process.platform'] - }) - - resets.forEach((reset, index) => { - // Calling a reset out of order removes it from the stack - // but does not change the descriptor so it should still be the - // last in descriptor until there are none left - const lastPlatform = platforms[platforms.length - 1] - const nextPlatform = index === platforms.length - 1 ? initial : lastPlatform - t.equal(process.platform, lastPlatform) - reset() - t.equal(process.platform, nextPlatform, 'multiple resets are indempotent') - reset() - reset() - t.equal(process.platform, nextPlatform, 'multiple resets are indempotent') - }) - }) - - t.equal(process.platform, initial) - }) - - t.test('reset all', async (t) => { - const { teardown } = mockGlobals(t, { 'process.platform': initial }) - - await t.test('platforms', async (t) => { - const resets = platforms.map((p) => { - const { teardown: nestedTeardown, reset } = mockGlobals(t, { 'process.platform': p }) - t.equal(process.platform, p) - return [ - reset['process.platform'], - nestedTeardown, - ] - }) - - resets.forEach(r => r[1]()) - t.equal(process.platform, initial, 'teardown goes to initial value') - - resets.forEach((r) => r[0]()) - t.equal(process.platform, initial, 'calling resets after teardown does nothing') - }) - - t.equal(process.platform, initial) - teardown() - t.equal(process.platform, originals.platform) - }) -}) diff --git a/deps/npm/test/lib/load-all-commands.js b/deps/npm/test/lib/load-all-commands.js index 1742376a36e69d..d3846434489cee 100644 --- a/deps/npm/test/lib/load-all-commands.js +++ b/deps/npm/test/lib/load-all-commands.js @@ -6,20 +6,30 @@ const t = require('tap') const util = require('util') const { load: loadMockNpm } = require('../fixtures/mock-npm.js') const { commands } = require('../../lib/utils/cmd-list.js') +const BaseCommand = require('../../lib/base-command.js') const isAsyncFn = (v) => typeof v === 'function' && /^\[AsyncFunction:/.test(util.inspect(v)) t.test('load each command', async t => { + const counts = { + completion: 0, + ignoreImplicitWorkspace: 0, + workspaces: 0, + noParams: 0, + } + for (const cmd of commands) { - t.test(cmd, async t => { + await t.test(cmd, async t => { const { npm, outputs, cmd: impl } = await loadMockNpm(t, { command: cmd, config: { usage: true }, }) const ctor = impl.constructor - if (impl.completion) { - t.type(impl.completion, 'function', 'completion, if present, is a function') + t.notOk(impl.completion, 'completion is static, not on instance') + if (ctor.completion) { + t.ok(isAsyncFn(ctor.completion), 'completion is async function') + counts.completion++ } // exec fn @@ -28,7 +38,15 @@ t.test('load each command', async t => { // workspaces t.type(ctor.ignoreImplicitWorkspace, 'boolean', 'ctor has ignoreImplictWorkspace boolean') + if (ctor.ignoreImplicitWorkspace !== BaseCommand.ignoreImplicitWorkspace) { + counts.ignoreImplicitWorkspace++ + } + t.type(ctor.workspaces, 'boolean', 'ctor has workspaces boolean') + if (ctor.workspaces !== BaseCommand.workspaces) { + counts.workspaces++ + } + if (ctor.workspaces) { t.ok(isAsyncFn(impl.execWorkspaces), 'execWorkspaces is async') t.ok(impl.exec.length <= 1, 'execWorkspaces fn has 0 or 1 args') @@ -38,13 +56,32 @@ t.test('load each command', async t => { // name/desc t.ok(impl.description, 'implementation has a description') + t.equal(impl.description, ctor.description, 'description is same on instance and ctor') t.ok(impl.name, 'implementation has a name') + t.equal(impl.name, ctor.name, 'name is same on instance and ctor') t.equal(cmd, impl.name, 'command list and name are the same') + // params are optional + if (impl.params) { + t.equal(impl.params, ctor.params, 'params is same on instance and ctor') + t.ok(impl.params, 'implementation has a params') + } else { + counts.noParams++ + } + // usage t.match(impl.usage, cmd, 'usage contains the command') await npm.exec(cmd, []) t.match(outputs[0][0], impl.usage, 'usage is what is output') + t.match(outputs[0][0], ctor.describeUsage, 'usage is what is output') + t.notOk(impl.describeUsage, 'describe usage is only static') }) } + + // make sure refactors dont move or rename these static properties since + // we guard against the tests for them above + t.ok(counts.completion > 0, 'has some completion functions') + t.ok(counts.ignoreImplicitWorkspace > 0, 'has some commands that change ignoreImplicitWorkspace') + t.ok(counts.workspaces > 0, 'has some commands that change workspaces') + t.ok(counts.noParams > 0, 'has some commands that do not have params') }) diff --git a/deps/npm/test/lib/npm.js b/deps/npm/test/lib/npm.js index 61b31be6200286..162e8c83ca4a4d 100644 --- a/deps/npm/test/lib/npm.js +++ b/deps/npm/test/lib/npm.js @@ -2,7 +2,7 @@ const t = require('tap') const { resolve, dirname, join } = require('path') const fs = require('fs') const { load: loadMockNpm } = require('../fixtures/mock-npm.js') -const mockGlobals = require('../fixtures/mock-globals') +const mockGlobals = require('@npmcli/mock-globals') const { commands } = require('../../lib/utils/cmd-list.js') t.test('not yet loaded', async t => { @@ -105,10 +105,6 @@ t.test('npm.load', async t => { mockGlobals(t, { process: { platform: 'win32' } }) t.equal(npm.bin, npm.globalBin, 'bin is global bin in windows mode') t.equal(npm.dir, npm.globalDir, 'dir is global dir in windows mode') - - const tmp = npm.tmp - t.match(tmp, String, 'npm.tmp is a string') - t.equal(tmp, npm.tmp, 'getter only generates it once') }) await t.test('forceful loading', async t => { @@ -127,7 +123,7 @@ t.test('npm.load', async t => { await t.test('node is a symlink', async t => { const node = process.platform === 'win32' ? 'node.exe' : 'node' - const { npm, logs, outputs, prefix } = await loadMockNpm(t, { + const { Npm, npm, logs, outputs, prefix } = await loadMockNpm(t, { prefixDir: { bin: t.fixture('symlink', dirname(process.execPath)), }, @@ -168,8 +164,8 @@ t.test('npm.load', async t => { t.equal(npm.command, 'll', 'command set to first npm command') t.equal(npm.flatOptions.npmCommand, 'll', 'npmCommand flatOption set') - const ll = await npm.cmd('ll') - t.same(outputs, [[ll.usage]], 'print usage') + const ll = Npm.cmd('ll') + t.same(outputs, [[ll.describeUsage]], 'print usage') npm.config.set('usage', false) outputs.length = 0 @@ -202,7 +198,6 @@ t.test('npm.load', async t => { await t.test('--no-workspaces with --workspace', async t => { const { npm } = await loadMockNpm(t, { - load: false, prefixDir: { packages: { a: { @@ -554,14 +549,14 @@ t.test('output clears progress and console.logs the message', async t => { }) t.test('aliases and typos', async t => { - const { npm } = await loadMockNpm(t, { load: false }) - await t.rejects(npm.cmd('thisisnotacommand'), { code: 'EUNKNOWNCOMMAND' }) - await t.rejects(npm.cmd(''), { code: 'EUNKNOWNCOMMAND' }) - await t.rejects(npm.cmd('birthday'), { code: 'EUNKNOWNCOMMAND' }) - await t.resolves(npm.cmd('it'), { name: 'install-test' }) - await t.resolves(npm.cmd('installTe'), { name: 'install-test' }) - await t.resolves(npm.cmd('access'), { name: 'access' }) - await t.resolves(npm.cmd('auth'), { name: 'owner' }) + const { Npm } = await loadMockNpm(t, { init: false }) + t.throws(() => Npm.cmd('thisisnotacommand'), { code: 'EUNKNOWNCOMMAND' }) + t.throws(() => Npm.cmd(''), { code: 'EUNKNOWNCOMMAND' }) + t.throws(() => Npm.cmd('birthday'), { code: 'EUNKNOWNCOMMAND' }) + t.match(Npm.cmd('it').name, 'install-test') + t.match(Npm.cmd('installTe').name, 'install-test') + t.match(Npm.cmd('access').name, 'access') + t.match(Npm.cmd('auth').name, 'owner') }) t.test('explicit workspace rejection', async t => { @@ -663,30 +658,28 @@ t.test('implicit workspace accept', async t => { t.test('usage', async t => { t.test('with browser', async t => { - mockGlobals(t, { process: { platform: 'posix' } }) - const { npm } = await loadMockNpm(t) - const usage = await npm.usage + const { npm } = await loadMockNpm(t, { globals: { process: { platform: 'posix' } } }) + const usage = npm.usage npm.config.set('viewer', 'browser') - const browserUsage = await npm.usage + const browserUsage = npm.usage t.notMatch(usage, '(in a browser)') t.match(browserUsage, '(in a browser)') }) t.test('windows always uses browser', async t => { - mockGlobals(t, { process: { platform: 'win32' } }) - const { npm } = await loadMockNpm(t) - const usage = await npm.usage + const { npm } = await loadMockNpm(t, { globals: { process: { platform: 'win32' } } }) + const usage = npm.usage npm.config.set('viewer', 'browser') - const browserUsage = await npm.usage + const browserUsage = npm.usage t.match(usage, '(in a browser)') t.match(browserUsage, '(in a browser)') }) t.test('includes commands', async t => { const { npm } = await loadMockNpm(t) - const usage = await npm.usage + const usage = npm.usage npm.config.set('long', true) - const longUsage = await npm.usage + const longUsage = npm.usage const lastCmd = commands[commands.length - 1] for (const cmd of commands) { @@ -719,7 +712,7 @@ t.test('usage', async t => { for (const width of widths) { t.test(`column width ${width}`, async t => { mockGlobals(t, { 'process.stdout.columns': width }) - const usage = await npm.usage + const usage = npm.usage t.matchSnapshot(usage) }) } diff --git a/deps/npm/test/lib/utils/ansi-trim.js b/deps/npm/test/lib/utils/ansi-trim.js index de8d3929370001..5a9e3b0c87cba7 100644 --- a/deps/npm/test/lib/utils/ansi-trim.js +++ b/deps/npm/test/lib/utils/ansi-trim.js @@ -1,5 +1,8 @@ const t = require('tap') const ansiTrim = require('../../../lib/utils/ansi-trim.js') -const chalk = require('chalk') -t.equal(ansiTrim('foo'), 'foo', 'does nothing if no ansis') -t.equal(ansiTrim(chalk.red('foo')), 'foo', 'strips out ansis') + +t.test('basic', async t => { + const chalk = await import('chalk').then(v => v.default) + t.equal(ansiTrim('foo'), 'foo', 'does nothing if no ansis') + t.equal(ansiTrim(chalk.red('foo')), 'foo', 'strips out ansis') +}) diff --git a/deps/npm/test/lib/utils/audit-error.js b/deps/npm/test/lib/utils/audit-error.js index 1cb29a0857d752..f6be56a152f710 100644 --- a/deps/npm/test/lib/utils/audit-error.js +++ b/deps/npm/test/lib/utils/audit-error.js @@ -10,6 +10,8 @@ const auditError = async (t, { command, error, ...config } = {}) => { const mock = await mockNpm(t, { command, config, + exec: true, + prefixDir: { 'package.json': '{}', 'package-lock.json': '{}' }, }) const res = {} @@ -32,7 +34,8 @@ t.test('no error, not audit command', async t => { t.equal(result, false, 'no error') t.notOk(error, 'no error') - t.strictSame(output, '', 'no output') + t.match(output.trim(), /up to date/, 'install output') + t.match(output.trim(), /found 0 vulnerabilities/, 'install output') t.strictSame(logs, [], 'no warnings') }) @@ -53,7 +56,8 @@ t.test('error, not audit command', async t => { t.equal(result, true, 'had error') t.notOk(error, 'no error') - t.strictSame(output, '', 'no output') + t.match(output.trim(), /up to date/, 'install output') + t.match(output.trim(), /found 0 vulnerabilities/, 'install output') t.strictSame(logs, [], 'no warnings') }) @@ -62,7 +66,7 @@ t.test('error, audit command, not json', async t => { command: 'audit', error: { message: 'message', - body: Buffer.from('body'), + body: Buffer.from('body error text'), method: 'POST', uri: 'https://example.com/not/a/registry', headers: { @@ -75,7 +79,7 @@ t.test('error, audit command, not json', async t => { t.equal(result, undefined) t.ok(error, 'throws error') - t.strictSame(output, 'body', 'some output') + t.match(output, 'body error text', 'some output') t.strictSame(logs, [['audit', 'message']], 'some warnings') }) @@ -97,7 +101,7 @@ t.test('error, audit command, json', async t => { t.equal(result, undefined) t.ok(error, 'throws error') - t.strictSame(output, + t.match(output, '{\n' + ' "message": "message",\n' + ' "method": "POST",\n' + diff --git a/deps/npm/test/lib/utils/completion/installed-deep.js b/deps/npm/test/lib/utils/completion/installed-deep.js index 434d0214db4c84..0af26861ff83a5 100644 --- a/deps/npm/test/lib/utils/completion/installed-deep.js +++ b/deps/npm/test/lib/utils/completion/installed-deep.js @@ -1,32 +1,6 @@ -const { resolve } = require('path') const t = require('tap') const installedDeep = require('../../../../lib/utils/completion/installed-deep.js') - -let prefix -let globalDir = 'MISSING_GLOBAL_DIR' -const _flatOptions = { - depth: Infinity, - global: false, - workspacesEnabled: true, - Arborist: require('@npmcli/arborist'), - get prefix () { - return prefix - }, -} -const npm = { - flatOptions: _flatOptions, - get prefix () { - return _flatOptions.prefix - }, - get globalDir () { - return globalDir - }, - config: { - get (key) { - return _flatOptions[key] - }, - }, -} +const mockNpm = require('../../../fixtures/mock-npm') const fixture = { 'package.json': JSON.stringify({ @@ -153,16 +127,23 @@ const globalFixture = { }, } -t.test('get list of package names', async t => { - const fix = t.testdir({ - local: fixture, - global: globalFixture, +const mockDeep = async (t, config) => { + const mock = await mockNpm(t, { + prefixDir: fixture, + globalPrefixDir: globalFixture, + config: { + depth: Infinity, + ...config, + }, }) - prefix = resolve(fix, 'local') - globalDir = resolve(fix, 'global/node_modules') + const res = await installedDeep(mock.npm) - const res = await installedDeep(npm, null) + return res +} + +t.test('get list of package names', async t => { + const res = await mockDeep(t) t.same( res, [ @@ -179,17 +160,7 @@ t.test('get list of package names', async t => { }) t.test('get list of package names as global', async t => { - const fix = t.testdir({ - local: fixture, - global: globalFixture, - }) - - prefix = resolve(fix, 'local') - globalDir = resolve(fix, 'global/node_modules') - - _flatOptions.global = true - - const res = await installedDeep(npm, null) + const res = await mockDeep(t, { global: true }) t.same( res, [ @@ -199,22 +170,10 @@ t.test('get list of package names as global', async t => { ], 'should return list of global packages with no extra flags' ) - _flatOptions.global = false - t.end() }) t.test('limit depth', async t => { - const fix = t.testdir({ - local: fixture, - global: globalFixture, - }) - - prefix = resolve(fix, 'local') - globalDir = resolve(fix, 'global/node_modules') - - _flatOptions.depth = 0 - - const res = await installedDeep(npm, null) + const res = await mockDeep(t, { depth: 0 }) t.same( res, [ @@ -229,23 +188,10 @@ t.test('limit depth', async t => { ], 'should print only packages up to the specified depth' ) - _flatOptions.depth = 0 - t.end() }) t.test('limit depth as global', async t => { - const fix = t.testdir({ - local: fixture, - global: globalFixture, - }) - - prefix = resolve(fix, 'local') - globalDir = resolve(fix, 'global/node_modules') - - _flatOptions.global = true - _flatOptions.depth = 0 - - const res = await installedDeep(npm, null) + const res = await mockDeep(t, { depth: 0, global: true }) t.same( res, [ @@ -256,7 +202,4 @@ t.test('limit depth as global', async t => { ], 'should reorder so that packages above that level depth goes last' ) - _flatOptions.global = false - _flatOptions.depth = 0 - t.end() }) diff --git a/deps/npm/test/lib/utils/completion/installed-shallow.js b/deps/npm/test/lib/utils/completion/installed-shallow.js index 5a65b6b6bfaef7..3666803979cb38 100644 --- a/deps/npm/test/lib/utils/completion/installed-shallow.js +++ b/deps/npm/test/lib/utils/completion/installed-shallow.js @@ -1,13 +1,10 @@ const t = require('tap') -const { resolve } = require('path') const installed = require('../../../../lib/utils/completion/installed-shallow.js') +const mockNpm = require('../../../fixtures/mock-npm') -const flatOptions = { global: false } -const npm = { flatOptions } - -t.test('global not set, include globals with -g', async t => { - const dir = t.testdir({ - global: { +const mockShallow = async (t, config) => { + const res = await mockNpm(t, { + globalPrefixDir: { node_modules: { x: {}, '@scope': { @@ -15,7 +12,7 @@ t.test('global not set, include globals with -g', async t => { }, }, }, - local: { + prefixDir: { node_modules: { a: {}, '@scope': { @@ -23,10 +20,13 @@ t.test('global not set, include globals with -g', async t => { }, }, }, + config: { global: false, ...config }, }) - npm.globalDir = resolve(dir, 'global/node_modules') - npm.localDir = resolve(dir, 'local/node_modules') - flatOptions.global = false + return res +} + +t.test('global not set, include globals with -g', async t => { + const { npm } = await mockShallow(t) const opt = { conf: { argv: { remain: [] } } } const res = await installed(npm, opt) t.strictSame(res.sort(), [ @@ -35,64 +35,21 @@ t.test('global not set, include globals with -g', async t => { 'a', '@scope/b', ].sort()) - t.end() }) t.test('global set, include globals and not locals', async t => { - const dir = t.testdir({ - global: { - node_modules: { - x: {}, - '@scope': { - y: {}, - }, - }, - }, - local: { - node_modules: { - a: {}, - '@scope': { - b: {}, - }, - }, - }, - }) - npm.globalDir = resolve(dir, 'global/node_modules') - npm.localDir = resolve(dir, 'local/node_modules') - flatOptions.global = true + const { npm } = await mockShallow(t, { global: true }) const opt = { conf: { argv: { remain: [] } } } const res = await installed(npm, opt) t.strictSame(res.sort(), [ '@scope/y', 'x', ].sort()) - t.end() }) t.test('more than 3 items in argv, skip it', async t => { - const dir = t.testdir({ - global: { - node_modules: { - x: {}, - '@scope': { - y: {}, - }, - }, - }, - local: { - node_modules: { - a: {}, - '@scope': { - b: {}, - }, - }, - }, - }) - npm.globalDir = resolve(dir, 'global/node_modules') - npm.localDir = resolve(dir, 'local/node_modules') - flatOptions.global = false + const { npm } = await mockShallow(t) const opt = { conf: { argv: { remain: [1, 2, 3, 4, 5, 6] } } } const res = await installed(npm, opt) t.strictSame(res, null) - t.end() }) diff --git a/deps/npm/test/lib/utils/config/definitions.js b/deps/npm/test/lib/utils/config/definitions.js index 288166039bf6fe..8775824c6c131c 100644 --- a/deps/npm/test/lib/utils/config/definitions.js +++ b/deps/npm/test/lib/utils/config/definitions.js @@ -1,6 +1,6 @@ const t = require('tap') const { resolve } = require('path') -const mockGlobals = require('../../../fixtures/mock-globals') +const mockGlobals = require('@npmcli/mock-globals') const tmock = require('../../../fixtures/tmock') const pkg = require('../../../../package.json') diff --git a/deps/npm/test/lib/utils/config/index.js b/deps/npm/test/lib/utils/config/index.js index 90931a96d7aa24..010ec34888da49 100644 --- a/deps/npm/test/lib/utils/config/index.js +++ b/deps/npm/test/lib/utils/config/index.js @@ -1,7 +1,7 @@ const t = require('tap') const config = require('../../../../lib/utils/config/index.js') const definitions = require('../../../../lib/utils/config/definitions.js') -const mockGlobals = require('../../../fixtures/mock-globals.js') +const mockGlobals = require('@npmcli/mock-globals') t.test('defaults', t => { // just spot check a few of these to show that we got defaults assembled diff --git a/deps/npm/test/lib/utils/did-you-mean.js b/deps/npm/test/lib/utils/did-you-mean.js index d3cb3a24f0ae5c..d111c2f0029605 100644 --- a/deps/npm/test/lib/utils/did-you-mean.js +++ b/deps/npm/test/lib/utils/did-you-mean.js @@ -1,9 +1,8 @@ const t = require('tap') -const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') const dym = require('../../../lib/utils/did-you-mean.js') + t.test('did-you-mean', async t => { - const { npm } = await loadMockNpm(t) t.test('with package.json', async t => { const testdir = t.testdir({ 'package.json': JSON.stringify({ @@ -17,27 +16,27 @@ t.test('did-you-mean', async t => { }), }) t.test('nistall', async t => { - const result = await dym(npm, testdir, 'nistall') + const result = await dym(testdir, 'nistall') t.match(result, 'npm install') }) t.test('sttest', async t => { - const result = await dym(npm, testdir, 'sttest') + const result = await dym(testdir, 'sttest') t.match(result, 'npm test') t.match(result, 'npm run posttest') }) t.test('npz', async t => { - const result = await dym(npm, testdir, 'npxx') + const result = await dym(testdir, 'npxx') t.match(result, 'npm exec npx') }) t.test('qwuijbo', async t => { - const result = await dym(npm, testdir, 'qwuijbo') + const result = await dym(testdir, 'qwuijbo') t.match(result, '') }) }) t.test('with no package.json', t => { const testdir = t.testdir({}) t.test('nistall', async t => { - const result = await dym(npm, testdir, 'nistall') + const result = await dym(testdir, 'nistall') t.match(result, 'npm install') }) t.end() @@ -49,7 +48,7 @@ t.test('did-you-mean', async t => { }), }) - const result = await dym(npm, testdir, 'nistall') + const result = await dym(testdir, 'nistall') t.match(result, 'npm install') }) }) diff --git a/deps/npm/test/lib/utils/display.js b/deps/npm/test/lib/utils/display.js index 7a99dcb679c09c..b8f047668bfe4c 100644 --- a/deps/npm/test/lib/utils/display.js +++ b/deps/npm/test/lib/utils/display.js @@ -1,7 +1,7 @@ const t = require('tap') const log = require('../../../lib/utils/log-shim') const mockLogs = require('../../fixtures/mock-logs') -const mockGlobals = require('../../fixtures/mock-globals') +const mockGlobals = require('@npmcli/mock-globals') const tmock = require('../../fixtures/tmock') const mockDisplay = (t, mocks) => { diff --git a/deps/npm/test/lib/utils/error-message.js b/deps/npm/test/lib/utils/error-message.js index 37b3bc6afeddc1..1ba5865592edba 100644 --- a/deps/npm/test/lib/utils/error-message.js +++ b/deps/npm/test/lib/utils/error-message.js @@ -2,7 +2,7 @@ const t = require('tap') const { resolve } = require('path') const fs = require('fs/promises') const { load: _loadMockNpm } = require('../../fixtures/mock-npm.js') -const mockGlobals = require('../../fixtures/mock-globals.js') +const mockGlobals = require('@npmcli/mock-globals') const tmock = require('../../fixtures/tmock') const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot.js') @@ -46,7 +46,9 @@ const loadMockNpm = async (t, { errorMocks, ...opts } = {}) => { t.test('just simple messages', async t => { const { errorMessage } = await loadMockNpm(t, { + prefixDir: { 'package-lock.json': '{}' }, command: 'audit', + exec: true, }) const codes = [ 'ENOAUDIT', diff --git a/deps/npm/test/lib/utils/exit-handler.js b/deps/npm/test/lib/utils/exit-handler.js index 8942d909225971..f553e1a2ea518d 100644 --- a/deps/npm/test/lib/utils/exit-handler.js +++ b/deps/npm/test/lib/utils/exit-handler.js @@ -6,7 +6,7 @@ const { join, resolve } = require('path') const EventEmitter = require('events') const { format } = require('../../../lib/utils/log-file') const { load: loadMockNpm } = require('../../fixtures/mock-npm') -const mockGlobals = require('../../fixtures/mock-globals') +const mockGlobals = require('@npmcli/mock-globals') const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot') const tmock = require('../../fixtures/tmock') @@ -40,7 +40,7 @@ t.cleanSnapshot = (path) => cleanDate(cleanCwd(path)) mockGlobals(t, { process: Object.assign(new EventEmitter(), { // these are process properties that are needed in the running code and tests - ...pick(process, 'execPath', 'stdout', 'stderr', 'cwd', 'chdir', 'env', 'umask'), + ...pick(process, 'execPath', 'stdout', 'stderr', 'stdin', 'cwd', 'chdir', 'env', 'umask'), argv: ['/node', ...process.argv.slice(1)], version: 'v1.0.0', kill: () => {}, @@ -53,13 +53,11 @@ mockGlobals(t, { }), }, { replace: true }) -const mockExitHandler = async (t, { init, load, testdir, config, mocks, files } = {}) => { +const mockExitHandler = async (t, { config, mocks, files, ...opts } = {}) => { const errors = [] const { npm, logMocks, ...rest } = await loadMockNpm(t, { - init, - load, - testdir, + ...opts, mocks: { '{ROOT}/package.json': { version: '1.0.0', @@ -592,13 +590,14 @@ t.test('exits uncleanly when only emitting exit event', async (t) => { t.match(logs.error, [['', 'Exit handler never called!']]) t.equal(process.exitCode, 1, 'exitCode coerced to 1') - t.end() }) t.test('do no fancy handling for shellouts', async t => { - const { exitHandler, npm, logs } = await mockExitHandler(t) - - await npm.cmd('exec') + const { exitHandler, logs } = await mockExitHandler(t, { + command: 'exec', + exec: true, + argv: ['-c', 'exit'], + }) const loudNoises = () => logs.filter(([level]) => ['warn', 'error'].includes(level)) @@ -614,7 +613,6 @@ t.test('do no fancy handling for shellouts', async t => { t.equal(process.exitCode, 1, 'got expected exit code') // should log some warnings and errors, because something weird happened t.strictNotSame(loudNoises(), [], 'bring the noise') - t.end() }) t.test('shellout with code=0 (extra weird?)', async t => { @@ -622,6 +620,4 @@ t.test('do no fancy handling for shellouts', async t => { t.equal(process.exitCode, 1, 'got expected exit code') t.strictNotSame(loudNoises(), [], 'bring the noise') }) - - t.end() }) diff --git a/deps/npm/test/lib/utils/explain-dep.js b/deps/npm/test/lib/utils/explain-dep.js index e5389fd26d7967..06174f36a7ffcc 100644 --- a/deps/npm/test/lib/utils/explain-dep.js +++ b/deps/npm/test/lib/utils/explain-dep.js @@ -1,269 +1,277 @@ const { resolve } = require('path') const t = require('tap') -const Chalk = require('chalk') const { explainNode, printNode } = require('../../../lib/utils/explain-dep.js') const { cleanCwd } = require('../../fixtures/clean-snapshot') -const testdir = t.testdirName -const color = new Chalk.Instance({ level: Chalk.level }) -const noColor = new Chalk.Instance({ level: 0 }) - t.cleanSnapshot = (str) => cleanCwd(str) -const cases = { - prodDep: { - name: 'prod-dep', - version: '1.2.3', - location: 'node_modules/prod-dep', - dependents: [ - { - type: 'prod', - name: 'prod-dep', - spec: '1.x', - from: { - location: '/path/to/project', +const getCases = (testdir) => { + const cases = { + prodDep: { + name: 'prod-dep', + version: '1.2.3', + location: 'node_modules/prod-dep', + dependents: [ + { + type: 'prod', + name: 'prod-dep', + spec: '1.x', + from: { + location: '/path/to/project', + }, }, - }, - ], - }, + ], + }, - deepDev: { - name: 'deep-dev', - version: '2.3.4', - location: 'node_modules/deep-dev', - dev: true, - dependents: [ - { - type: 'prod', - name: 'deep-dev', - spec: '2.x', - from: { - name: 'metadev', - version: '3.4.5', - location: 'node_modules/dev/node_modules/metadev', - dependents: [ - { - type: 'prod', - name: 'metadev', - spec: '3.x', - from: { - name: 'topdev', - version: '4.5.6', - location: 'node_modules/topdev', - dependents: [ - { - type: 'dev', - name: 'topdev', - spec: '4.x', - from: { - location: '/path/to/project', + deepDev: { + name: 'deep-dev', + version: '2.3.4', + location: 'node_modules/deep-dev', + dev: true, + dependents: [ + { + type: 'prod', + name: 'deep-dev', + spec: '2.x', + from: { + name: 'metadev', + version: '3.4.5', + location: 'node_modules/dev/node_modules/metadev', + dependents: [ + { + type: 'prod', + name: 'metadev', + spec: '3.x', + from: { + name: 'topdev', + version: '4.5.6', + location: 'node_modules/topdev', + dependents: [ + { + type: 'dev', + name: 'topdev', + spec: '4.x', + from: { + location: '/path/to/project', + }, }, - }, - ], + ], + }, }, - }, - ], + ], + }, }, - }, - ], - }, + ], + }, - optional: { - name: 'optdep', - version: '1.0.0', - location: 'node_modules/optdep', - optional: true, - dependents: [ - { - type: 'optional', - name: 'optdep', + optional: { + name: 'optdep', + version: '1.0.0', + location: 'node_modules/optdep', + optional: true, + dependents: [ + { + type: 'optional', + name: 'optdep', + spec: '1.0.0', + from: { + location: '/path/to/project', + }, + }, + ], + }, + + peer: { + name: 'peer', + version: '1.0.0', + location: 'node_modules/peer', + peer: true, + dependents: [ + { + type: 'peer', + name: 'peer', + spec: '1.0.0', + from: { + location: '/path/to/project', + }, + }, + ], + }, + + bundled: { + name: 'bundle-of-joy', + version: '1.0.0', + location: 'node_modules/bundle-of-joy', + bundled: true, + dependents: [ + { + type: 'prod', + name: 'prod-dep', + spec: '1.x', + bundled: true, + from: { + location: '/path/to/project', + }, + }, + ], + }, + + extraneous: { + name: 'extra-neos', + version: '1337.420.69-lol', + location: 'node_modules/extra-neos', + dependents: [], + extraneous: true, + }, + + overridden: { + name: 'overridden-root', + version: '1.0.0', + location: 'node_modules/overridden-root', + overridden: true, + dependents: [{ + type: 'prod', + name: 'overridden-dep', spec: '1.0.0', + rawSpec: '^2.0.0', + overridden: true, from: { location: '/path/to/project', }, - }, - ], - }, + }], + }, + } - peer: { - name: 'peer', + cases.manyDeps = { + name: 'manydep', version: '1.0.0', - location: 'node_modules/peer', - peer: true, dependents: [ { - type: 'peer', - name: 'peer', + type: 'prod', + name: 'manydep', spec: '1.0.0', + from: cases.prodDep, + }, + { + type: 'optional', + name: 'manydep', + spec: '1.x', + from: cases.optional, + }, + { + type: 'prod', + name: 'manydep', + spec: '1.0.x', + from: cases.extraneous, + }, + { + type: 'dev', + name: 'manydep', + spec: '*', + from: cases.deepDev, + }, + { + type: 'peer', + name: 'manydep', + spec: '>1.0.0-beta <1.0.1', + from: cases.peer, + }, + { + type: 'prod', + name: 'manydep', + spec: '>1.0.0-beta <1.0.1', from: { location: '/path/to/project', }, }, - ], - }, - - bundled: { - name: 'bundle-of-joy', - version: '1.0.0', - location: 'node_modules/bundle-of-joy', - bundled: true, - dependents: [ { type: 'prod', - name: 'prod-dep', - spec: '1.x', - bundled: true, + name: 'manydep', + spec: '1', from: { - location: '/path/to/project', + name: 'a package with a pretty long name', + version: '1.2.3', + dependents: { + location: '/path/to/project', + }, }, }, - ], - }, - - extraneous: { - name: 'extra-neos', - version: '1337.420.69-lol', - location: 'node_modules/extra-neos', - dependents: [], - extraneous: true, - }, - - overridden: { - name: 'overridden-root', - version: '1.0.0', - location: 'node_modules/overridden-root', - overridden: true, - dependents: [{ - type: 'prod', - name: 'overridden-dep', - spec: '1.0.0', - rawSpec: '^2.0.0', - overridden: true, - from: { - location: '/path/to/project', - }, - }], - }, -} - -cases.manyDeps = { - name: 'manydep', - version: '1.0.0', - dependents: [ - { - type: 'prod', - name: 'manydep', - spec: '1.0.0', - from: cases.prodDep, - }, - { - type: 'optional', - name: 'manydep', - spec: '1.x', - from: cases.optional, - }, - { - type: 'prod', - name: 'manydep', - spec: '1.0.x', - from: cases.extraneous, - }, - { - type: 'dev', - name: 'manydep', - spec: '*', - from: cases.deepDev, - }, - { - type: 'peer', - name: 'manydep', - spec: '>1.0.0-beta <1.0.1', - from: cases.peer, - }, - { - type: 'prod', - name: 'manydep', - spec: '>1.0.0-beta <1.0.1', - from: { - location: '/path/to/project', - }, - }, - { - type: 'prod', - name: 'manydep', - spec: '1', - from: { - name: 'a package with a pretty long name', - version: '1.2.3', - dependents: { - location: '/path/to/project', + { + type: 'prod', + name: 'manydep', + spec: '1', + from: { + name: 'another package with a pretty long name', + version: '1.2.3', + dependents: { + location: '/path/to/project', + }, }, }, - }, - { - type: 'prod', - name: 'manydep', - spec: '1', - from: { - name: 'another package with a pretty long name', - version: '1.2.3', - dependents: { - location: '/path/to/project', + { + type: 'prod', + name: 'manydep', + spec: '1', + from: { + name: 'yet another a package with a pretty long name', + version: '1.2.3', + dependents: { + location: '/path/to/project', + }, }, }, - }, - { - type: 'prod', - name: 'manydep', - spec: '1', - from: { - name: 'yet another a package with a pretty long name', - version: '1.2.3', - dependents: { - location: '/path/to/project', - }, + ], + } + + cases.workspaces = { + name: 'a', + version: '1.0.0', + location: 'a', + isWorkspace: true, + dependents: [], + linksIn: [ + { + name: 'a', + version: '1.0.0', + location: 'node_modules/a', + isWorkspace: true, + dependents: [ + { + type: 'workspace', + name: 'a', + spec: `file:${resolve(testdir, 'ws-project', 'a')}`, + from: { location: resolve(testdir, 'ws-project') }, + }, + ], }, - }, - ], -} + ], + } -cases.workspaces = { - name: 'a', - version: '1.0.0', - location: 'a', - isWorkspace: true, - dependents: [], - linksIn: [ - { - name: 'a', - version: '1.0.0', - location: 'node_modules/a', - isWorkspace: true, - dependents: [ - { - type: 'workspace', - name: 'a', - spec: `file:${resolve(testdir, 'ws-project', 'a')}`, - from: { location: resolve(testdir, 'ws-project') }, - }, - ], - }, - ], + return cases } -for (const [name, expl] of Object.entries(cases)) { - t.test(name, t => { - t.matchSnapshot(printNode(expl, color), 'print color') - t.matchSnapshot(printNode(expl, noColor), 'print nocolor') - t.matchSnapshot(explainNode(expl, Infinity, color), 'explain color deep') - t.matchSnapshot(explainNode(expl, 2, noColor), 'explain nocolor shallow') - t.end() - }) -} +t.test('basic', async t => { + const { Chalk } = await import('chalk') + const color = new Chalk({ level: 3 }) + const noColor = new Chalk({ level: 0 }) + + const testdir = t.testdir() + const cases = getCases(testdir) + + for (const [name, expl] of Object.entries(getCases(testdir))) { + t.test(name, t => { + t.matchSnapshot(printNode(expl, color), 'print color') + t.matchSnapshot(printNode(expl, noColor), 'print nocolor') + t.matchSnapshot(explainNode(expl, Infinity, color), 'explain color deep') + t.matchSnapshot(explainNode(expl, 2, noColor), 'explain nocolor shallow') + t.end() + }) + } -// make sure that we show the last one if it's the only one that would -// hit the ... -cases.manyDeps.dependents.pop() -t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test one') -cases.manyDeps.dependents.pop() -t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test two') + // make sure that we show the last one if it's the only one that would + // hit the ... + cases.manyDeps.dependents.pop() + t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test one') + cases.manyDeps.dependents.pop() + t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test two') +}) diff --git a/deps/npm/test/lib/utils/explain-eresolve.js b/deps/npm/test/lib/utils/explain-eresolve.js index 0f60556ef2ac98..157cc97a5a3cb6 100644 --- a/deps/npm/test/lib/utils/explain-eresolve.js +++ b/deps/npm/test/lib/utils/explain-eresolve.js @@ -1,29 +1,31 @@ const t = require('tap') -const Chalk = require('chalk') const { explain, report } = require('../../../lib/utils/explain-eresolve.js') const cases = require('../../fixtures/eresolve-explanations.js') -const color = new Chalk.Instance({ level: Chalk.level }) -const noColor = new Chalk.Instance({ level: 0 }) +t.test('basic', async t => { + const { Chalk } = await import('chalk') + const color = new Chalk({ level: 3 }) + const noColor = new Chalk({ level: 0 }) -for (const [name, expl] of Object.entries(cases)) { + for (const [name, expl] of Object.entries(cases)) { // no sense storing the whole contents of each object in the snapshot // we can trust that JSON.stringify still works just fine. - expl.toJSON = () => ({ name, json: true }) + expl.toJSON = () => ({ name, json: true }) - t.test(name, t => { - const colorReport = report(expl, color, noColor) - t.matchSnapshot(colorReport.explanation, 'report with color') - t.matchSnapshot(colorReport.file, 'report from color') + t.test(name, t => { + const colorReport = report(expl, color, noColor) + t.matchSnapshot(colorReport.explanation, 'report with color') + t.matchSnapshot(colorReport.file, 'report from color') - const noColorReport = report(expl, noColor, noColor) - t.matchSnapshot(noColorReport.explanation, 'report with no color') - t.equal(noColorReport.file, colorReport.file, 'same report written for object') + const noColorReport = report(expl, noColor, noColor) + t.matchSnapshot(noColorReport.explanation, 'report with no color') + t.equal(noColorReport.file, colorReport.file, 'same report written for object') - t.matchSnapshot(explain(expl, color, 2), 'explain with color, depth of 2') - t.matchSnapshot(explain(expl, noColor, 6), 'explain with no color, depth of 6') + t.matchSnapshot(explain(expl, color, 2), 'explain with color, depth of 2') + t.matchSnapshot(explain(expl, noColor, 6), 'explain with no color, depth of 6') - t.end() - }) -} + t.end() + }) + } +}) diff --git a/deps/npm/test/lib/utils/open-url-prompt.js b/deps/npm/test/lib/utils/open-url-prompt.js index faf2ab32587af1..c889313e162c7f 100644 --- a/deps/npm/test/lib/utils/open-url-prompt.js +++ b/deps/npm/test/lib/utils/open-url-prompt.js @@ -1,138 +1,120 @@ const t = require('tap') -const mockGlobals = require('../../fixtures/mock-globals.js') const EventEmitter = require('events') const tmock = require('../../fixtures/tmock') - -const OUTPUT = [] -const output = (...args) => OUTPUT.push(args) -const npm = { - _config: { - json: false, - browser: true, - }, - config: { - get: k => npm._config[k], - set: (k, v) => { - npm._config[k] = v +const mockNpm = require('../../fixtures/mock-npm') + +const mockOpenUrlPrompt = async (t, { + questionShouldResolve = true, + openUrlPromptInterrupted = false, + openerResult = null, + isTTY = true, + emitter = null, + url: openUrl = 'https://www.npmjs.com', + ...config +}) => { + const mock = await mockNpm(t, { + globals: { + 'process.stdin.isTTY': isTTY, + 'process.stdout.isTTY': isTTY, }, - }, - output, -} - -let openerUrl = null -let openerOpts = null -let openerResult = null - -let questionShouldResolve = true -let openUrlPromptInterrupted = false + config, + }) -const readline = { - createInterface: () => ({ - question: (_q, cb) => { - if (questionShouldResolve === true) { - cb() - } + let openerUrl = null + let openerOpts = null + + const openUrlPrompt = tmock(t, '{LIB}/utils/open-url-prompt.js', { + '@npmcli/promise-spawn': { + open: async (url, options) => { + openerUrl = url + openerOpts = options + if (openerResult) { + throw openerResult + } + }, }, - close: () => {}, - on: (_signal, cb) => { - if (openUrlPromptInterrupted && _signal === 'SIGINT') { - cb() - } + readline: { + createInterface: () => ({ + question: (_q, cb) => { + if (questionShouldResolve === true) { + cb() + } + }, + close: () => {}, + on: (_signal, cb) => { + if (openUrlPromptInterrupted && _signal === 'SIGINT') { + cb() + } + }, + }), }, - }), -} + }) -const openUrlPrompt = tmock(t, '{LIB}/utils/open-url-prompt.js', { - '@npmcli/promise-spawn': { - open: async (url, options) => { - openerUrl = url - openerOpts = options - if (openerResult) { - throw openerResult - } - }, - }, - readline, -}) + let error + const args = [mock.npm, openUrl, 'npm home', 'prompt'] + if (emitter) { + mock.open = openUrlPrompt(...args, emitter) + } else { + await openUrlPrompt(...args).catch((er) => error = er) + } -mockGlobals(t, { - 'process.stdin.isTTY': true, - 'process.stdout.isTTY': true, -}) + return { + ...mock, + openerUrl, + openerOpts, + OUTPUT: mock.joinedOutput(), + emitter, + error, + } +} t.test('does not open a url in non-interactive environments', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - }) - - mockGlobals(t, { - 'process.stdin.isTTY': false, - 'process.stdout.isTTY': false, - }) + const { openerUrl, openerOpts } = await mockOpenUrlPrompt(t, { isTTY: false }) - await openUrlPrompt(npm, 'https://www.npmjs.com', 'npm home', 'prompt') t.equal(openerUrl, null, 'did not open') t.same(openerOpts, null, 'did not open') }) t.test('opens a url', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - npm._config.browser = true - }) + const { OUTPUT, openerUrl, openerOpts } = await mockOpenUrlPrompt(t, { browser: true }) - npm._config.browser = 'browser' - await openUrlPrompt(npm, 'https://www.npmjs.com', 'npm home', 'prompt') t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') - t.same(openerOpts, { command: 'browser' }, 'passed command as null (the default)') + t.same(openerOpts, { command: null }, 'passed command as null (the default)') t.matchSnapshot(OUTPUT) }) +t.test('opens a url with browser string', async t => { + const { openerUrl, openerOpts } = await mockOpenUrlPrompt(t, { browser: 'firefox' }) + + t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') + // FIXME: browser string is parsed as a boolean in config layer + // this is a bug that should be fixed or the config should not allow it + t.same(openerOpts, { command: null }, 'passed command as null (the default)') +}) + t.test('prints json output', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - npm._config.json = false - }) + const { OUTPUT } = await mockOpenUrlPrompt(t, { json: true }) - npm._config.json = true - await openUrlPrompt(npm, 'https://www.npmjs.com', 'npm home', 'prompt') t.matchSnapshot(OUTPUT) }) t.test('returns error for non-https url', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 + const { error, OUTPUT, openerUrl, openerOpts } = await mockOpenUrlPrompt(t, { + url: 'ftp://www.npmjs.com', }) - await t.rejects( - openUrlPrompt(npm, 'ftp://www.npmjs.com', 'npm home', 'prompt'), - /Invalid URL/, - 'got the correct error' - ) + + t.match(error, /Invalid URL/, 'got the correct error') t.equal(openerUrl, null, 'did not open') t.same(openerOpts, null, 'did not open') - t.same(OUTPUT, [], 'printed no output') + t.same(OUTPUT, '', 'printed no output') }) t.test('does not open url if canceled', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - questionShouldResolve = true - }) - - questionShouldResolve = false const emitter = new EventEmitter() - - const open = openUrlPrompt(npm, 'https://www.npmjs.com', 'npm home', 'prompt', emitter) + const { openerUrl, openerOpts, open } = await mockOpenUrlPrompt(t, { + questionShouldResolve: false, + emitter, + }) emitter.emit('abort') @@ -143,41 +125,21 @@ t.test('does not open url if canceled', async t => { }) t.test('returns error when opener errors', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - openerResult = null - OUTPUT.length = 0 + const { error, openerUrl } = await mockOpenUrlPrompt(t, { + openerResult: new Error('Opener failed'), }) - openerResult = new Error('Opener failed') - - await t.rejects( - openUrlPrompt(npm, 'https://www.npmjs.com', 'npm home', 'prompt'), - /Opener failed/, - 'got the correct error' - ) + t.match(error, /Opener failed/, 'got the correct error') t.equal(openerUrl, 'https://www.npmjs.com', 'did not open') }) t.test('throws "canceled" error on SIGINT', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - questionShouldResolve = true - openUrlPromptInterrupted = false - }) - - questionShouldResolve = false - openUrlPromptInterrupted = true const emitter = new EventEmitter() + const { open } = await mockOpenUrlPrompt(t, { + questionShouldResolve: false, + openUrlPromptInterrupted: true, + emitter, + }) - const open = openUrlPrompt(npm, 'https://www.npmjs.com', 'npm home', 'prompt', emitter) - - try { - await open - } catch (err) { - t.equal(err.message, 'canceled') - } + await t.rejects(open, /canceled/, 'message is canceled') }) diff --git a/deps/npm/test/lib/utils/open-url.js b/deps/npm/test/lib/utils/open-url.js index 28a11b3609c674..0ce1b57aa5f9f7 100644 --- a/deps/npm/test/lib/utils/open-url.js +++ b/deps/npm/test/lib/utils/open-url.js @@ -1,197 +1,143 @@ const t = require('tap') const tmock = require('../../fixtures/tmock') +const mockNpm = require('../../fixtures/mock-npm') -const OUTPUT = [] -const output = (...args) => OUTPUT.push(args) -const npm = { - _config: { - json: false, - browser: true, - }, - config: { - get: k => npm._config[k], - set: (k, v) => { - npm._config[k] = v - }, - }, - output, -} +const mockOpenUrl = async (t, args, { openerResult, ...config } = {}) => { + let openerUrl = null + let openerOpts = null + + const open = async (url, options) => { + openerUrl = url + openerOpts = options + if (openerResult) { + throw openerResult + } + } + + const mock = await mockNpm(t, { config }) + + const openUrl = tmock(t, '{LIB}/utils/open-url.js', { + '@npmcli/promise-spawn': { open }, + }) -let openerUrl = null -let openerOpts = null -let openerResult = null + const openWithNpm = (...a) => openUrl(mock.npm, ...a) -const open = async (url, options) => { - openerUrl = url - openerOpts = options - if (openerResult) { - throw openerResult + if (args) { + await openWithNpm(...args) } -} -const openUrl = tmock(t, '{LIB}/utils/open-url.js', { - '@npmcli/promise-spawn': { - open, - }, -}) + return { + ...mock, + openUrl: openWithNpm, + openerUrl: () => openerUrl, + openerOpts: () => openerOpts, + } +} t.test('opens a url', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - }) - await openUrl(npm, 'https://www.npmjs.com', 'npm home') - t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') - t.same(openerOpts, { command: null }, 'passed command as null (the default)') - t.same(OUTPUT, [], 'printed no output') + const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, + ['https://www.npmjs.com', 'npm home']) + t.equal(openerUrl(), 'https://www.npmjs.com', 'opened the given url') + t.same(openerOpts(), { command: null }, 'passed command as null (the default)') + t.same(joinedOutput(), '', 'printed no output') }) t.test('returns error for non-https url', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - }) + const { openUrl, openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t) await t.rejects( - openUrl(npm, 'ftp://www.npmjs.com', 'npm home'), + openUrl('ftp://www.npmjs.com', 'npm home'), /Invalid URL/, 'got the correct error' ) - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.same(OUTPUT, [], 'printed no output') + t.equal(openerUrl(), null, 'did not open') + t.same(openerOpts(), null, 'did not open') + t.same(joinedOutput(), '', 'printed no output') }) t.test('returns error for file url', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - }) + const { openUrl, openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t) await t.rejects( - openUrl(npm, 'file:///usr/local/bin/ls', 'npm home'), + openUrl('file:///usr/local/bin/ls', 'npm home'), /Invalid URL/, 'got the correct error' ) - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.same(OUTPUT, [], 'printed no output') + t.equal(openerUrl(), null, 'did not open') + t.same(openerOpts(), null, 'did not open') + t.same(joinedOutput(), '', 'printed no output') }) t.test('file url allowed if explicitly asked for', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - }) - await openUrl(npm, 'file:///man/page/npm-install', 'npm home', true) - t.equal(openerUrl, 'file:///man/page/npm-install', 'opened the given url') - t.same(openerOpts, { command: null }, 'passed command as null (the default)') - t.same(OUTPUT, [], 'printed no output') + const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, + ['file:///man/page/npm-install', 'npm home', true]) + t.equal(openerUrl(), 'file:///man/page/npm-install', 'opened the given url') + t.same(openerOpts(), { command: null }, 'passed command as null (the default)') + t.same(joinedOutput(), '', 'printed no output') }) t.test('returns error for non-parseable url', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - }) + const { openUrl, openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t) await t.rejects( - openUrl(npm, 'git+ssh://user@host:repo.git', 'npm home'), + openUrl('git+ssh://user@host:repo.git', 'npm home'), /Invalid URL/, 'got the correct error' ) - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.same(OUTPUT, [], 'printed no output') + t.equal(openerUrl(), null, 'did not open') + t.same(openerOpts(), null, 'did not open') + t.same(joinedOutput(), '', 'printed no output') }) t.test('encodes non-URL-safe characters in url provided', async t => { - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - }) - await openUrl(npm, 'https://www.npmjs.com/|cat', 'npm home') - t.equal(openerUrl, 'https://www.npmjs.com/%7Ccat', 'opened the encoded url') - t.same(openerOpts, { command: null }, 'passed command as null (the default)') - t.same(OUTPUT, [], 'printed no output') + const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, + ['https://www.npmjs.com/|cat', 'npm home']) + t.equal(openerUrl(), 'https://www.npmjs.com/%7Ccat', 'opened the encoded url') + t.same(openerOpts(), { command: null }, 'passed command as null (the default)') + t.same(joinedOutput(), '', 'printed no output') }) t.test('opens a url with the given browser', async t => { - npm.config.set('browser', 'chrome') - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - npm.config.set('browser', true) - }) - await openUrl(npm, 'https://www.npmjs.com', 'npm home') - t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') - t.same(openerOpts, { command: 'chrome' }, 'passed the given browser as command') - t.same(OUTPUT, [], 'printed no output') + const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, + ['https://www.npmjs.com', 'npm home'], { browser: 'chrome' }) + t.equal(openerUrl(), 'https://www.npmjs.com', 'opened the given url') + // FIXME: browser string is parsed as a boolean in config layer + // this is a bug that should be fixed or the config should not allow it + t.same(openerOpts(), { command: null }, 'passed the given browser as command') + t.same(joinedOutput(), '', 'printed no output') }) t.test('prints where to go when browser is disabled', async t => { - npm.config.set('browser', false) - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - npm.config.set('browser', true) - }) - await openUrl(npm, 'https://www.npmjs.com', 'npm home') - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.equal(OUTPUT.length, 1, 'got one logged message') - t.equal(OUTPUT[0].length, 1, 'logged message had one value') - t.matchSnapshot(OUTPUT[0][0], 'printed expected message') + const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, + ['https://www.npmjs.com', 'npm home'], { browser: false }) + t.equal(openerUrl(), null, 'did not open') + t.same(openerOpts(), null, 'did not open') + t.matchSnapshot(joinedOutput(), 'printed expected message') }) t.test('prints where to go when browser is disabled and json is enabled', async t => { - npm.config.set('browser', false) - npm.config.set('json', true) - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - npm.config.set('browser', true) - npm.config.set('json', false) - }) - await openUrl(npm, 'https://www.npmjs.com', 'npm home') - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.equal(OUTPUT.length, 1, 'got one logged message') - t.equal(OUTPUT[0].length, 1, 'logged message had one value') - t.matchSnapshot(OUTPUT[0][0], 'printed expected message') + const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, + ['https://www.npmjs.com', 'npm home'], { browser: false, json: true }) + t.equal(openerUrl(), null, 'did not open') + t.same(openerOpts(), null, 'did not open') + t.matchSnapshot(joinedOutput(), 'printed expected message') }) t.test('prints where to go when given browser does not exist', async t => { - npm.config.set('browser', 'firefox') - openerResult = Object.assign(new Error('failed'), { code: 'ENOENT' }) - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - npm.config.set('browser', true) - }) - await openUrl(npm, 'https://www.npmjs.com', 'npm home') - t.equal(openerUrl, 'https://www.npmjs.com', 'tried to open the correct url') - t.same(openerOpts, { command: 'firefox' }, 'tried to use the correct browser') - t.equal(OUTPUT.length, 1, 'got one logged message') - t.equal(OUTPUT[0].length, 1, 'logged message had one value') - t.matchSnapshot(OUTPUT[0][0], 'printed expected message') + const { openerUrl, openerOpts, joinedOutput } = await mockOpenUrl(t, + ['https://www.npmjs.com', 'npm home'], + { + openerResult: Object.assign(new Error('failed'), { code: 'ENOENT' }), + } + ) + + t.equal(openerUrl(), 'https://www.npmjs.com', 'tried to open the correct url') + t.same(openerOpts(), { command: null }, 'tried to use the correct browser') + t.matchSnapshot(joinedOutput(), 'printed expected message') }) t.test('handles unknown opener error', async t => { - npm.config.set('browser', 'firefox') - openerResult = Object.assign(new Error('failed'), { code: 'ENOBRIAN' }) - t.teardown(() => { - openerUrl = null - openerOpts = null - OUTPUT.length = 0 - npm.config.set('browser', true) + const { openUrl } = await mockOpenUrl(t, null, { + browser: 'firefox', + openerResult: Object.assign(new Error('failed'), { code: 'ENOBRIAN' }), }) - t.rejects(openUrl(npm, 'https://www.npmjs.com', 'npm home'), 'failed', 'got the correct error') + + await t.rejects(openUrl('https://www.npmjs.com', 'npm home'), 'failed', 'got the correct error') }) diff --git a/deps/npm/test/lib/utils/reify-finish.js b/deps/npm/test/lib/utils/reify-finish.js index ee112203a24bc8..a2ca6e43679627 100644 --- a/deps/npm/test/lib/utils/reify-finish.js +++ b/deps/npm/test/lib/utils/reify-finish.js @@ -1,81 +1,95 @@ const t = require('tap') +const fs = require('fs/promises') +const { join } = require('path') const { cleanNewlines } = require('../../fixtures/clean-snapshot') const tmock = require('../../fixtures/tmock') +const mockNpm = require('../../fixtures/mock-npm') -const npm = { - config: { - data: { - get: () => builtinConfMock, - }, - }, +// windowwwwwwssss!!!!! +const readRc = async (dir) => { + const res = await fs.readFile(join(dir, 'npmrc'), 'utf8').catch(() => '') + return cleanNewlines(res).trim() } -const builtinConfMock = { - loadError: new Error('no builtin config'), - raw: { hasBuiltinConfig: true, x: 'y', nested: { foo: 'bar' } }, -} +const mockReififyFinish = async (t, { actualTree = {}, otherDirs = {}, ...config }) => { + const mock = await mockNpm(t, { + npm: ({ other }) => ({ + npmRoot: other, + }), + otherDirs: { + npmrc: `key=value`, + ...otherDirs, + }, + config, + }) -const reifyOutput = () => {} + const reifyFinish = tmock(t, '{LIB}/utils/reify-finish.js', { + '{LIB}/utils/reify-output.js': () => {}, + }) -let expectWrite = false -const realFs = require('fs') -const fs = { - ...realFs, - promises: realFs.promises && { - ...realFs.promises, - writeFile: async (path, data) => { - if (!expectWrite) { - throw new Error('did not expect to write builtin config file') - } - return realFs.promises.writeFile(path, data) - }, - }, -} + await reifyFinish(mock.npm, { + options: { global: mock.npm.global }, + actualTree: typeof actualTree === 'function' ? actualTree(mock) : actualTree, + }) -const reifyFinish = tmock(t, '{LIB}/utils/reify-finish.js', { - fs, - '{LIB}/utils/reify-output.js': reifyOutput, -}) + const builtinRc = { + raw: await readRc(mock.other), + data: Object.fromEntries(Object.entries(mock.npm.config.data.get('builtin').data)), + } + + return { + builtinRc, + ...mock, + } +} -t.test('should not write if not global', async t => { - expectWrite = false - await reifyFinish(npm, { - options: { global: false }, - actualTree: {}, +t.test('ok by default', async t => { + const mock = await mockReififyFinish(t, { + global: false, }) + t.same(mock.builtinRc.raw, 'key=value') + t.strictSame(mock.builtinRc.data, { key: 'value' }) }) t.test('should not write if no global npm module', async t => { - expectWrite = false - await reifyFinish(npm, { - options: { global: true }, + const mock = await mockReififyFinish(t, { + global: true, actualTree: { inventory: new Map(), }, }) + t.same(mock.builtinRc.raw, 'key=value') + t.strictSame(mock.builtinRc.data, { key: 'value' }) }) t.test('should not write if builtin conf had load error', async t => { - expectWrite = false - await reifyFinish(npm, { - options: { global: true }, + const mock = await mockReififyFinish(t, { + global: true, + otherDirs: { + npmrc: {}, + }, actualTree: { inventory: new Map([['node_modules/npm', {}]]), }, }) + t.same(mock.builtinRc.raw, '') + t.strictSame(mock.builtinRc.data, {}) }) t.test('should write if everything above passes', async t => { - expectWrite = true - delete builtinConfMock.loadError - const path = t.testdir() - await reifyFinish(npm, { - options: { global: true }, - actualTree: { - inventory: new Map([['node_modules/npm', { path }]]), + const mock = await mockReififyFinish(t, { + global: true, + otherDirs: { + 'new-npm': {}, }, + actualTree: ({ other }) => ({ + inventory: new Map([['node_modules/npm', { path: join(other, 'new-npm') }]]), + }), }) - // windowwwwwwssss!!!!! - const data = cleanNewlines(fs.readFileSync(`${path}/npmrc`, 'utf8')) - t.matchSnapshot(data, 'written config') + + t.same(mock.builtinRc.raw, 'key=value') + t.strictSame(mock.builtinRc.data, { key: 'value' }) + + const newFile = await readRc(join(mock.other, 'new-npm')) + t.equal(mock.builtinRc.raw, newFile) }) diff --git a/deps/npm/test/lib/utils/reify-output.js b/deps/npm/test/lib/utils/reify-output.js index 5d1d5be47efa30..1c6215ab33bef0 100644 --- a/deps/npm/test/lib/utils/reify-output.js +++ b/deps/npm/test/lib/utils/reify-output.js @@ -8,6 +8,7 @@ const mockReify = async (t, reify, { command, ...config } = {}) => { const mock = await mockNpm(t, { command, config, + setCmd: true, }) reifyOutput(mock.npm, reify) diff --git a/deps/npm/test/lib/utils/update-notifier.js b/deps/npm/test/lib/utils/update-notifier.js index 9c12433a2d1177..cc5348a440e0a7 100644 --- a/deps/npm/test/lib/utils/update-notifier.js +++ b/deps/npm/test/lib/utils/update-notifier.js @@ -19,7 +19,8 @@ const runUpdateNotifier = async (t, { PACOTE_ERROR, STAT_MTIME = 0, mocks: _mocks = {}, - command = 'view', + command = 'help', + prefixDir, version = CURRENT_VERSION, argv = [], ...config @@ -76,6 +77,8 @@ const runUpdateNotifier = async (t, { command, mocks, config, + exec: true, + prefixDir, argv, }) const updateNotifier = tmock(t, '{LIB}/utils/update-notifier.js', mocks) @@ -106,6 +109,7 @@ t.test('situations in which we do not notify', t => { t.test('do not suggest update if already updating', async t => { const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { command: 'install', + prefixDir: { 'package.json': `{"name":"${t.testName}"}` }, argv: ['npm'], global: true, }) @@ -116,6 +120,7 @@ t.test('situations in which we do not notify', t => { t.test('do not suggest update if already updating with spec', async t => { const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { command: 'install', + prefixDir: { 'package.json': `{"name":"${t.testName}"}` }, argv: ['npm@latest'], global: true, })