From 131240c2f3096c2913f0ed6d40b8c1a447ebe316 Mon Sep 17 00:00:00 2001 From: npm CLI robot Date: Wed, 7 Jun 2023 15:49:11 +0000 Subject: [PATCH] deps: upgrade npm to 9.7.1 --- deps/npm/docs/content/commands/npm-access.md | 6 + deps/npm/docs/content/commands/npm-adduser.md | 5 + deps/npm/docs/content/commands/npm-audit.md | 18 + deps/npm/docs/content/commands/npm-bugs.md | 4 + deps/npm/docs/content/commands/npm-cache.md | 2 + deps/npm/docs/content/commands/npm-ci.md | 30 +- deps/npm/docs/content/commands/npm-config.md | 10 + deps/npm/docs/content/commands/npm-dedupe.md | 24 +- .../docs/content/commands/npm-deprecate.md | 4 + deps/npm/docs/content/commands/npm-diff.md | 20 + deps/npm/docs/content/commands/npm-docs.md | 4 + deps/npm/docs/content/commands/npm-doctor.md | 2 + deps/npm/docs/content/commands/npm-edit.md | 2 + deps/npm/docs/content/commands/npm-exec.md | 3 + deps/npm/docs/content/commands/npm-explain.md | 2 + deps/npm/docs/content/commands/npm-explore.md | 2 + .../docs/content/commands/npm-find-dupes.md | 22 +- deps/npm/docs/content/commands/npm-fund.md | 8 + .../docs/content/commands/npm-help-search.md | 2 + deps/npm/docs/content/commands/npm-help.md | 2 + deps/npm/docs/content/commands/npm-hook.md | 4 + deps/npm/docs/content/commands/npm-init.md | 7 + .../content/commands/npm-install-ci-test.md | 30 +- .../docs/content/commands/npm-install-test.md | 42 +- deps/npm/docs/content/commands/npm-install.md | 42 +- deps/npm/docs/content/commands/npm-link.md | 30 +- deps/npm/docs/content/commands/npm-login.md | 5 + deps/npm/docs/content/commands/npm-logout.md | 3 + deps/npm/docs/content/commands/npm-ls.md | 24 +- deps/npm/docs/content/commands/npm-org.md | 8 + .../npm/docs/content/commands/npm-outdated.md | 10 + deps/npm/docs/content/commands/npm-owner.md | 4 + deps/npm/docs/content/commands/npm-pack.md | 6 + deps/npm/docs/content/commands/npm-ping.md | 2 + deps/npm/docs/content/commands/npm-pkg.md | 4 + deps/npm/docs/content/commands/npm-prefix.md | 2 + deps/npm/docs/content/commands/npm-profile.md | 8 + deps/npm/docs/content/commands/npm-prune.md | 12 + deps/npm/docs/content/commands/npm-publish.md | 19 + deps/npm/docs/content/commands/npm-query.md | 2 + deps/npm/docs/content/commands/npm-rebuild.md | 10 + deps/npm/docs/content/commands/npm-repo.md | 4 + deps/npm/docs/content/commands/npm-restart.md | 4 + deps/npm/docs/content/commands/npm-root.md | 2 + .../docs/content/commands/npm-run-script.md | 6 + deps/npm/docs/content/commands/npm-search.md | 22 + deps/npm/docs/content/commands/npm-star.md | 6 + deps/npm/docs/content/commands/npm-stars.md | 2 + deps/npm/docs/content/commands/npm-start.md | 4 + deps/npm/docs/content/commands/npm-stop.md | 4 + deps/npm/docs/content/commands/npm-team.md | 8 + deps/npm/docs/content/commands/npm-test.md | 4 + deps/npm/docs/content/commands/npm-token.md | 8 + .../docs/content/commands/npm-uninstall.md | 20 + .../docs/content/commands/npm-unpublish.md | 4 + deps/npm/docs/content/commands/npm-unstar.md | 6 + deps/npm/docs/content/commands/npm-update.md | 30 +- deps/npm/docs/content/commands/npm-version.md | 14 + deps/npm/docs/content/commands/npm-view.md | 2 + deps/npm/docs/content/commands/npm-whoami.md | 2 + deps/npm/docs/content/commands/npm.md | 2 +- deps/npm/docs/content/using-npm/config.md | 305 +++++++++++- deps/npm/docs/output/commands/npm-ci.html | 10 +- deps/npm/docs/output/commands/npm-dedupe.html | 1 - .../docs/output/commands/npm-find-dupes.html | 1 - .../output/commands/npm-install-ci-test.html | 10 +- .../output/commands/npm-install-test.html | 10 +- .../npm/docs/output/commands/npm-install.html | 10 +- deps/npm/docs/output/commands/npm-link.html | 1 - deps/npm/docs/output/commands/npm-ls.html | 2 +- .../npm/docs/output/commands/npm-publish.html | 10 +- .../docs/output/commands/npm-uninstall.html | 16 +- deps/npm/docs/output/commands/npm-update.html | 1 - deps/npm/docs/output/commands/npm.html | 2 +- deps/npm/docs/output/using-npm/config.html | 18 +- deps/npm/lib/base-command.js | 126 ++--- deps/npm/lib/cli-entry.js | 74 +++ deps/npm/lib/cli.js | 104 +--- deps/npm/lib/commands/access.js | 10 +- deps/npm/lib/commands/audit.js | 67 ++- deps/npm/lib/commands/cache.js | 2 +- deps/npm/lib/commands/ci.js | 1 - deps/npm/lib/commands/completion.js | 19 +- deps/npm/lib/commands/config.js | 14 +- deps/npm/lib/commands/deprecate.js | 6 +- deps/npm/lib/commands/diff.js | 8 +- deps/npm/lib/commands/dist-tag.js | 7 +- deps/npm/lib/commands/edit.js | 4 +- deps/npm/lib/commands/exec.js | 2 + deps/npm/lib/commands/explain.js | 4 +- deps/npm/lib/commands/explore.js | 10 +- deps/npm/lib/commands/fund.js | 4 +- deps/npm/lib/commands/get.js | 8 +- deps/npm/lib/commands/help.js | 9 +- deps/npm/lib/commands/init.js | 9 +- deps/npm/lib/commands/install.js | 3 +- deps/npm/lib/commands/link.js | 17 +- deps/npm/lib/commands/ls.js | 4 +- deps/npm/lib/commands/org.js | 2 +- deps/npm/lib/commands/owner.js | 19 +- deps/npm/lib/commands/profile.js | 2 +- deps/npm/lib/commands/publish.js | 11 +- deps/npm/lib/commands/rebuild.js | 4 +- deps/npm/lib/commands/run-script.js | 27 +- deps/npm/lib/commands/set.js | 7 +- deps/npm/lib/commands/team.js | 2 +- deps/npm/lib/commands/token.js | 2 +- deps/npm/lib/commands/uninstall.js | 10 +- deps/npm/lib/commands/unpublish.js | 18 +- deps/npm/lib/commands/update.js | 4 +- deps/npm/lib/commands/version.js | 2 +- deps/npm/lib/commands/view.js | 6 +- deps/npm/lib/es6/validate-engines.js | 49 ++ deps/npm/lib/npm.js | 110 ++-- deps/npm/lib/utils/cmd-list.js | 35 ++ deps/npm/lib/utils/config/definition.js | 4 + deps/npm/lib/utils/config/definitions.js | 25 +- deps/npm/lib/utils/did-you-mean.js | 10 +- deps/npm/lib/utils/explain-eresolve.js | 4 +- deps/npm/lib/utils/format-search-stream.js | 11 +- deps/npm/lib/utils/npm-usage.js | 9 +- deps/npm/lib/utils/reify-output.js | 1 + deps/npm/lib/workspaces/get-workspaces.js | 6 +- deps/npm/man/man1/npm-access.1 | 2 +- deps/npm/man/man1/npm-adduser.1 | 2 +- deps/npm/man/man1/npm-audit.1 | 2 +- deps/npm/man/man1/npm-bugs.1 | 2 +- deps/npm/man/man1/npm-cache.1 | 2 +- deps/npm/man/man1/npm-ci.1 | 14 +- deps/npm/man/man1/npm-completion.1 | 2 +- deps/npm/man/man1/npm-config.1 | 2 +- deps/npm/man/man1/npm-dedupe.1 | 4 +- deps/npm/man/man1/npm-deprecate.1 | 2 +- deps/npm/man/man1/npm-diff.1 | 2 +- deps/npm/man/man1/npm-dist-tag.1 | 2 +- deps/npm/man/man1/npm-docs.1 | 2 +- deps/npm/man/man1/npm-doctor.1 | 2 +- deps/npm/man/man1/npm-edit.1 | 2 +- deps/npm/man/man1/npm-exec.1 | 2 +- deps/npm/man/man1/npm-explain.1 | 2 +- deps/npm/man/man1/npm-explore.1 | 2 +- deps/npm/man/man1/npm-find-dupes.1 | 4 +- deps/npm/man/man1/npm-fund.1 | 2 +- deps/npm/man/man1/npm-help-search.1 | 2 +- deps/npm/man/man1/npm-help.1 | 2 +- deps/npm/man/man1/npm-hook.1 | 2 +- deps/npm/man/man1/npm-init.1 | 2 +- deps/npm/man/man1/npm-install-ci-test.1 | 14 +- deps/npm/man/man1/npm-install-test.1 | 14 +- deps/npm/man/man1/npm-install.1 | 14 +- deps/npm/man/man1/npm-link.1 | 4 +- deps/npm/man/man1/npm-login.1 | 2 +- deps/npm/man/man1/npm-logout.1 | 2 +- deps/npm/man/man1/npm-ls.1 | 4 +- deps/npm/man/man1/npm-org.1 | 2 +- deps/npm/man/man1/npm-outdated.1 | 2 +- deps/npm/man/man1/npm-owner.1 | 2 +- deps/npm/man/man1/npm-pack.1 | 2 +- deps/npm/man/man1/npm-ping.1 | 2 +- deps/npm/man/man1/npm-pkg.1 | 2 +- deps/npm/man/man1/npm-prefix.1 | 2 +- deps/npm/man/man1/npm-profile.1 | 2 +- deps/npm/man/man1/npm-prune.1 | 2 +- deps/npm/man/man1/npm-publish.1 | 16 +- deps/npm/man/man1/npm-query.1 | 2 +- deps/npm/man/man1/npm-rebuild.1 | 2 +- deps/npm/man/man1/npm-repo.1 | 2 +- deps/npm/man/man1/npm-restart.1 | 2 +- deps/npm/man/man1/npm-root.1 | 2 +- deps/npm/man/man1/npm-run-script.1 | 2 +- deps/npm/man/man1/npm-search.1 | 2 +- deps/npm/man/man1/npm-shrinkwrap.1 | 2 +- deps/npm/man/man1/npm-star.1 | 2 +- deps/npm/man/man1/npm-stars.1 | 2 +- deps/npm/man/man1/npm-start.1 | 2 +- deps/npm/man/man1/npm-stop.1 | 2 +- deps/npm/man/man1/npm-team.1 | 2 +- deps/npm/man/man1/npm-test.1 | 2 +- deps/npm/man/man1/npm-token.1 | 2 +- deps/npm/man/man1/npm-uninstall.1 | 21 +- deps/npm/man/man1/npm-unpublish.1 | 2 +- deps/npm/man/man1/npm-unstar.1 | 2 +- deps/npm/man/man1/npm-update.1 | 4 +- deps/npm/man/man1/npm-version.1 | 2 +- deps/npm/man/man1/npm-view.1 | 2 +- deps/npm/man/man1/npm-whoami.1 | 2 +- deps/npm/man/man1/npm.1 | 4 +- deps/npm/man/man1/npx.1 | 2 +- deps/npm/man/man5/folders.5 | 2 +- deps/npm/man/man5/install.5 | 2 +- deps/npm/man/man5/npm-global.5 | 2 +- deps/npm/man/man5/npm-json.5 | 2 +- deps/npm/man/man5/npm-shrinkwrap-json.5 | 2 +- deps/npm/man/man5/npmrc.5 | 2 +- deps/npm/man/man5/package-json.5 | 2 +- deps/npm/man/man5/package-lock-json.5 | 2 +- deps/npm/man/man7/config.7 | 28 +- deps/npm/man/man7/dependency-selectors.7 | 2 +- deps/npm/man/man7/developers.7 | 2 +- deps/npm/man/man7/logging.7 | 2 +- deps/npm/man/man7/orgs.7 | 2 +- deps/npm/man/man7/package-spec.7 | 2 +- deps/npm/man/man7/registry.7 | 2 +- deps/npm/man/man7/removal.7 | 2 +- deps/npm/man/man7/scope.7 | 2 +- deps/npm/man/man7/scripts.7 | 2 +- deps/npm/man/man7/workspaces.7 | 2 +- .../@npmcli/arborist/package.json | 1 - .../node_modules/@npmcli/config/lib/index.js | 7 + .../node_modules/@npmcli/config/package.json | 2 +- deps/npm/node_modules/@npmcli/git/lib/find.js | 14 +- .../npm/node_modules/@npmcli/git/package.json | 11 +- .../@npmcli/package-json/lib/index.js | 1 + .../@npmcli/package-json/lib/normalize.js | 32 +- .../@npmcli/package-json/package.json | 8 +- deps/npm/node_modules/chalk/license | 2 +- deps/npm/node_modules/chalk/package.json | 59 ++- deps/npm/node_modules/chalk/source/index.js | 164 +++--- .../node_modules/chalk/source/templates.js | 134 ----- deps/npm/node_modules/chalk/source/util.js | 39 -- .../node_modules/chalk/source/utilities.js | 33 ++ .../chalk/source/vendor/ansi-styles/index.js | 223 +++++++++ .../source/vendor/supports-color/browser.js | 30 ++ .../source/vendor/supports-color/index.js | 181 +++++++ deps/npm/node_modules/has-flag/index.js | 8 - deps/npm/node_modules/has-flag/license | 9 - deps/npm/node_modules/has-flag/package.json | 46 -- deps/npm/node_modules/libnpmexec/README.md | 2 +- .../node_modules/libnpmexec/lib/run-script.js | 17 +- deps/npm/node_modules/libnpmexec/package.json | 5 +- deps/npm/node_modules/libnpmpublish/README.md | 11 + .../libnpmpublish/lib/provenance.js | 45 ++ .../node_modules/libnpmpublish/lib/publish.js | 122 ++--- .../node_modules/libnpmpublish/package.json | 3 +- .../npm-audit-report/lib/colors.js | 16 +- .../npm-audit-report/lib/index.js | 4 +- .../npm-audit-report/lib/reporters/detail.js | 10 +- .../npm-audit-report/lib/reporters/install.js | 4 +- .../npm-audit-report/package.json | 13 +- .../node_modules/supports-color/browser.js | 5 - deps/npm/node_modules/supports-color/index.js | 135 ----- deps/npm/node_modules/supports-color/license | 9 - .../node_modules/supports-color/package.json | 53 -- deps/npm/package.json | 29 +- .../test/lib/commands/audit.js.test.cjs | 21 + .../test/lib/commands/config.js.test.cjs | 4 + .../test/lib/commands/diff.js.test.cjs | 2 +- .../test/lib/commands/publish.js.test.cjs | 142 ++++++ .../tap-snapshots/test/lib/docs.js.test.cjs | 471 +++++++++++++++++- .../lib/utils/config/definition.js.test.cjs | 9 + .../test/lib/utils/explain-dep.js.test.cjs | 76 +-- .../lib/utils/explain-eresolve.js.test.cjs | 70 +-- .../lib/utils/open-url-prompt.js.test.cjs | 16 +- .../test/lib/utils/reify-finish.js.test.cjs | 15 - deps/npm/test/bin/npx-cli.js | 2 +- .../fixtures/libnpmsearch-stream-result.js | 8 +- deps/npm/test/fixtures/mock-globals.js | 236 --------- deps/npm/test/fixtures/mock-npm.js | 27 +- deps/npm/test/fixtures/sandbox.js | 4 +- deps/npm/test/lib/cli-entry.js | 168 +++++++ deps/npm/test/lib/cli.js | 163 +----- deps/npm/test/lib/commands/access.js | 3 +- deps/npm/test/lib/commands/adduser.js | 147 ++---- deps/npm/test/lib/commands/audit.js | 320 +++++++++--- deps/npm/test/lib/commands/bugs.js | 3 +- deps/npm/test/lib/commands/cache.js | 9 +- deps/npm/test/lib/commands/completion.js | 41 +- deps/npm/test/lib/commands/deprecate.js | 4 +- deps/npm/test/lib/commands/diff.js | 31 +- deps/npm/test/lib/commands/dist-tag.js | 15 +- deps/npm/test/lib/commands/doctor.js | 2 +- deps/npm/test/lib/commands/explain.js | 11 +- deps/npm/test/lib/commands/explore.js | 38 +- deps/npm/test/lib/commands/get.js | 5 +- deps/npm/test/lib/commands/help-search.js | 3 +- deps/npm/test/lib/commands/help.js | 21 +- deps/npm/test/lib/commands/hook.js | 2 +- deps/npm/test/lib/commands/init.js | 15 +- deps/npm/test/lib/commands/install.js | 30 +- deps/npm/test/lib/commands/link.js | 5 +- deps/npm/test/lib/commands/login.js | 126 ++--- deps/npm/test/lib/commands/logout.js | 2 +- deps/npm/test/lib/commands/org.js | 8 +- deps/npm/test/lib/commands/outdated.js | 78 +-- deps/npm/test/lib/commands/owner.js | 17 +- deps/npm/test/lib/commands/pack.js | 8 +- deps/npm/test/lib/commands/prefix.js | 2 +- deps/npm/test/lib/commands/profile.js | 13 +- deps/npm/test/lib/commands/prune.js | 1 - deps/npm/test/lib/commands/publish.js | 54 +- deps/npm/test/lib/commands/root.js | 2 +- deps/npm/test/lib/commands/run-script.js | 8 +- deps/npm/test/lib/commands/stars.js | 15 +- deps/npm/test/lib/commands/team.js | 12 +- deps/npm/test/lib/commands/token.js | 17 +- deps/npm/test/lib/commands/uninstall.js | 12 +- deps/npm/test/lib/commands/unpublish.js | 6 +- deps/npm/test/lib/commands/version.js | 7 +- deps/npm/test/lib/commands/view.js | 6 +- deps/npm/test/lib/docs.js | 48 +- deps/npm/test/lib/es6/validate-engines.js | 34 ++ deps/npm/test/lib/fixtures/mock-globals.js | 331 ------------ deps/npm/test/lib/load-all-commands.js | 43 +- deps/npm/test/lib/npm.js | 49 +- deps/npm/test/lib/utils/ansi-trim.js | 9 +- deps/npm/test/lib/utils/audit-error.js | 14 +- .../lib/utils/completion/installed-deep.js | 93 +--- .../lib/utils/completion/installed-shallow.js | 69 +-- deps/npm/test/lib/utils/config/definitions.js | 2 +- deps/npm/test/lib/utils/config/index.js | 2 +- deps/npm/test/lib/utils/did-you-mean.js | 15 +- deps/npm/test/lib/utils/display.js | 2 +- deps/npm/test/lib/utils/error-message.js | 4 +- deps/npm/test/lib/utils/exit-handler.js | 22 +- deps/npm/test/lib/utils/explain-dep.js | 466 ++++++++--------- deps/npm/test/lib/utils/explain-eresolve.js | 36 +- deps/npm/test/lib/utils/open-url-prompt.js | 220 ++++---- deps/npm/test/lib/utils/open-url.js | 234 ++++----- deps/npm/test/lib/utils/reify-finish.js | 114 +++-- deps/npm/test/lib/utils/reify-output.js | 1 + deps/npm/test/lib/utils/update-notifier.js | 7 +- 321 files changed, 4603 insertions(+), 3408 deletions(-) create mode 100644 deps/npm/lib/cli-entry.js create mode 100644 deps/npm/lib/es6/validate-engines.js delete mode 100644 deps/npm/node_modules/chalk/source/templates.js delete mode 100644 deps/npm/node_modules/chalk/source/util.js create mode 100644 deps/npm/node_modules/chalk/source/utilities.js create mode 100644 deps/npm/node_modules/chalk/source/vendor/ansi-styles/index.js create mode 100644 deps/npm/node_modules/chalk/source/vendor/supports-color/browser.js create mode 100644 deps/npm/node_modules/chalk/source/vendor/supports-color/index.js delete mode 100644 deps/npm/node_modules/has-flag/index.js delete mode 100644 deps/npm/node_modules/has-flag/license delete mode 100644 deps/npm/node_modules/has-flag/package.json delete mode 100644 deps/npm/node_modules/supports-color/browser.js delete mode 100644 deps/npm/node_modules/supports-color/index.js delete mode 100644 deps/npm/node_modules/supports-color/license delete mode 100644 deps/npm/node_modules/supports-color/package.json delete mode 100644 deps/npm/tap-snapshots/test/lib/utils/reify-finish.js.test.cjs delete mode 100644 deps/npm/test/fixtures/mock-globals.js create mode 100644 deps/npm/test/lib/cli-entry.js create mode 100644 deps/npm/test/lib/es6/validate-engines.js delete mode 100644 deps/npm/test/lib/fixtures/mock-globals.js diff --git a/deps/npm/docs/content/commands/npm-access.md b/deps/npm/docs/content/commands/npm-access.md index 84421e880961..9e9f385fe386 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 bc7d888a2f3d..e19b3e3a3f85 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 7358d878980a..62f93448c245 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 1f135fc6c933..4fb660a3ecb5 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 a9d76179e811..1697be92adb7 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 5757bf1b2943..2a1f39a00f9c 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 69370fd5deba..80f44b27d12f 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 d9c614d519eb..592d76973cff 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 146aab88c5bf..706ecf3135c4 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 852fcf3d0661..e93aef383c3f 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 027a101d121e..582fc55eef3f 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 bd399ce494a6..e72d273ac817 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 04a4d15b5afc..a26df11b5dd0 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 af19ec5f0778..fa8d80cffc97 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 382429ad7e97..b0f0ebcb6808 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 cc312a0d28c6..e25e760d08d7 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 bfdff61cbb4e..b326b9236153 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 0db66f49ad65..cd12e1b40bc4 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 d92ea03aefb1..5bc4602ef981 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 48af6da7fa08..bc2c8762eefd 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 1304512e33a6..581e78661d6c 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 d8d7acee77f0..b0efecdb7e67 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 c5fe98be705f..b38f49177083 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 b864051ca138..a2136fd52f39 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 a2225b9f3897..627d016fe1c1 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 9c4c61a6fb04..607dc60b190d 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 00f10ad95eeb..531dc71ae392 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 8ac3948f116d..2d5aa3e5827f 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 1ba7a4b73d50..3091ebfdeca7 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 ca788b01fcb9..f06524731df5 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 0e1061ab168a..b1a1c62688e6 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 2f1ca487d55a..cd172adc3dee 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 a39f05543919..2ef859786085 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 812be9f002de..cc3326f75942 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 484aabfca543..1df2a8d1ddb8 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 e17a26d346b8..7718ed34ff82 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 b8cdde7e151a..d048532c98d4 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 f0374944cc3f..071258e78471 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 334209490b24..0e18cddf8b36 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 5a6bfb79cee3..ec9cc2c5752f 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 8a58a6176fa7..c42e09767ef4 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 10ddc139f853..005f4ac87158 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 6c31cfceb511..545315c742fd 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 41777d302556..75d70c2afb62 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 26011e4f7959..9e3ae1e9b257 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 3e4fa4553957..df5cc51b417e 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 ba70051f10ac..59e1fbec52cc 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 114cde202e2f..642ccfa14f19 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 7ba8425ffa47..cf9392c605c3 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 05df3fb7d742..6075b4363c2f 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 68b2192673d3..a32619a75fe1 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 ffdb578d10fc..72a7822b59fc 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 bfd8e05a14f3..a17193d5fe8d 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 ef12bcd64ac9..de90df9c0c3b 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 20ef4afa947d..52f2961246b1 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 7e49ad096a82..92ae740befa3 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 fa9d963c4f96..7a8adb62bbb2 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 00d165cfbc77..bc31b4a12a73 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 14a94305b82f..280b6ebe1f09 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 3801dfaa4882..a1458f020235 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 347e7d40993c..4cd80b802510 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 51983cbbe167..9d1f02c42639 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 12dc2c58a756..9fed910b2eba 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 d77f4a59c7de..46db8279fb04 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 82d5eba473f1..725f197e8503 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 1afa069a3dc2..f87de26e312b 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 27ab7c3ae5b2..5c0fb7cf0848 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 0c72b0c09172..ba8d534d1834 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 9686106d8b8d..ac36e1beb568 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 98a9f08418a1..4a4e6c274a09 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 32c3da827ca8..373a2ae22f92 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 0adff8e5d95e..598964ce524e 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 000000000000..aad06e069038 --- /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 a393626f0829..c85ecb65a700 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 318151fc81e2..99c1264a84ed 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 7b75ecbf2e02..500620f2cd01 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 66b432dfc13a..50bb35e3544d 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 97c292e8c538..e662379278e0 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 efbad9d61001..38205ad8fc49 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 dfd44015cd04..b49cdd648f9d 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 844d5f60a02a..ada2bac40f2f 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 3924166af0a8..64d81d525d79 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 bc61a4691e55..15f9622d1490 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 a671a5d6bad5..fbc7840a3987 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 a5235c784585..ed4b07dc39b4 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 a72514fb9780..403274db68df 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 0d915cb4c695..7a03ea4eabd7 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 1e8981967fc3..2804d36cd560 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 5e92e85a6638..4bf5d2caf826 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 4b40ef37afa2..39c580f9a687 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 1e5661a7840f..539fba885dee 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 99f5b326f7b2..2bfd20a72658 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 61ae5a980886..a81450a247ed 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 eb9114802d5e..92300b1c404a 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 575ff75e2a6c..1f32d41ff730 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 3a997db800db..5b54dd41f3d6 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 4fba1209e033..a7d4ac2f29fb 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 8befbc5ca34c..54707278f969 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 527447e42791..8af96f725555 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 e1bce0e52a51..13efdde750a8 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 b650026a599a..f315d183845c 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 2d4fc663715e..3c6cf305a6e5 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 bc2e4f379636..c24684b3dd61 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 e5373119ec75..07775efb9cf2 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 f1bcded192e5..66985297b957 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 26be5ad68198..caa69dd317ca 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 a52328367179..029a6fdd3101 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 bbe7dcdd18bb..f118184124db 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 000000000000..0eaa549fc370 --- /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 eebb453dbbac..f08ef32c180d 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 e5479139033d..9bd252bc3fac 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 f88d8334cf01..54e522c355b9 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 78c341eabeff..f86c3ddff81b 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 10b33d5f83a0..ff3c812b46c3 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 ba46f3480adb..f3c6ae23a479 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 21929cce7d05..762dea90859d 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 b04ad33f9dd7..1bd790ca601b 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 5ac7fa4b0189..22036dc8110c 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 706553359600..59efb0e9f01b 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 8b8d996a1199..96534a085059 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 4653d85c7f8f..3a018dbdb9bc 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 270c517ef17f..da9a483715f6 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 efd8922d66c6..a5ddd4e79cf7 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 2757922d47b3..5669388f5538 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 4728ef4cb9bf..05e435ec7b9f 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 18a006978e39..d72df722ccd3 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 a860ea4a9533..4b19fa0e4735 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 8cbe55011c07..56e57db5eb54 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 f4b4087a4280..1458a880fca9 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 906e1776f5f0..44df189c3910 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 50dc8e390804..11e501009fb1 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 be212b1f014c..dd701e970997 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 1592de0c3220..b1d36f31034a 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 1c428d2c2a9f..140946f3a1d3 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 d1260e218440..d6efae12633f 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 d206176d92ba..1a32c14c1d3d 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 39fe060038a8..2e9549c753aa 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 efb00a7eba7b..13d9d3adebaa 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 fe3adb8a7bca..074cd075823d 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 e46f4b3d2f89..1de2840e884e 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 b95a78b18bf9..340db5486a64 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 99cc0585ffda..4dfab8c702c8 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 ec4f8c5c1e35..d74c57e3266c 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 96b310cdf987..0aac5f1f8749 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 a403b55b15ba..b66013372f7b 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 8359b949f164..e8a019ad45e3 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 ebe0a7c70d7a..38df2396ca9b 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 61b9c2ae235d..f593dbb817ef 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 546a04044e4e..1f3fbb5f40b0 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 fe605158b7aa..4696fc20bf6d 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 8a69570f2da3..0d1d4458e2f0 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 96527eec8bda..b1665a772b0b 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 68997c98c121..16a6febff6c7 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 40e1ac2e3824..7803db5d7a8f 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 db6f0a79d6bb..568a752ae79d 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 42e6834e7e55..ec10aec156d2 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 a1d4ee3dbc02..9b24982794ac 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 b4f3595ff683..cc5daf398a54 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 98d181fe6273..d724cc5282c7 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 5f7ccce98d11..bb3153987946 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 0cd80c479cfe..84dcbb977577 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 5153e2297755..e0f8c8e084c2 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 960699c6192f..91d81761c105 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 21ae38d01ccb..0caa8f7eea44 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 6a53d9e695a2..e640d17e025d 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 0838720edb31..cdd5e4ad7ddb 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 18024e5e9cdd..f26ddca63b83 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 312c44448833..0d641645964d 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 f293aa8a346b..2bbd7b3e2de0 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 c7812e1e925a..3f8721a2fcf2 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 06dbfc014275..27c095652c39 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 cdc7d807cf65..14742a96d8a1 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 84b82d9a2cb9..abed5a5d48d0 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 9832f0b5f01c..7f4945ba882d 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 d0593123ac84..a9aeb2f6c24f 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 7e0237c768a8..b35a578da663 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 21ac3b07226c..151d24baa7c8 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 70242ed19632..802ccf68678e 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 82e3ff9b193d..787e2ee66387 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 620d6d56fe08..3a88228dc2f2 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 5733d82cfcfd..50b8dcb5e4cf 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 add5aac5a268..7bc53ca0d779 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 1fcb52d7b395..7e6e660595d8 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 c392079457ac..62545305dc67 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 934e3af20f75..c4ddf51f87ca 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 de38edb1b1b4..096c705950c1 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 934e3af20f75..c4ddf51f87ca 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 c646afa88dfe..36e22713c4ce 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 f3ab3eda6aa4..3ac345a3452c 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 c04212f9e21d..8aaab33cd744 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 c646afa88dfe..36e22713c4ce 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 0f529dc9bbc4..ceac876f546a 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 e20d300946a8..cec41d8d3f4b 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 d84c647c9303..74767ecff534 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 9d1c568bd7c4..30c2c60da44c 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 f8f0e9a9e0d8..62ae6b1a5b10 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 7e67161fb683..6ebfc55f1526 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 21342529c51c..0e3ff55c217d 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 b27bdd402950..db66480d4465 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 1f9dfcf016ae..dfd9542fb278 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 00f2240aedd3..ac9cd5f29ee6 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 00ae221f4b09..72012d4dcd48 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 896e40c294c3..68dca1c75aa1 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 bba6a2e9e5c8..ec98a3c6a693 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 b7b848dea151..84a009851d8a 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 e68d51669014..e0190fc3ac53 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 d58f01dbcc16..34bd310b88e5 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 41c78dddfa3c..eeba1c041578 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 34e415b45d49..756837cdde58 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 bc101cd4fde1..9594ef3d7ff4 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 61607c5bb6ae..a4e2cbab4c0b 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 e7af2f77107d..fa7ceba3eb4a 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 47c23f29068c..ddcf7589e979 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": "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/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 75ec66350527..8bc993da5d62 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 b130949d646f..000000000000 --- 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 ca466fd466c0..000000000000 --- 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 000000000000..4366dee0d84d --- /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 000000000000..eaa7bed6cb1e --- /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 000000000000..9fa6888f1028 --- /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 000000000000..a7cea61e9eb5 --- /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 b6f80b1f8ffd..000000000000 --- 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 e7af2f77107d..000000000000 --- 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 a9cba4b856d0..000000000000 --- 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 dc79d12cffc4..fb4a1e32b18d 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 ba60395468d6..89dcf2e65303 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 e47e301ab7dd..1fa85ff033b8 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 9c9c61d4b596..90b1f7c68ab4 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 1eb870da5f24..ebe4a2447533 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 79c00eb68ad0..3749c3cebfdc 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 a4adbe2a50f1..0e86861893e0 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 2fbf5c36093d..e6688f2f1c8c 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 63063f92526a..d0ced01efefe 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 ba2f013836d9..6dde8ec88de4 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 cb8a249691e2..0a1e82533e65 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 8779f4c1d2c7..492071c1faf9 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 62afa3a7425d..000000000000 --- 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 6fada390fb88..000000000000 --- 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 e7af2f77107d..000000000000 --- 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 f7182edcea2b..000000000000 --- 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 148a2a3b9e56..f417d60fbab8 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 4fec8f86c5ba..761119168826 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 c88888b7cd7d..93ac959ce440 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 533b4f196e66..e87086d7d9b8 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 7cb836226a76..54dd00985975 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": "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/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 d7a943500e49..bd5aa05991ab 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 ad506ae8e358..bf4dc30a041f 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 8550617eb0a0..876cc6552b76 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 99ad5c0f31e9..3d73019d3e45 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 8af3c475c772..968b14a20d90 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 a82905a39967..000000000000 --- 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 5670f24f07b7..67a8d3319fc1 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 b2ec20f59efe..1ec8b7b113d6 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 aec8a8396368..000000000000 --- 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 a2d35c2479d7..b91ee8a3933a 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 460609628c8a..01a5e562fd9b 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 000000000000..b436304c3004 --- /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 cafd13feabe9..a6cb576e886e 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 d1839aaaef21..7aec33701297 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 ddfbb945b2fc..410e8c4987ca 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 5c82fa14de32..4014e7338735 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 bf45b9eee81a..953c8e6345a2 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 fe2854f9aa62..15ee4dc80aa1 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 6cc1677552e8..904d9410fdd6 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 48513c7303a0..4ae146fd3aee 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 d9ff9e5dad0e..36a9e4bc17d9 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 4cc241f74582..1c63ce497d3f 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 d1a88299e69a..1682a6cccfa4 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 79c917a1cd45..f4d898797bcb 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 786a34a8e298..6988dca90fbf 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 597cccc3ff0b..dec634f83517 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 ce6e5f7cf00b..8da725fad769 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 e38f1bbce24d..3fda9fb6e07f 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 01da9dc720da..e4e1214b812f 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 00caf90d0ec9..cb708303f405 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 1be42d6e6125..f40b62edde17 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 feae75a4b909..65792fd141ac 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 63666670712e..b42d3001ebb9 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 0043bb4c5792..4ff21665f303 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 d3700304328e..511251e1bb09 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 02f2067c5480..7becc79d62e1 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 f9399a60cdf8..9329e8985e60 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 3e7c0225c306..61296cc93a53 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 e8295cf6a5b3..4fc348843fa2 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 1152acfdc5c4..784523f7ccd8 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 81245bcfca16..65cfba5e5c00 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 39696066130f..820760bb5704 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 a886b30c3ee4..506e2bc04eb8 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 6e2bf22adddc..cb54a7f51e90 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 124d2d344d8d..d92ced950291 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 a13a56d986e3..1a5480293edc 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 1fd686a4427c..2bc4af4a81a3 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 59a517d144d3..ae116d44c208 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 96c06bf3ffee..6e898bd3d07e 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 c48ff827fa28..8aa6c088bfc9 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 51bc130df24e..ca07ef9eec2f 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 b8a1a4fc6007..5e7bfe45a93c 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 000000000000..0e6bce726af9 --- /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 55418dd8e199..000000000000 --- 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 1742376a36e6..d3846434489c 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 61b31be62002..162e8c83ca4a 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 de8d39293700..5a9e3b0c87cb 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 1cb29a0857d7..f6be56a152f7 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 434d0214db4c..0af26861ff83 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 5a65b6b6bfae..3666803979cb 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 288166039bf6..8775824c6c13 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 90931a96d7aa..010ec34888da 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 d3cb3a24f0ae..d111c2f00296 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 7a99dcb679c0..b8f047668bfe 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 37b3bc6afedd..1ba5865592ed 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 8942d9092259..f553e1a2ea51 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 e5389fd26d79..06174f36a7ff 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 0f60556ef2ac..157cc97a5a3c 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 faf2ab32587a..c889313e162c 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 28a11b3609c6..0ce1b57aa5f9 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 ee112203a24b..a2ca6e436796 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 5d1d5be47efa..1c6215ab33be 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 9c12433a2d11..cc5348a440e0 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, })