summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deps/npm/README.md2
-rw-r--r--deps/npm/docs/content/commands/npm-bin.md2
-rw-r--r--deps/npm/docs/content/commands/npm-ci.md9
-rw-r--r--deps/npm/docs/content/commands/npm-config.md11
-rw-r--r--deps/npm/docs/content/commands/npm-diff.md2
-rw-r--r--deps/npm/docs/content/commands/npm-install-test.md2
-rw-r--r--deps/npm/docs/content/commands/npm-install.md2
-rw-r--r--deps/npm/docs/content/commands/npm-link.md2
-rw-r--r--deps/npm/docs/content/commands/npm-ls.md2
-rw-r--r--deps/npm/docs/content/commands/npm-outdated.md2
-rw-r--r--deps/npm/docs/content/commands/npm-prefix.md2
-rw-r--r--deps/npm/docs/content/commands/npm-rebuild.md2
-rw-r--r--deps/npm/docs/content/commands/npm-root.md2
-rw-r--r--deps/npm/docs/content/commands/npm-set-script.md2
-rw-r--r--deps/npm/docs/content/commands/npm-update.md2
-rw-r--r--deps/npm/docs/content/using-npm/config.md45
-rw-r--r--deps/npm/docs/output/commands/npm-bin.html2
-rw-r--r--deps/npm/docs/output/commands/npm-ci.html9
-rw-r--r--deps/npm/docs/output/commands/npm-config.html11
-rw-r--r--deps/npm/docs/output/commands/npm-diff.html2
-rw-r--r--deps/npm/docs/output/commands/npm-install-test.html2
-rw-r--r--deps/npm/docs/output/commands/npm-install.html2
-rw-r--r--deps/npm/docs/output/commands/npm-link.html2
-rw-r--r--deps/npm/docs/output/commands/npm-ls.html4
-rw-r--r--deps/npm/docs/output/commands/npm-outdated.html2
-rw-r--r--deps/npm/docs/output/commands/npm-prefix.html2
-rw-r--r--deps/npm/docs/output/commands/npm-rebuild.html2
-rw-r--r--deps/npm/docs/output/commands/npm-root.html2
-rw-r--r--deps/npm/docs/output/commands/npm-set-script.html1
-rw-r--r--deps/npm/docs/output/commands/npm-update.html2
-rw-r--r--deps/npm/docs/output/commands/npm.html2
-rw-r--r--deps/npm/docs/output/using-npm/config.html45
-rw-r--r--deps/npm/lib/commands/bin.js2
-rw-r--r--deps/npm/lib/commands/birthday.js4
-rw-r--r--deps/npm/lib/commands/cache.js14
-rw-r--r--deps/npm/lib/commands/ci.js51
-rw-r--r--deps/npm/lib/commands/config.js2
-rw-r--r--deps/npm/lib/commands/dedupe.js2
-rw-r--r--deps/npm/lib/commands/diff.js2
-rw-r--r--deps/npm/lib/commands/dist-tag.js2
-rw-r--r--deps/npm/lib/commands/fund.js2
-rw-r--r--deps/npm/lib/commands/install.js2
-rw-r--r--deps/npm/lib/commands/link.js2
-rw-r--r--deps/npm/lib/commands/ls.js2
-rw-r--r--deps/npm/lib/commands/outdated.js6
-rw-r--r--deps/npm/lib/commands/owner.js4
-rw-r--r--deps/npm/lib/commands/pack.js6
-rw-r--r--deps/npm/lib/commands/pkg.js2
-rw-r--r--deps/npm/lib/commands/publish.js7
-rw-r--r--deps/npm/lib/commands/rebuild.js2
-rw-r--r--deps/npm/lib/commands/set-script.js4
-rw-r--r--deps/npm/lib/commands/shrinkwrap.js2
-rw-r--r--deps/npm/lib/commands/uninstall.js5
-rw-r--r--deps/npm/lib/commands/update.js2
-rw-r--r--deps/npm/lib/commands/view.js2
-rw-r--r--deps/npm/lib/npm.js15
-rw-r--r--deps/npm/lib/utils/config/definitions.js15
-rw-r--r--deps/npm/lib/utils/get-identity.js45
-rw-r--r--deps/npm/man/man1/npm-bin.13
-rw-r--r--deps/npm/man/man1/npm-ci.113
-rw-r--r--deps/npm/man/man1/npm-config.117
-rw-r--r--deps/npm/man/man1/npm-diff.13
-rw-r--r--deps/npm/man/man1/npm-install-test.13
-rw-r--r--deps/npm/man/man1/npm-install.13
-rw-r--r--deps/npm/man/man1/npm-link.13
-rw-r--r--deps/npm/man/man1/npm-ls.15
-rw-r--r--deps/npm/man/man1/npm-outdated.13
-rw-r--r--deps/npm/man/man1/npm-prefix.13
-rw-r--r--deps/npm/man/man1/npm-rebuild.13
-rw-r--r--deps/npm/man/man1/npm-root.13
-rw-r--r--deps/npm/man/man1/npm-set-script.12
-rw-r--r--deps/npm/man/man1/npm-update.13
-rw-r--r--deps/npm/man/man1/npm.12
-rw-r--r--deps/npm/man/man7/config.761
-rw-r--r--deps/npm/node_modules/cacache/lib/content/read.js163
-rw-r--r--deps/npm/node_modules/cacache/lib/content/rm.js18
-rw-r--r--deps/npm/node_modules/cacache/lib/content/write.js62
-rw-r--r--deps/npm/node_modules/cacache/lib/entry-index.js195
-rw-r--r--deps/npm/node_modules/cacache/lib/get.js140
-rw-r--r--deps/npm/node_modules/cacache/lib/put.js35
-rw-r--r--deps/npm/node_modules/cacache/lib/util/fix-owner.js75
-rw-r--r--deps/npm/node_modules/cacache/lib/util/move-file.js83
-rw-r--r--deps/npm/node_modules/cacache/lib/util/tmp.js12
-rw-r--r--deps/npm/node_modules/cacache/lib/verify.js348
-rw-r--r--deps/npm/node_modules/cacache/package.json10
-rw-r--r--deps/npm/node_modules/libnpmpack/package.json4
-rw-r--r--deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js138
-rw-r--r--deps/npm/node_modules/make-fetch-happen/lib/pipeline.js41
-rw-r--r--deps/npm/node_modules/make-fetch-happen/lib/remote.js13
-rw-r--r--deps/npm/node_modules/make-fetch-happen/package.json8
-rw-r--r--deps/npm/node_modules/npm-packlist/lib/index.js51
-rw-r--r--deps/npm/node_modules/npm-packlist/package.json6
-rw-r--r--deps/npm/node_modules/pacote/README.md4
-rw-r--r--deps/npm/node_modules/pacote/lib/dir.js4
-rw-r--r--deps/npm/node_modules/pacote/lib/registry.js191
-rw-r--r--deps/npm/node_modules/pacote/package.json8
-rw-r--r--deps/npm/node_modules/ssri/lib/index.js27
-rw-r--r--deps/npm/node_modules/ssri/package.json6
-rw-r--r--deps/npm/package.json10
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/cache.js.test.cjs63
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/ci.js.test.cjs13
-rw-r--r--deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs6
-rw-r--r--deps/npm/tap-snapshots/test/lib/npm.js.test.cjs (renamed from deps/npm/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs)452
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs11
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs45
-rw-r--r--deps/npm/test/fixtures/mock-npm.js4
-rw-r--r--deps/npm/test/fixtures/mock-registry.js19
-rw-r--r--deps/npm/test/lib/commands/cache.js557
-rw-r--r--deps/npm/test/lib/commands/ci.js451
-rw-r--r--deps/npm/test/lib/commands/deprecate.js2
-rw-r--r--deps/npm/test/lib/commands/exec.js2
-rw-r--r--deps/npm/test/lib/commands/outdated.js12
-rw-r--r--deps/npm/test/lib/commands/ping.js154
-rw-r--r--deps/npm/test/lib/commands/set-script.js2
-rw-r--r--deps/npm/test/lib/commands/whoami.js24
-rw-r--r--deps/npm/test/lib/npm.js58
-rw-r--r--deps/npm/test/lib/utils/get-identity.js103
-rw-r--r--deps/npm/test/lib/utils/is-windows.js39
-rw-r--r--deps/npm/test/lib/utils/npm-usage.js60
-rw-r--r--deps/npm/test/lib/utils/ping.js35
120 files changed, 2044 insertions, 2237 deletions
diff --git a/deps/npm/README.md b/deps/npm/README.md
index 642e1a51eb..7e4a5f38a7 100644
--- a/deps/npm/README.md
+++ b/deps/npm/README.md
@@ -50,7 +50,7 @@ npm <command>
* [**Documentation**](https://docs.npmjs.com/) - Official docs & how-tos for all things **npm**
* Note: you can also search docs locally with `npm help-search <query>`
* [**Bug Tracker**](https://github.com/npm/cli/issues) - Search or submit bugs against the CLI
-* [**Roadmap**](https://github.com/npm/roadmap) - Track & follow along with our public roadmap
+* [**Roadmap**](https://github.com/orgs/github/projects/4247/views/1?filterQuery=npm) - Track & follow along with our public roadmap
* [**Feedback**](https://github.com/npm/feedback) - Contribute ideas & discussion around the npm registry, website & CLI
* [**RFCs**](https://github.com/npm/rfcs) - Contribute ideas & specifications for the API/design of the npm CLI
* [**Service Status**](https://status.npmjs.org/) - Monitor the current status & see incident reports for the website & registry
diff --git a/deps/npm/docs/content/commands/npm-bin.md b/deps/npm/docs/content/commands/npm-bin.md
index 94b72cfd5c..b344ea2fc9 100644
--- a/deps/npm/docs/content/commands/npm-bin.md
+++ b/deps/npm/docs/content/commands/npm-bin.md
@@ -34,6 +34,8 @@ Print the folder where npm will install executables.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-ci.md b/deps/npm/docs/content/commands/npm-ci.md
index 2bb542a725..3374bf1e25 100644
--- a/deps/npm/docs/content/commands/npm-ci.md
+++ b/deps/npm/docs/content/commands/npm-ci.md
@@ -1,7 +1,7 @@
---
title: npm-ci
section: 1
-description: Install a project with a clean slate
+description: Clean install a project
---
### Synopsis
@@ -28,12 +28,7 @@ it's meant to be used in automated environments such as test platforms,
continuous integration, and deployment -- or any situation where you want
to make sure you're doing a clean install of your dependencies.
-`npm ci` will be significantly faster when:
-
-- There is a `package-lock.json` or `npm-shrinkwrap.json` file.
-- The `node_modules` folder is missing or empty.
-
-In short, the main differences between using `npm install` and `npm ci` are:
+The main differences between using `npm install` and `npm ci` are:
* The project **must** have an existing `package-lock.json` or
`npm-shrinkwrap.json`.
diff --git a/deps/npm/docs/content/commands/npm-config.md b/deps/npm/docs/content/commands/npm-config.md
index a66a198ce4..809e42a1be 100644
--- a/deps/npm/docs/content/commands/npm-config.md
+++ b/deps/npm/docs/content/commands/npm-config.md
@@ -124,6 +124,8 @@ Not supported by all npm commands.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
@@ -156,6 +158,15 @@ The command to run for `npm edit` and `npm config edit`.
When passed to `npm config` this refers to which config file to use.
+When set to "global" mode, packages are installed into the `prefix` folder
+instead of the current working directory. See
+[folders](/configuring-npm/folders) for more on the differences in behavior.
+
+* packages are installed into the `{prefix}/lib/node_modules` folder, instead
+ of the current working directory.
+* bin files are linked to `{prefix}/bin`
+* man pages are linked to `{prefix}/share/man`
+
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
diff --git a/deps/npm/docs/content/commands/npm-diff.md b/deps/npm/docs/content/commands/npm-diff.md
index 7dcc8af7c3..7183e4a2b7 100644
--- a/deps/npm/docs/content/commands/npm-diff.md
+++ b/deps/npm/docs/content/commands/npm-diff.md
@@ -248,6 +248,8 @@ Treat all files as text in `npm diff`.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-install-test.md b/deps/npm/docs/content/commands/npm-install-test.md
index 3dd860ea5c..18e374869d 100644
--- a/deps/npm/docs/content/commands/npm-install-test.md
+++ b/deps/npm/docs/content/commands/npm-install-test.md
@@ -70,6 +70,8 @@ rather than using npm's default semver range operator.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-install.md b/deps/npm/docs/content/commands/npm-install.md
index d6668a2c2b..318df5780e 100644
--- a/deps/npm/docs/content/commands/npm-install.md
+++ b/deps/npm/docs/content/commands/npm-install.md
@@ -460,6 +460,8 @@ rather than using npm's default semver range operator.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-link.md b/deps/npm/docs/content/commands/npm-link.md
index 975c807c38..34c67aa3de 100644
--- a/deps/npm/docs/content/commands/npm-link.md
+++ b/deps/npm/docs/content/commands/npm-link.md
@@ -153,6 +153,8 @@ rather than using npm's default semver range operator.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-ls.md b/deps/npm/docs/content/commands/npm-ls.md
index ded8c0c0d2..5ad4593bfa 100644
--- a/deps/npm/docs/content/commands/npm-ls.md
+++ b/deps/npm/docs/content/commands/npm-ls.md
@@ -137,6 +137,8 @@ Output parseable results from commands that write to standard output. For
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-outdated.md b/deps/npm/docs/content/commands/npm-outdated.md
index 6fa026550e..1bf2de039c 100644
--- a/deps/npm/docs/content/commands/npm-outdated.md
+++ b/deps/npm/docs/content/commands/npm-outdated.md
@@ -150,6 +150,8 @@ Output parseable results from commands that write to standard output. For
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-prefix.md b/deps/npm/docs/content/commands/npm-prefix.md
index 39328bcc88..6f08e43fa8 100644
--- a/deps/npm/docs/content/commands/npm-prefix.md
+++ b/deps/npm/docs/content/commands/npm-prefix.md
@@ -51,6 +51,8 @@ npm prefix -g
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-rebuild.md b/deps/npm/docs/content/commands/npm-rebuild.md
index 52c368c8c5..fa5b0cfa97 100644
--- a/deps/npm/docs/content/commands/npm-rebuild.md
+++ b/deps/npm/docs/content/commands/npm-rebuild.md
@@ -42,6 +42,8 @@ will be rebuilt.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-root.md b/deps/npm/docs/content/commands/npm-root.md
index 40b58e4b33..80545235fc 100644
--- a/deps/npm/docs/content/commands/npm-root.md
+++ b/deps/npm/docs/content/commands/npm-root.md
@@ -41,6 +41,8 @@ echo "Global packages installed in: ${global_node_modules}"
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/commands/npm-set-script.md b/deps/npm/docs/content/commands/npm-set-script.md
index 0fc267f760..8695b43f14 100644
--- a/deps/npm/docs/content/commands/npm-set-script.md
+++ b/deps/npm/docs/content/commands/npm-set-script.md
@@ -7,6 +7,8 @@ description: Set tasks in the scripts section of package.json
### Synopsis
An npm command that lets you create a task in the `scripts` section of the `package.json`.
+Deprecated.
+
<!-- AUTOGENERATED USAGE DESCRIPTIONS START -->
<!-- automatically generated, do not edit manually -->
<!-- see lib/commands/set-script.js -->
diff --git a/deps/npm/docs/content/commands/npm-update.md b/deps/npm/docs/content/commands/npm-update.md
index 421d04ca3d..55aad182fc 100644
--- a/deps/npm/docs/content/commands/npm-update.md
+++ b/deps/npm/docs/content/commands/npm-update.md
@@ -188,6 +188,8 @@ Will also prevent writing to `package-lock.json` if set to `false`.
* Default: false
* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
Operates in "global" mode, so that packages are installed into the `prefix`
folder instead of the current working directory. See
diff --git a/deps/npm/docs/content/using-npm/config.md b/deps/npm/docs/content/using-npm/config.md
index a33e791bb8..12b508582a 100644
--- a/deps/npm/docs/content/using-npm/config.md
+++ b/deps/npm/docs/content/using-npm/config.md
@@ -687,23 +687,6 @@ results in no commit being made at all.
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
-#### `global`
-
-* Default: false
-* Type: Boolean
-
-Operates in "global" mode, so that packages are installed into the `prefix`
-folder instead of the current working directory. See
-[folders](/configuring-npm/folders) for more on the differences in behavior.
-
-* packages are installed into the `{prefix}/lib/node_modules` folder, instead
- of the current working directory.
-* bin files are linked to `{prefix}/bin`
-* man pages are linked to `{prefix}/share/man`
-
-<!-- automatically generated, do not edit manually -->
-<!-- see lib/utils/config/definitions.js -->
-
#### `global-style`
* Default: false
@@ -1001,6 +984,15 @@ npm registry. Must be IPv4 in versions of Node prior to 0.12.
When passed to `npm config` this refers to which config file to use.
+When set to "global" mode, packages are installed into the `prefix` folder
+instead of the current working directory. See
+[folders](/configuring-npm/folders) for more on the differences in behavior.
+
+* packages are installed into the `{prefix}/lib/node_modules` folder, instead
+ of the current working directory.
+* bin files are linked to `{prefix}/bin`
+* man pages are linked to `{prefix}/share/man`
+
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
@@ -1941,6 +1933,25 @@ Alias for `--include=dev`.
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
+#### `global`
+
+* Default: false
+* Type: Boolean
+* DEPRECATED: `--global`, `--local` are deprecated. Use `--location=global`
+ instead.
+
+Operates in "global" mode, so that packages are installed into the `prefix`
+folder instead of the current working directory. See
+[folders](/configuring-npm/folders) for more on the differences in behavior.
+
+* packages are installed into the `{prefix}/lib/node_modules` folder, instead
+ of the current working directory.
+* bin files are linked to `{prefix}/bin`
+* man pages are linked to `{prefix}/share/man`
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+
#### `init.author.email`
* Default: ""
diff --git a/deps/npm/docs/output/commands/npm-bin.html b/deps/npm/docs/output/commands/npm-bin.html
index 5961ea7e50..7b957b6014 100644
--- a/deps/npm/docs/output/commands/npm-bin.html
+++ b/deps/npm/docs/output/commands/npm-bin.html
@@ -165,6 +165,8 @@ npm command-line interface
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-ci.html b/deps/npm/docs/output/commands/npm-ci.html
index 713f7b0c81..4f9a194ae5 100644
--- a/deps/npm/docs/output/commands/npm-ci.html
+++ b/deps/npm/docs/output/commands/npm-ci.html
@@ -137,7 +137,7 @@ npm command-line interface
<section id="content">
<header class="title">
<h1 id="npm-ci">npm-ci</h1>
-<span class="description">Install a project with a clean slate</span>
+<span class="description">Clean install a project</span>
</header>
<section id="table_of_contents">
@@ -161,12 +161,7 @@ aliases: clean-install, ic, install-clean, isntall-clean
it's meant to be used in automated environments such as test platforms,
continuous integration, and deployment -- or any situation where you want
to make sure you're doing a clean install of your dependencies.</p>
-<p><code>npm ci</code> will be significantly faster when:</p>
-<ul>
-<li>There is a <code>package-lock.json</code> or <code>npm-shrinkwrap.json</code> file.</li>
-<li>The <code>node_modules</code> folder is missing or empty.</li>
-</ul>
-<p>In short, the main differences between using <code>npm install</code> and <code>npm ci</code> are:</p>
+<p>The main differences between using <code>npm install</code> and <code>npm ci</code> are:</p>
<ul>
<li>The project <strong>must</strong> have an existing <code>package-lock.json</code> or
<code>npm-shrinkwrap.json</code>.</li>
diff --git a/deps/npm/docs/output/commands/npm-config.html b/deps/npm/docs/output/commands/npm-config.html
index f8b279756d..e267531fc0 100644
--- a/deps/npm/docs/output/commands/npm-config.html
+++ b/deps/npm/docs/output/commands/npm-config.html
@@ -223,6 +223,8 @@ saving them to your <code>package.json</code>.</li>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
@@ -251,6 +253,15 @@ to "global"</li>
<li>Type: "global", "user", or "project"</li>
</ul>
<p>When passed to <code>npm config</code> this refers to which config file to use.</p>
+<p>When set to "global" mode, packages are installed into the <code>prefix</code> folder
+instead of the current working directory. See
+<a href="../configuring-npm/folders.html">folders</a> for more on the differences in behavior.</p>
+<ul>
+<li>packages are installed into the <code>{prefix}/lib/node_modules</code> folder, instead
+of the current working directory.</li>
+<li>bin files are linked to <code>{prefix}/bin</code></li>
+<li>man pages are linked to <code>{prefix}/share/man</code></li>
+</ul>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h4 id="long"><code>long</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-diff.html b/deps/npm/docs/output/commands/npm-diff.html
index 13ed989c46..7ee9d76d22 100644
--- a/deps/npm/docs/output/commands/npm-diff.html
+++ b/deps/npm/docs/output/commands/npm-diff.html
@@ -334,6 +334,8 @@ located within the folder <code>./lib/</code> and changed lines of code within t
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-install-test.html b/deps/npm/docs/output/commands/npm-install-test.html
index 6306ceb593..fce049dc2c 100644
--- a/deps/npm/docs/output/commands/npm-install-test.html
+++ b/deps/npm/docs/output/commands/npm-install-test.html
@@ -196,6 +196,8 @@ rather than using npm's default semver range operator.</p>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-install.html b/deps/npm/docs/output/commands/npm-install.html
index 509702b5bd..ca6ca1ee26 100644
--- a/deps/npm/docs/output/commands/npm-install.html
+++ b/deps/npm/docs/output/commands/npm-install.html
@@ -522,6 +522,8 @@ rather than using npm's default semver range operator.</p>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-link.html b/deps/npm/docs/output/commands/npm-link.html
index f7d5f66a9e..cb43c0478d 100644
--- a/deps/npm/docs/output/commands/npm-link.html
+++ b/deps/npm/docs/output/commands/npm-link.html
@@ -251,6 +251,8 @@ rather than using npm's default semver range operator.</p>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html
index 579b54a388..10caff53c3 100644
--- a/deps/npm/docs/output/commands/npm-ls.html
+++ b/deps/npm/docs/output/commands/npm-ls.html
@@ -166,7 +166,7 @@ tree at all, use <a href="../commands/npm-explain.html"><code>npm explain</code>
the results to only the paths to the packages named. Note that nested
packages will <em>also</em> show the paths to the specified packages. For
example, running <code>npm ls promzard</code> in npm's source tree will show:</p>
-<pre lang="bash"><code>npm@8.10.0 /path/to/npm
+<pre lang="bash"><code>npm@8.11.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
</code></pre>
@@ -246,6 +246,8 @@ saving them to your <code>package.json</code>.</li>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-outdated.html b/deps/npm/docs/output/commands/npm-outdated.html
index 0bdb9f9a66..15030d6008 100644
--- a/deps/npm/docs/output/commands/npm-outdated.html
+++ b/deps/npm/docs/output/commands/npm-outdated.html
@@ -268,6 +268,8 @@ saving them to your <code>package.json</code>.</li>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-prefix.html b/deps/npm/docs/output/commands/npm-prefix.html
index 2f30214426..df6960ef97 100644
--- a/deps/npm/docs/output/commands/npm-prefix.html
+++ b/deps/npm/docs/output/commands/npm-prefix.html
@@ -176,6 +176,8 @@ also specified.</p>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-rebuild.html b/deps/npm/docs/output/commands/npm-rebuild.html
index f4524f1a4f..84837a3be5 100644
--- a/deps/npm/docs/output/commands/npm-rebuild.html
+++ b/deps/npm/docs/output/commands/npm-rebuild.html
@@ -173,6 +173,8 @@ will be rebuilt.</p>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-root.html b/deps/npm/docs/output/commands/npm-root.html
index e0595fd8e7..c9cc1d4b67 100644
--- a/deps/npm/docs/output/commands/npm-root.html
+++ b/deps/npm/docs/output/commands/npm-root.html
@@ -170,6 +170,8 @@ echo "Global packages installed in: ${global_node_modules}"
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm-set-script.html b/deps/npm/docs/output/commands/npm-set-script.html
index 51b29d87fa..d9bc6b6077 100644
--- a/deps/npm/docs/output/commands/npm-set-script.html
+++ b/deps/npm/docs/output/commands/npm-set-script.html
@@ -147,6 +147,7 @@ npm command-line interface
<div id="_content"><h3 id="synopsis">Synopsis</h3>
<p>An npm command that lets you create a task in the <code>scripts</code> section of the <code>package.json</code>.</p>
+<p>Deprecated.</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
diff --git a/deps/npm/docs/output/commands/npm-update.html b/deps/npm/docs/output/commands/npm-update.html
index d88ea8578b..d0cb6d5f75 100644
--- a/deps/npm/docs/output/commands/npm-update.html
+++ b/deps/npm/docs/output/commands/npm-update.html
@@ -275,6 +275,8 @@ be <em>downgraded</em>.</p>
<ul>
<li>Default: false</li>
<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
</ul>
<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
folder instead of the current working directory. See
diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html
index 4a816cc1a9..99c109c4e2 100644
--- a/deps/npm/docs/output/commands/npm.html
+++ b/deps/npm/docs/output/commands/npm.html
@@ -149,7 +149,7 @@ npm command-line interface
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h3 id="version">Version</h3>
-<p>8.10.0</p>
+<p>8.11.0</p>
<h3 id="description">Description</h3>
<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
diff --git a/deps/npm/docs/output/using-npm/config.html b/deps/npm/docs/output/using-npm/config.html
index d00c7654e1..ef033b8693 100644
--- a/deps/npm/docs/output/using-npm/config.html
+++ b/deps/npm/docs/output/using-npm/config.html
@@ -142,7 +142,7 @@ npm command-line interface
<section id="table_of_contents">
<h2 id="table-of-contents">Table of contents</h2>
-<div id="_table_of_contents"><ul><li><a href="#description">Description</a></li><ul><li><a href="#command-line-flags">Command Line Flags</a></li><li><a href="#environment-variables">Environment Variables</a></li><li><a href="#npmrc-files">npmrc Files</a></li><li><a href="#default-configs">Default Configs</a></li></ul><li><a href="#shorthands-and-other-cli-niceties">Shorthands and Other CLI Niceties</a></li><li><a href="#config-settings">Config Settings</a></li><ul><li><a href="#auth"><code>_auth</code></a></li><li><a href="#access"><code>access</code></a></li><li><a href="#all"><code>all</code></a></li><li><a href="#allow-same-version"><code>allow-same-version</code></a></li><li><a href="#audit"><code>audit</code></a></li><li><a href="#audit-level"><code>audit-level</code></a></li><li><a href="#before"><code>before</code></a></li><li><a href="#bin-links"><code>bin-links</code></a></li><li><a href="#browser"><code>browser</code></a></li><li><a href="#ca"><code>ca</code></a></li><li><a href="#cache"><code>cache</code></a></li><li><a href="#cafile"><code>cafile</code></a></li><li><a href="#call"><code>call</code></a></li><li><a href="#cert"><code>cert</code></a></li><li><a href="#ci-name"><code>ci-name</code></a></li><li><a href="#cidr"><code>cidr</code></a></li><li><a href="#color"><code>color</code></a></li><li><a href="#commit-hooks"><code>commit-hooks</code></a></li><li><a href="#depth"><code>depth</code></a></li><li><a href="#description2"><code>description</code></a></li><li><a href="#diff"><code>diff</code></a></li><li><a href="#diff-dst-prefix"><code>diff-dst-prefix</code></a></li><li><a href="#diff-ignore-all-space"><code>diff-ignore-all-space</code></a></li><li><a href="#diff-name-only"><code>diff-name-only</code></a></li><li><a href="#diff-no-prefix"><code>diff-no-prefix</code></a></li><li><a href="#diff-src-prefix"><code>diff-src-prefix</code></a></li><li><a href="#diff-text"><code>diff-text</code></a></li><li><a href="#diff-unified"><code>diff-unified</code></a></li><li><a href="#dry-run"><code>dry-run</code></a></li><li><a href="#editor"><code>editor</code></a></li><li><a href="#engine-strict"><code>engine-strict</code></a></li><li><a href="#fetch-retries"><code>fetch-retries</code></a></li><li><a href="#fetch-retry-factor"><code>fetch-retry-factor</code></a></li><li><a href="#fetch-retry-maxtimeout"><code>fetch-retry-maxtimeout</code></a></li><li><a href="#fetch-retry-mintimeout"><code>fetch-retry-mintimeout</code></a></li><li><a href="#fetch-timeout"><code>fetch-timeout</code></a></li><li><a href="#force"><code>force</code></a></li><li><a href="#foreground-scripts"><code>foreground-scripts</code></a></li><li><a href="#format-package-lock"><code>format-package-lock</code></a></li><li><a href="#fund"><code>fund</code></a></li><li><a href="#git"><code>git</code></a></li><li><a href="#git-tag-version"><code>git-tag-version</code></a></li><li><a href="#global"><code>global</code></a></li><li><a href="#global-style"><code>global-style</code></a></li><li><a href="#globalconfig"><code>globalconfig</code></a></li><li><a href="#heading"><code>heading</code></a></li><li><a href="#https-proxy"><code>https-proxy</code></a></li><li><a href="#if-present"><code>if-present</code></a></li><li><a href="#ignore-scripts"><code>ignore-scripts</code></a></li><li><a href="#include"><code>include</code></a></li><li><a href="#include-staged"><code>include-staged</code></a></li><li><a href="#include-workspace-root"><code>include-workspace-root</code></a></li><li><a href="#init-author-email"><code>init-author-email</code></a></li><li><a href="#init-author-name"><code>init-author-name</code></a></li><li><a href="#init-author-url"><code>init-author-url</code></a></li><li><a href="#init-license"><code>init-license</code></a></li><li><a href="#init-module"><code>init-module</code></a></li><li><a href="#init-version"><code>init-version</code></a></li><li><a href="#install-links"><code>install-links</code></a></li><li><a href="#json"><code>json</code></a></li><li><a href="#key"><code>key</code></a></li><li><a href="#legacy-bundling"><code>legacy-bundling</code></a></li><li><a href="#legacy-peer-deps"><code>legacy-peer-deps</code></a></li><li><a href="#link"><code>link</code></a></li><li><a href="#local-address"><code>local-address</code></a></li><li><a href="#location"><code>location</code></a></li><li><a href="#lockfile-version"><code>lockfile-version</code></a></li><li><a href="#loglevel"><code>loglevel</code></a></li><li><a href="#logs-dir"><code>logs-dir</code></a></li><li><a href="#logs-max"><code>logs-max</code></a></li><li><a href="#long"><code>long</code></a></li><li><a href="#maxsockets"><code>maxsockets</code></a></li><li><a href="#message"><code>message</code></a></li><li><a href="#node-options"><code>node-options</code></a></li><li><a href="#node-version"><code>node-version</code></a></li><li><a href="#noproxy"><code>noproxy</code></a></li><li><a href="#npm-version"><code>npm-version</code></a></li><li><a href="#offline"><code>offline</code></a></li><li><a href="#omit"><code>omit</code></a></li><li><a href="#omit-lockfile-registry-resolved"><code>omit-lockfile-registry-resolved</code></a></li><li><a href="#otp"><code>otp</code></a></li><li><a href="#pack-destination"><code>pack-destination</code></a></li><li><a href="#package"><code>package</code></a></li><li><a href="#package-lock"><code>package-lock</code></a></li><li><a href="#package-lock-only"><code>package-lock-only</code></a></li><li><a href="#parseable"><code>parseable</code></a></li><li><a href="#prefer-offline"><code>prefer-offline</code></a></li><li><a href="#prefer-online"><code>prefer-online</code></a></li><li><a href="#prefix"><code>prefix</code></a></li><li><a href="#preid"><code>preid</code></a></li><li><a href="#progress"><code>progress</code></a></li><li><a href="#proxy"><code>proxy</code></a></li><li><a href="#read-only"><code>read-only</code></a></li><li><a href="#rebuild-bundle"><code>rebuild-bundle</code></a></li><li><a href="#registry"><code>registry</code></a></li><li><a href="#save"><code>save</code></a></li><li><a href="#save-bundle"><code>save-bundle</code></a></li><li><a href="#save-dev"><code>save-dev</code></a></li><li><a href="#save-exact"><code>save-exact</code></a></li><li><a href="#save-optional"><code>save-optional</code></a></li><li><a href="#save-peer"><code>save-peer</code></a></li><li><a href="#save-prefix"><code>save-prefix</code></a></li><li><a href="#save-prod"><code>save-prod</code></a></li><li><a href="#scope"><code>scope</code></a></li><li><a href="#script-shell"><code>script-shell</code></a></li><li><a href="#searchexclude"><code>searchexclude</code></a></li><li><a href="#searchlimit"><code>searchlimit</code></a></li><li><a href="#searchopts"><code>searchopts</code></a></li><li><a href="#searchstaleness"><code>searchstaleness</code></a></li><li><a href="#shell"><code>shell</code></a></li><li><a href="#sign-git-commit"><code>sign-git-commit</code></a></li><li><a href="#sign-git-tag"><code>sign-git-tag</code></a></li><li><a href="#strict-peer-deps"><code>strict-peer-deps</code></a></li><li><a href="#strict-ssl"><code>strict-ssl</code></a></li><li><a href="#tag"><code>tag</code></a></li><li><a href="#tag-version-prefix"><code>tag-version-prefix</code></a></li><li><a href="#timing"><code>timing</code></a></li><li><a href="#umask"><code>umask</code></a></li><li><a href="#unicode"><code>unicode</code></a></li><li><a href="#update-notifier"><code>update-notifier</code></a></li><li><a href="#usage"><code>usage</code></a></li><li><a href="#user-agent"><code>user-agent</code></a></li><li><a href="#userconfig"><code>userconfig</code></a></li><li><a href="#version"><code>version</code></a></li><li><a href="#versions"><code>versions</code></a></li><li><a href="#viewer"><code>viewer</code></a></li><li><a href="#which"><code>which</code></a></li><li><a href="#workspace"><code>workspace</code></a></li><li><a href="#workspaces"><code>workspaces</code></a></li><li><a href="#workspaces-update"><code>workspaces-update</code></a></li><li><a href="#yes"><code>yes</code></a></li><li><a href="#also"><code>also</code></a></li><li><a href="#auth-type"><code>auth-type</code></a></li><li><a href="#cache-max"><code>cache-max</code></a></li><li><a href="#cache-min"><code>cache-min</code></a></li><li><a href="#dev"><code>dev</code></a></li><li><a href="#initauthoremail"><code>init.author.email</code></a></li><li><a href="#initauthorname"><code>init.author.name</code></a></li><li><a href="#initauthorurl"><code>init.author.url</code></a></li><li><a href="#initlicense"><code>init.license</code></a></li><li><a href="#initmodule"><code>init.module</code></a></li><li><a href="#initversion"><code>init.version</code></a></li><li><a href="#only"><code>only</code></a></li><li><a href="#optional"><code>optional</code></a></li><li><a href="#production"><code>production</code></a></li><li><a href="#shrinkwrap"><code>shrinkwrap</code></a></li><li><a href="#sso-poll-frequency"><code>sso-poll-frequency</code></a></li><li><a href="#sso-type"><code>sso-type</code></a></li><li><a href="#tmp"><code>tmp</code></a></li></ul><li><a href="#see-also">See also</a></li></ul></div>
+<div id="_table_of_contents"><ul><li><a href="#description">Description</a></li><ul><li><a href="#command-line-flags">Command Line Flags</a></li><li><a href="#environment-variables">Environment Variables</a></li><li><a href="#npmrc-files">npmrc Files</a></li><li><a href="#default-configs">Default Configs</a></li></ul><li><a href="#shorthands-and-other-cli-niceties">Shorthands and Other CLI Niceties</a></li><li><a href="#config-settings">Config Settings</a></li><ul><li><a href="#auth"><code>_auth</code></a></li><li><a href="#access"><code>access</code></a></li><li><a href="#all"><code>all</code></a></li><li><a href="#allow-same-version"><code>allow-same-version</code></a></li><li><a href="#audit"><code>audit</code></a></li><li><a href="#audit-level"><code>audit-level</code></a></li><li><a href="#before"><code>before</code></a></li><li><a href="#bin-links"><code>bin-links</code></a></li><li><a href="#browser"><code>browser</code></a></li><li><a href="#ca"><code>ca</code></a></li><li><a href="#cache"><code>cache</code></a></li><li><a href="#cafile"><code>cafile</code></a></li><li><a href="#call"><code>call</code></a></li><li><a href="#cert"><code>cert</code></a></li><li><a href="#ci-name"><code>ci-name</code></a></li><li><a href="#cidr"><code>cidr</code></a></li><li><a href="#color"><code>color</code></a></li><li><a href="#commit-hooks"><code>commit-hooks</code></a></li><li><a href="#depth"><code>depth</code></a></li><li><a href="#description2"><code>description</code></a></li><li><a href="#diff"><code>diff</code></a></li><li><a href="#diff-dst-prefix"><code>diff-dst-prefix</code></a></li><li><a href="#diff-ignore-all-space"><code>diff-ignore-all-space</code></a></li><li><a href="#diff-name-only"><code>diff-name-only</code></a></li><li><a href="#diff-no-prefix"><code>diff-no-prefix</code></a></li><li><a href="#diff-src-prefix"><code>diff-src-prefix</code></a></li><li><a href="#diff-text"><code>diff-text</code></a></li><li><a href="#diff-unified"><code>diff-unified</code></a></li><li><a href="#dry-run"><code>dry-run</code></a></li><li><a href="#editor"><code>editor</code></a></li><li><a href="#engine-strict"><code>engine-strict</code></a></li><li><a href="#fetch-retries"><code>fetch-retries</code></a></li><li><a href="#fetch-retry-factor"><code>fetch-retry-factor</code></a></li><li><a href="#fetch-retry-maxtimeout"><code>fetch-retry-maxtimeout</code></a></li><li><a href="#fetch-retry-mintimeout"><code>fetch-retry-mintimeout</code></a></li><li><a href="#fetch-timeout"><code>fetch-timeout</code></a></li><li><a href="#force"><code>force</code></a></li><li><a href="#foreground-scripts"><code>foreground-scripts</code></a></li><li><a href="#format-package-lock"><code>format-package-lock</code></a></li><li><a href="#fund"><code>fund</code></a></li><li><a href="#git"><code>git</code></a></li><li><a href="#git-tag-version"><code>git-tag-version</code></a></li><li><a href="#global-style"><code>global-style</code></a></li><li><a href="#globalconfig"><code>globalconfig</code></a></li><li><a href="#heading"><code>heading</code></a></li><li><a href="#https-proxy"><code>https-proxy</code></a></li><li><a href="#if-present"><code>if-present</code></a></li><li><a href="#ignore-scripts"><code>ignore-scripts</code></a></li><li><a href="#include"><code>include</code></a></li><li><a href="#include-staged"><code>include-staged</code></a></li><li><a href="#include-workspace-root"><code>include-workspace-root</code></a></li><li><a href="#init-author-email"><code>init-author-email</code></a></li><li><a href="#init-author-name"><code>init-author-name</code></a></li><li><a href="#init-author-url"><code>init-author-url</code></a></li><li><a href="#init-license"><code>init-license</code></a></li><li><a href="#init-module"><code>init-module</code></a></li><li><a href="#init-version"><code>init-version</code></a></li><li><a href="#install-links"><code>install-links</code></a></li><li><a href="#json"><code>json</code></a></li><li><a href="#key"><code>key</code></a></li><li><a href="#legacy-bundling"><code>legacy-bundling</code></a></li><li><a href="#legacy-peer-deps"><code>legacy-peer-deps</code></a></li><li><a href="#link"><code>link</code></a></li><li><a href="#local-address"><code>local-address</code></a></li><li><a href="#location"><code>location</code></a></li><li><a href="#lockfile-version"><code>lockfile-version</code></a></li><li><a href="#loglevel"><code>loglevel</code></a></li><li><a href="#logs-dir"><code>logs-dir</code></a></li><li><a href="#logs-max"><code>logs-max</code></a></li><li><a href="#long"><code>long</code></a></li><li><a href="#maxsockets"><code>maxsockets</code></a></li><li><a href="#message"><code>message</code></a></li><li><a href="#node-options"><code>node-options</code></a></li><li><a href="#node-version"><code>node-version</code></a></li><li><a href="#noproxy"><code>noproxy</code></a></li><li><a href="#npm-version"><code>npm-version</code></a></li><li><a href="#offline"><code>offline</code></a></li><li><a href="#omit"><code>omit</code></a></li><li><a href="#omit-lockfile-registry-resolved"><code>omit-lockfile-registry-resolved</code></a></li><li><a href="#otp"><code>otp</code></a></li><li><a href="#pack-destination"><code>pack-destination</code></a></li><li><a href="#package"><code>package</code></a></li><li><a href="#package-lock"><code>package-lock</code></a></li><li><a href="#package-lock-only"><code>package-lock-only</code></a></li><li><a href="#parseable"><code>parseable</code></a></li><li><a href="#prefer-offline"><code>prefer-offline</code></a></li><li><a href="#prefer-online"><code>prefer-online</code></a></li><li><a href="#prefix"><code>prefix</code></a></li><li><a href="#preid"><code>preid</code></a></li><li><a href="#progress"><code>progress</code></a></li><li><a href="#proxy"><code>proxy</code></a></li><li><a href="#read-only"><code>read-only</code></a></li><li><a href="#rebuild-bundle"><code>rebuild-bundle</code></a></li><li><a href="#registry"><code>registry</code></a></li><li><a href="#save"><code>save</code></a></li><li><a href="#save-bundle"><code>save-bundle</code></a></li><li><a href="#save-dev"><code>save-dev</code></a></li><li><a href="#save-exact"><code>save-exact</code></a></li><li><a href="#save-optional"><code>save-optional</code></a></li><li><a href="#save-peer"><code>save-peer</code></a></li><li><a href="#save-prefix"><code>save-prefix</code></a></li><li><a href="#save-prod"><code>save-prod</code></a></li><li><a href="#scope"><code>scope</code></a></li><li><a href="#script-shell"><code>script-shell</code></a></li><li><a href="#searchexclude"><code>searchexclude</code></a></li><li><a href="#searchlimit"><code>searchlimit</code></a></li><li><a href="#searchopts"><code>searchopts</code></a></li><li><a href="#searchstaleness"><code>searchstaleness</code></a></li><li><a href="#shell"><code>shell</code></a></li><li><a href="#sign-git-commit"><code>sign-git-commit</code></a></li><li><a href="#sign-git-tag"><code>sign-git-tag</code></a></li><li><a href="#strict-peer-deps"><code>strict-peer-deps</code></a></li><li><a href="#strict-ssl"><code>strict-ssl</code></a></li><li><a href="#tag"><code>tag</code></a></li><li><a href="#tag-version-prefix"><code>tag-version-prefix</code></a></li><li><a href="#timing"><code>timing</code></a></li><li><a href="#umask"><code>umask</code></a></li><li><a href="#unicode"><code>unicode</code></a></li><li><a href="#update-notifier"><code>update-notifier</code></a></li><li><a href="#usage"><code>usage</code></a></li><li><a href="#user-agent"><code>user-agent</code></a></li><li><a href="#userconfig"><code>userconfig</code></a></li><li><a href="#version"><code>version</code></a></li><li><a href="#versions"><code>versions</code></a></li><li><a href="#viewer"><code>viewer</code></a></li><li><a href="#which"><code>which</code></a></li><li><a href="#workspace"><code>workspace</code></a></li><li><a href="#workspaces"><code>workspaces</code></a></li><li><a href="#workspaces-update"><code>workspaces-update</code></a></li><li><a href="#yes"><code>yes</code></a></li><li><a href="#also"><code>also</code></a></li><li><a href="#auth-type"><code>auth-type</code></a></li><li><a href="#cache-max"><code>cache-max</code></a></li><li><a href="#cache-min"><code>cache-min</code></a></li><li><a href="#dev"><code>dev</code></a></li><li><a href="#global"><code>global</code></a></li><li><a href="#initauthoremail"><code>init.author.email</code></a></li><li><a href="#initauthorname"><code>init.author.name</code></a></li><li><a href="#initauthorurl"><code>init.author.url</code></a></li><li><a href="#initlicense"><code>init.license</code></a></li><li><a href="#initmodule"><code>init.module</code></a></li><li><a href="#initversion"><code>init.version</code></a></li><li><a href="#only"><code>only</code></a></li><li><a href="#optional"><code>optional</code></a></li><li><a href="#production"><code>production</code></a></li><li><a href="#shrinkwrap"><code>shrinkwrap</code></a></li><li><a href="#sso-poll-frequency"><code>sso-poll-frequency</code></a></li><li><a href="#sso-type"><code>sso-type</code></a></li><li><a href="#tmp"><code>tmp</code></a></li></ul><li><a href="#see-also">See also</a></li></ul></div>
</section>
<div id="_content"><h3 id="description">Description</h3>
@@ -696,22 +696,6 @@ but is not in the <code>PATH</code>, then set this to the full path to the git b
results in no commit being made at all.</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
-<h4 id="global"><code>global</code></h4>
-<ul>
-<li>Default: false</li>
-<li>Type: Boolean</li>
-</ul>
-<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
-folder instead of the current working directory. See
-<a href="../configuring-npm/folders.html">folders</a> for more on the differences in behavior.</p>
-<ul>
-<li>packages are installed into the <code>{prefix}/lib/node_modules</code> folder, instead
-of the current working directory.</li>
-<li>bin files are linked to <code>{prefix}/bin</code></li>
-<li>man pages are linked to <code>{prefix}/share/man</code></li>
-</ul>
-<!-- raw HTML omitted -->
-<!-- raw HTML omitted -->
<h4 id="global-style"><code>global-style</code></h4>
<ul>
<li>Default: false</li>
@@ -951,6 +935,15 @@ to "global"</li>
<li>Type: "global", "user", or "project"</li>
</ul>
<p>When passed to <code>npm config</code> this refers to which config file to use.</p>
+<p>When set to "global" mode, packages are installed into the <code>prefix</code> folder
+instead of the current working directory. See
+<a href="../configuring-npm/folders.html">folders</a> for more on the differences in behavior.</p>
+<ul>
+<li>packages are installed into the <code>{prefix}/lib/node_modules</code> folder, instead
+of the current working directory.</li>
+<li>bin files are linked to <code>{prefix}/bin</code></li>
+<li>man pages are linked to <code>{prefix}/share/man</code></li>
+</ul>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h4 id="lockfile-version"><code>lockfile-version</code></h4>
@@ -1701,6 +1694,24 @@ in a future version of npm in favor of web-based login.</li>
<p>Alias for <code>--include=dev</code>.</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
+<h4 id="global"><code>global</code></h4>
+<ul>
+<li>Default: false</li>
+<li>Type: Boolean</li>
+<li>DEPRECATED: <code>--global</code>, <code>--local</code> are deprecated. Use <code>--location=global</code>
+instead.</li>
+</ul>
+<p>Operates in "global" mode, so that packages are installed into the <code>prefix</code>
+folder instead of the current working directory. See
+<a href="../configuring-npm/folders.html">folders</a> for more on the differences in behavior.</p>
+<ul>
+<li>packages are installed into the <code>{prefix}/lib/node_modules</code> folder, instead
+of the current working directory.</li>
+<li>bin files are linked to <code>{prefix}/bin</code></li>
+<li>man pages are linked to <code>{prefix}/share/man</code></li>
+</ul>
+<!-- raw HTML omitted -->
+<!-- raw HTML omitted -->
<h4 id="initauthoremail"><code>init.author.email</code></h4>
<ul>
<li>Default: ""</li>
diff --git a/deps/npm/lib/commands/bin.js b/deps/npm/lib/commands/bin.js
index 4200d5b8ca..9ba3cb4003 100644
--- a/deps/npm/lib/commands/bin.js
+++ b/deps/npm/lib/commands/bin.js
@@ -15,7 +15,7 @@ class Bin extends BaseCommand {
async exec (args) {
const b = this.npm.bin
this.npm.output(b)
- if (this.npm.config.get('global') && !path.split(delimiter).includes(b)) {
+ if (this.npm.global && !path.split(delimiter).includes(b)) {
log.error('bin', '(not in PATH env variable)')
}
}
diff --git a/deps/npm/lib/commands/birthday.js b/deps/npm/lib/commands/birthday.js
index c7b5b31c54..cdd6db6286 100644
--- a/deps/npm/lib/commands/birthday.js
+++ b/deps/npm/lib/commands/birthday.js
@@ -1,13 +1,15 @@
const BaseCommand = require('../base-command.js')
+const log = require('../utils/log-shim')
class Birthday extends BaseCommand {
static name = 'birthday'
- static description = 'Birthday'
+ static description = 'Birthday, deprecated'
static ignoreImplicitWorkspace = true
static isShellout = true
async exec () {
this.npm.config.set('yes', true)
+ log.warn('birthday', 'birthday is deprecated and will be removed in a future release')
return this.npm.exec('exec', ['@npmcli/npm-birthday'])
}
}
diff --git a/deps/npm/lib/commands/cache.js b/deps/npm/lib/commands/cache.js
index 634c8dbb42..862f346adb 100644
--- a/deps/npm/lib/commands/cache.js
+++ b/deps/npm/lib/commands/cache.js
@@ -10,11 +10,7 @@ const jsonParse = require('json-parse-even-better-errors')
const localeCompare = require('@isaacs/string-locale-compare')('en')
const log = require('../utils/log-shim')
-const searchCachePackage = async (path, spec, cacheKeys) => {
- const parsed = npa(spec)
- if (parsed.rawSpec !== '' && parsed.type === 'tag') {
- throw new Error(`Cannot list cache keys for a tagged package.`)
- }
+const searchCachePackage = async (path, parsed, cacheKeys) => {
/* eslint-disable-next-line max-len */
const searchMFH = new RegExp(`^make-fetch-happen:request-cache:.*(?<!/[@a-zA-Z]+)/${parsed.name}/-/(${parsed.name}[^/]+.tgz)$`)
const searchPack = new RegExp(`^make-fetch-happen:request-cache:.*/${parsed.escapedName}$`)
@@ -50,6 +46,7 @@ const searchCachePackage = async (path, spec, cacheKeys) => {
if (!packument.versions || typeof packument.versions !== 'object') {
continue
}
+
// assuming this is a packument
for (const ver of Object.keys(packument.versions)) {
if (semver.satisfies(ver, parsed.rawSpec)) {
@@ -148,6 +145,7 @@ class Cache extends BaseCommand {
}
this.npm.output(`Deleted: ${key}`)
await cacache.rm.entry(cachePath, key)
+ // XXX this could leave other entries without content!
await cacache.rm.content(cachePath, entry.integrity)
}
}
@@ -204,7 +202,11 @@ class Cache extends BaseCommand {
// get results for each package spec specified
const results = new Set()
for (const spec of specs) {
- const keySet = await searchCachePackage(cachePath, spec, cacheKeys)
+ const parsed = npa(spec)
+ if (parsed.rawSpec !== '' && parsed.type === 'tag') {
+ throw this.usageError('Cannot list cache keys for a tagged package.')
+ }
+ const keySet = await searchCachePackage(cachePath, parsed, cacheKeys)
for (const key of keySet) {
results.add(key)
}
diff --git a/deps/npm/lib/commands/ci.js b/deps/npm/lib/commands/ci.js
index eb1e02bcdc..2a6125d564 100644
--- a/deps/npm/lib/commands/ci.js
+++ b/deps/npm/lib/commands/ci.js
@@ -8,19 +8,10 @@ const readdir = util.promisify(fs.readdir)
const log = require('../utils/log-shim.js')
const validateLockfile = require('../utils/validate-lockfile.js')
-const removeNodeModules = async where => {
- const rimrafOpts = { glob: false }
- process.emit('time', 'npm-ci:rm')
- const path = `${where}/node_modules`
- // get the list of entries so we can skip the glob for performance
- const entries = await readdir(path, null).catch(er => [])
- await Promise.all(entries.map(f => rimraf(`${path}/${f}`, rimrafOpts)))
- process.emit('timeEnd', 'npm-ci:rm')
-}
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
class CI extends ArboristWorkspaceCmd {
- static description = 'Install a project with a clean slate'
+ static description = 'Clean install a project'
static name = 'ci'
static params = [
'audit',
@@ -30,10 +21,10 @@ class CI extends ArboristWorkspaceCmd {
]
async exec () {
- if (this.npm.config.get('global')) {
- const err = new Error('`npm ci` does not work for global packages')
- err.code = 'ECIGLOBAL'
- throw err
+ if (this.npm.global) {
+ throw Object.assign(new Error('`npm ci` does not work for global packages'), {
+ code: 'ECIGLOBAL',
+ })
}
const where = this.npm.prefix
@@ -46,17 +37,14 @@ class CI extends ArboristWorkspaceCmd {
}
const arb = new Arborist(opts)
- await Promise.all([
- arb.loadVirtual().catch(er => {
- log.verbose('loadVirtual', er.stack)
- const msg =
- 'The `npm ci` command can only install with an existing package-lock.json or\n' +
- 'npm-shrinkwrap.json with lockfileVersion >= 1. Run an install with npm@5 or\n' +
- 'later to generate a package-lock.json file, then try again.'
- throw new Error(msg)
- }),
- removeNodeModules(where),
- ])
+ await arb.loadVirtual().catch(er => {
+ log.verbose('loadVirtual', er.stack)
+ const msg =
+ 'The `npm ci` command can only install with an existing package-lock.json or\n' +
+ 'npm-shrinkwrap.json with lockfileVersion >= 1. Run an install with npm@5 or\n' +
+ 'later to generate a package-lock.json file, then try again.'
+ throw this.usageError(msg)
+ })
// retrieves inventory of packages from loaded virtual tree (lock file)
const virtualInventory = new Map(arb.virtualTree.inventory)
@@ -70,15 +58,24 @@ class CI extends ArboristWorkspaceCmd {
// throws a validation error in case of mismatches
const errors = validateLockfile(virtualInventory, arb.idealTree.inventory)
if (errors.length) {
- throw new Error(
+ throw this.usageError(
'`npm ci` can only install packages when your package.json and ' +
'package-lock.json or npm-shrinkwrap.json are in sync. Please ' +
'update your lock file with `npm install` ' +
'before continuing.\n\n' +
- errors.join('\n') + '\n'
+ errors.join('\n')
)
}
+ // Only remove node_modules after we've successfully loaded the virtual
+ // tree and validated the lockfile
+ await this.npm.time('npm-ci:rm', async () => {
+ const path = `${where}/node_modules`
+ // get the list of entries so we can skip the glob for performance
+ const entries = await readdir(path, null).catch(er => [])
+ return Promise.all(entries.map(f => rimraf(`${path}/${f}`, { glob: false })))
+ })
+
await arb.reify(opts)
const ignoreScripts = this.npm.config.get('ignore-scripts')
diff --git a/deps/npm/lib/commands/config.js b/deps/npm/lib/commands/config.js
index 0432abac39..96dd4abcaf 100644
--- a/deps/npm/lib/commands/config.js
+++ b/deps/npm/lib/commands/config.js
@@ -276,7 +276,7 @@ ${defData}
msg.push('')
}
- if (!this.npm.config.get('global')) {
+ if (!this.npm.global) {
const pkgPath = resolve(this.npm.prefix, 'package.json')
const pkg = await rpj(pkgPath).catch(() => ({}))
diff --git a/deps/npm/lib/commands/dedupe.js b/deps/npm/lib/commands/dedupe.js
index 96d1ac2ae9..2cc44b2a9f 100644
--- a/deps/npm/lib/commands/dedupe.js
+++ b/deps/npm/lib/commands/dedupe.js
@@ -22,7 +22,7 @@ class Dedupe extends ArboristWorkspaceCmd {
]
async exec (args) {
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
const er = new Error('`npm dedupe` does not work in global mode.')
er.code = 'EDEDUPEGLOBAL'
throw er
diff --git a/deps/npm/lib/commands/diff.js b/deps/npm/lib/commands/diff.js
index 11ee78265e..b8a64bd98a 100644
--- a/deps/npm/lib/commands/diff.js
+++ b/deps/npm/lib/commands/diff.js
@@ -50,7 +50,7 @@ class Diff extends BaseCommand {
// node_modules is sometimes under ./lib, and in global mode we're only ever
// walking through node_modules (because we will have been given a package
// name already)
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
this.top = resolve(this.npm.globalDir, '..')
} else {
this.top = this.prefix
diff --git a/deps/npm/lib/commands/dist-tag.js b/deps/npm/lib/commands/dist-tag.js
index 42cad80df0..a207e422cb 100644
--- a/deps/npm/lib/commands/dist-tag.js
+++ b/deps/npm/lib/commands/dist-tag.js
@@ -148,7 +148,7 @@ class DistTag extends BaseCommand {
async list (spec, opts) {
if (!spec) {
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
throw this.usageError()
}
const { name } = await readPackage(path.resolve(this.npm.prefix, 'package.json'))
diff --git a/deps/npm/lib/commands/fund.js b/deps/npm/lib/commands/fund.js
index 787a5193f0..09ca81653b 100644
--- a/deps/npm/lib/commands/fund.js
+++ b/deps/npm/lib/commands/fund.js
@@ -45,7 +45,7 @@ class Fund extends ArboristWorkspaceCmd {
throw err
}
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
const err = new Error('`npm fund` does not support global packages')
err.code = 'EFUNDGLOBAL'
throw err
diff --git a/deps/npm/lib/commands/install.js b/deps/npm/lib/commands/install.js
index d1f6d1481d..4cda364483 100644
--- a/deps/npm/lib/commands/install.js
+++ b/deps/npm/lib/commands/install.js
@@ -106,7 +106,7 @@ class Install extends ArboristWorkspaceCmd {
// the /path/to/node_modules/..
const globalTop = resolve(this.npm.globalDir, '..')
const ignoreScripts = this.npm.config.get('ignore-scripts')
- const isGlobalInstall = this.npm.config.get('global')
+ const isGlobalInstall = this.npm.global
const where = isGlobalInstall ? globalTop : this.npm.prefix
const forced = this.npm.config.get('force')
const scriptShell = this.npm.config.get('script-shell') || undefined
diff --git a/deps/npm/lib/commands/link.js b/deps/npm/lib/commands/link.js
index d656791469..80a60d36e3 100644
--- a/deps/npm/lib/commands/link.js
+++ b/deps/npm/lib/commands/link.js
@@ -43,7 +43,7 @@ class Link extends ArboristWorkspaceCmd {
}
async exec (args) {
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
throw Object.assign(
new Error(
'link should never be --global.\n' +
diff --git a/deps/npm/lib/commands/ls.js b/deps/npm/lib/commands/ls.js
index 06268fe7e0..cfd9cb5a50 100644
--- a/deps/npm/lib/commands/ls.js
+++ b/deps/npm/lib/commands/ls.js
@@ -52,7 +52,7 @@ class LS extends ArboristWorkspaceCmd {
const all = this.npm.config.get('all')
const color = this.npm.color
const depth = this.npm.config.get('depth')
- const global = this.npm.config.get('global')
+ const global = this.npm.global
const json = this.npm.config.get('json')
const link = this.npm.config.get('link')
const long = this.npm.config.get('long')
diff --git a/deps/npm/lib/commands/outdated.js b/deps/npm/lib/commands/outdated.js
index 0953c17ca1..081e75a2c6 100644
--- a/deps/npm/lib/commands/outdated.js
+++ b/deps/npm/lib/commands/outdated.js
@@ -27,7 +27,7 @@ class Outdated extends ArboristWorkspaceCmd {
async exec (args) {
const global = path.resolve(this.npm.globalDir, '..')
- const where = this.npm.config.get('global')
+ const where = this.npm.global
? global
: this.npm.prefix
@@ -140,7 +140,7 @@ class Outdated extends ArboristWorkspaceCmd {
getEdgesOut (node) {
// TODO: normalize usage of edges and avoid looping through nodes here
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
for (const child of node.children.values()) {
this.trackEdge(child)
}
@@ -166,7 +166,7 @@ class Outdated extends ArboristWorkspaceCmd {
}
getWorkspacesEdges (node) {
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
return
}
diff --git a/deps/npm/lib/commands/owner.js b/deps/npm/lib/commands/owner.js
index 9338b22a5e..4797e9c7ec 100644
--- a/deps/npm/lib/commands/owner.js
+++ b/deps/npm/lib/commands/owner.js
@@ -50,7 +50,7 @@ class Owner extends BaseCommand {
// reaches registry in order to autocomplete rm
if (argv[2] === 'rm') {
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
return []
}
const { name } = await readJson(resolve(this.npm.prefix, 'package.json'))
@@ -126,7 +126,7 @@ class Owner extends BaseCommand {
async getPkg (prefix, pkg) {
if (!pkg) {
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
throw this.usageError()
}
const { name } = await readJson(resolve(prefix, 'package.json'))
diff --git a/deps/npm/lib/commands/pack.js b/deps/npm/lib/commands/pack.js
index 41fef5cb45..8190ceecaf 100644
--- a/deps/npm/lib/commands/pack.js
+++ b/deps/npm/lib/commands/pack.js
@@ -44,7 +44,11 @@ class Pack extends BaseCommand {
// noise generated during packing
const tarballs = []
for (const { arg, manifest } of manifests) {
- const tarballData = await libpack(arg, this.npm.flatOptions)
+ const tarballData = await libpack(arg, {
+ ...this.npm.flatOptions,
+ prefix: this.npm.localPrefix,
+ workspaces: this.workspacePaths,
+ })
const pkgContents = await getContents(manifest, tarballData)
tarballs.push(pkgContents)
}
diff --git a/deps/npm/lib/commands/pkg.js b/deps/npm/lib/commands/pkg.js
index 3a8e01f65b..5fac9bfb54 100644
--- a/deps/npm/lib/commands/pkg.js
+++ b/deps/npm/lib/commands/pkg.js
@@ -29,7 +29,7 @@ class Pkg extends BaseCommand {
this.prefix = prefix
}
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
throw Object.assign(
new Error(`There's no package.json file to manage on global mode`),
{ code: 'EPKGGLOBAL' }
diff --git a/deps/npm/lib/commands/publish.js b/deps/npm/lib/commands/publish.js
index cbf0ccf4d6..da6437fa9c 100644
--- a/deps/npm/lib/commands/publish.js
+++ b/deps/npm/lib/commands/publish.js
@@ -80,7 +80,12 @@ class Publish extends BaseCommand {
}
// we pass dryRun: true to libnpmpack so it doesn't write the file to disk
- const tarballData = await pack(spec, { ...opts, dryRun: true })
+ const tarballData = await pack(spec, {
+ ...opts,
+ dryRun: true,
+ prefix: this.npm.localPrefix,
+ workspaces: this.workspacePaths,
+ })
const pkgContents = await getContents(manifest, tarballData)
// The purpose of re-reading the manifest is in case it changed,
diff --git a/deps/npm/lib/commands/rebuild.js b/deps/npm/lib/commands/rebuild.js
index 0e8a1510bd..3e6046d8df 100644
--- a/deps/npm/lib/commands/rebuild.js
+++ b/deps/npm/lib/commands/rebuild.js
@@ -26,7 +26,7 @@ class Rebuild extends ArboristWorkspaceCmd {
async exec (args) {
const globalTop = resolve(this.npm.globalDir, '..')
- const where = this.npm.config.get('global') ? globalTop : this.npm.prefix
+ const where = this.npm.global ? globalTop : this.npm.prefix
const arb = new Arborist({
...this.npm.flatOptions,
path: where,
diff --git a/deps/npm/lib/commands/set-script.js b/deps/npm/lib/commands/set-script.js
index a6b7c3a50c..a085f72a31 100644
--- a/deps/npm/lib/commands/set-script.js
+++ b/deps/npm/lib/commands/set-script.js
@@ -5,7 +5,7 @@ const log = require('../utils/log-shim')
const BaseCommand = require('../base-command.js')
class SetScript extends BaseCommand {
- static description = 'Set tasks in the scripts section of package.json'
+ static description = 'Set tasks in the scripts section of package.json, deprecated'
static params = ['workspace', 'workspaces', 'include-workspace-root']
static name = 'set-script'
static usage = ['[<script>] [<command>]']
@@ -34,6 +34,8 @@ class SetScript extends BaseCommand {
async exec (args) {
this.validate(args)
+ log.warn('set-script',
+ 'set-script is deprecated, use `npm pkg set scripts.scriptname="cmd" instead.')
const warn = await this.doSetScript(this.npm.localPrefix, args[0], args[1])
if (warn) {
log.warn('set-script', `Script "${args[0]}" was overwritten`)
diff --git a/deps/npm/lib/commands/shrinkwrap.js b/deps/npm/lib/commands/shrinkwrap.js
index 67cde15818..a240f03935 100644
--- a/deps/npm/lib/commands/shrinkwrap.js
+++ b/deps/npm/lib/commands/shrinkwrap.js
@@ -15,7 +15,7 @@ class Shrinkwrap extends BaseCommand {
//
// loadVirtual, fall back to loadActual
// rename shrinkwrap file type, and tree.meta.save()
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
const er = new Error('`npm shrinkwrap` does not work for global packages')
er.code = 'ESHRINKWRAPGLOBAL'
throw er
diff --git a/deps/npm/lib/commands/uninstall.js b/deps/npm/lib/commands/uninstall.js
index 5911818b6f..e4a193cc5c 100644
--- a/deps/npm/lib/commands/uninstall.js
+++ b/deps/npm/lib/commands/uninstall.js
@@ -21,13 +21,12 @@ class Uninstall extends ArboristWorkspaceCmd {
async exec (args) {
// the /path/to/node_modules/..
- const global = this.npm.config.get('global')
- const path = global
+ const path = this.npm.global
? resolve(this.npm.globalDir, '..')
: this.npm.localPrefix
if (!args.length) {
- if (!global) {
+ if (!this.npm.global) {
throw new Error('Must provide a package name to remove')
} else {
let pkg
diff --git a/deps/npm/lib/commands/update.js b/deps/npm/lib/commands/update.js
index c2c3502eed..ca80d61537 100644
--- a/deps/npm/lib/commands/update.js
+++ b/deps/npm/lib/commands/update.js
@@ -39,7 +39,7 @@ class Update extends ArboristWorkspaceCmd {
async exec (args) {
const update = args.length === 0 ? true : args
const global = path.resolve(this.npm.globalDir, '..')
- const where = this.npm.config.get('global')
+ const where = this.npm.global
? global
: this.npm.prefix
diff --git a/deps/npm/lib/commands/view.js b/deps/npm/lib/commands/view.js
index d78ee77dc0..efb298a03b 100644
--- a/deps/npm/lib/commands/view.js
+++ b/deps/npm/lib/commands/view.js
@@ -91,7 +91,7 @@ class View extends BaseCommand {
const local = /^\.@/.test(pkg) || pkg === '.'
if (local) {
- if (this.npm.config.get('global')) {
+ if (this.npm.global) {
throw new Error('Cannot use view command in global mode.')
}
const dir = this.npm.prefix
diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js
index 732362565e..2197f11a52 100644
--- a/deps/npm/lib/npm.js
+++ b/deps/npm/lib/npm.js
@@ -129,7 +129,6 @@ class Npm extends EventEmitter {
})
}
- const isGlobal = this.config.get('global')
const workspacesEnabled = this.config.get('workspaces')
// if cwd is a workspace, the default is set to [that workspace]
const implicitWorkspace = this.config.get('workspace', 'default').length > 0
@@ -160,7 +159,7 @@ class Npm extends EventEmitter {
execPromise = Promise.reject(
new Error('Can not use --no-workspaces and --workspace at the same time'))
} else if (filterByWorkspaces) {
- if (isGlobal) {
+ if (this.global) {
execPromise = Promise.reject(new Error('Workspaces not supported for global packages'))
} else {
execPromise = command.execWorkspaces(args, workspacesFilters)
@@ -333,6 +332,10 @@ class Npm extends EventEmitter {
return this.#chalk
}
+ get global () {
+ return this.config.get('global') || this.config.get('location') === 'global'
+ }
+
get logColor () {
return this.flatOptions.logColor
}
@@ -409,7 +412,7 @@ class Npm extends EventEmitter {
}
get dir () {
- return this.config.get('global') ? this.globalDir : this.localDir
+ return this.global ? this.globalDir : this.localDir
}
get globalBin () {
@@ -422,15 +425,15 @@ class Npm extends EventEmitter {
}
get bin () {
- return this.config.get('global') ? this.globalBin : this.localBin
+ return this.global ? this.globalBin : this.localBin
}
get prefix () {
- return this.config.get('global') ? this.globalPrefix : this.localPrefix
+ return this.global ? this.globalPrefix : this.localPrefix
}
set prefix (r) {
- const k = this.config.get('global') ? 'globalPrefix' : 'localPrefix'
+ const k = this.global ? 'globalPrefix' : 'localPrefix'
this[k] = r
}
diff --git a/deps/npm/lib/utils/config/definitions.js b/deps/npm/lib/utils/config/definitions.js
index c4be3a6584..92fbbd1e6d 100644
--- a/deps/npm/lib/utils/config/definitions.js
+++ b/deps/npm/lib/utils/config/definitions.js
@@ -811,6 +811,9 @@ define('global', {
default: false,
type: Boolean,
short: 'g',
+ deprecated: `
+ \`--global\`, \`--local\` are deprecated. Use \`--location=global\` instead.
+ `,
description: `
Operates in "global" mode, so that packages are installed into the
\`prefix\` folder instead of the current working directory. See
@@ -1179,12 +1182,24 @@ define('location', {
`,
description: `
When passed to \`npm config\` this refers to which config file to use.
+
+ When set to "global" mode, 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\`
`,
flatten: (key, obj, flatOptions) => {
flatten(key, obj, flatOptions)
if (flatOptions.global) {
flatOptions.location = 'global'
}
+ if (obj.location === 'global') {
+ flatOptions.global = true
+ }
},
})
diff --git a/deps/npm/lib/utils/get-identity.js b/deps/npm/lib/utils/get-identity.js
index e77c2eea4c..f4aedb89b3 100644
--- a/deps/npm/lib/utils/get-identity.js
+++ b/deps/npm/lib/utils/get-identity.js
@@ -1,39 +1,24 @@
const npmFetch = require('npm-registry-fetch')
-const needsAuthError = (msg) =>
- Object.assign(new Error(msg), { code: 'ENEEDAUTH' })
-
-module.exports = async (npm, opts = {}) => {
+module.exports = async (npm, opts) => {
const { registry } = opts
- if (!registry) {
- throw Object.assign(new Error('No registry specified.'), { code: 'ENOREGISTRY' })
- }
// First, check if we have a user/pass-based auth
const creds = npm.config.getCredentialsByURI(registry)
- const { username: usernameFromURI, token } = creds
+ if (creds.username) {
+ return creds.username
+ }
- if (usernameFromURI) {
- // Found username; return it
- return usernameFromURI
- } else if (token) {
- // No username, but we have a token; fetch the username from registry
- const registryData = await npmFetch.json('/-/whoami', {
- ...opts,
- })
- const { username: usernameFromRegistry } = registryData
- // Retrieved username from registry; return it
- if (usernameFromRegistry) {
- return usernameFromRegistry
- } else {
- // Didn't get username from registry; bad token
- throw needsAuthError(
- 'Your auth token is no longer valid. Please login again.'
- )
- }
- } else {
- // At this point, if they have a credentials object, it doesn't have a
- // token or auth in it. Probably just the default registry.
- throw needsAuthError('This command requires you to be logged in.')
+ // No username, but we have a token; fetch the username from registry
+ if (creds.token) {
+ const registryData = await npmFetch.json('/-/whoami', { ...opts })
+ return registryData.username
}
+
+ // At this point, even if they have a credentials object, it doesn't have a
+ // valid token.
+ throw Object.assign(
+ new Error('This command requires you to be logged in.'),
+ { code: 'ENEEDAUTH' }
+ )
}
diff --git a/deps/npm/man/man1/npm-bin.1 b/deps/npm/man/man1/npm-bin.1
index efe38ee8d9..9c6d2ccf4c 100644
--- a/deps/npm/man/man1/npm-bin.1
+++ b/deps/npm/man/man1/npm-bin.1
@@ -20,6 +20,9 @@ Print the folder where npm will install executables\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-ci.1 b/deps/npm/man/man1/npm-ci.1
index 3aefdfc80b..70182bf407 100644
--- a/deps/npm/man/man1/npm-ci.1
+++ b/deps/npm/man/man1/npm-ci.1
@@ -1,6 +1,6 @@
.TH "NPM\-CI" "1" "May 2022" "" ""
.SH "NAME"
-\fBnpm-ci\fR \- Install a project with a clean slate
+\fBnpm-ci\fR \- Clean install a project
.SS Synopsis
.P
.RS 2
@@ -17,16 +17,7 @@ it's meant to be used in automated environments such as test platforms,
continuous integration, and deployment \-\- or any situation where you want
to make sure you're doing a clean install of your dependencies\.
.P
-\fBnpm ci\fP will be significantly faster when:
-.RS 0
-.IP \(bu 2
-There is a \fBpackage\-lock\.json\fP or \fBnpm\-shrinkwrap\.json\fP file\.
-.IP \(bu 2
-The \fBnode_modules\fP folder is missing or empty\.
-
-.RE
-.P
-In short, the main differences between using \fBnpm install\fP and \fBnpm ci\fP are:
+The main differences between using \fBnpm install\fP and \fBnpm ci\fP are:
.RS 0
.IP \(bu 2
The project \fBmust\fR have an existing \fBpackage\-lock\.json\fP or
diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1
index 19f9ab6a06..88ffa9aa05 100644
--- a/deps/npm/man/man1/npm-config.1
+++ b/deps/npm/man/man1/npm-config.1
@@ -117,6 +117,9 @@ Not supported by all npm commands\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
@@ -155,6 +158,20 @@ Type: "global", "user", or "project"
.RE
.P
When passed to \fBnpm config\fP this refers to which config file to use\.
+.P
+When set to "global" mode, packages are installed into the \fBprefix\fP folder
+instead of the current working directory\. See
+npm help folders for more on the differences in behavior\.
+.RS 0
+.IP \(bu 2
+packages are installed into the \fB{prefix}/lib/node_modules\fP folder, instead
+of the current working directory\.
+.IP \(bu 2
+bin files are linked to \fB{prefix}/bin\fP
+.IP \(bu 2
+man pages are linked to \fB{prefix}/share/man\fP
+
+.RE
.SS \fBlong\fP
.RS 0
.IP \(bu 2
diff --git a/deps/npm/man/man1/npm-diff.1 b/deps/npm/man/man1/npm-diff.1
index 90bdfa9476..d32c343f06 100644
--- a/deps/npm/man/man1/npm-diff.1
+++ b/deps/npm/man/man1/npm-diff.1
@@ -232,6 +232,9 @@ Treat all files as text in \fBnpm diff\fP\|\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1
index 17aadace62..e29397bf94 100644
--- a/deps/npm/man/man1/npm-install-test.1
+++ b/deps/npm/man/man1/npm-install-test.1
@@ -56,6 +56,9 @@ rather than using npm's default semver range operator\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1
index 7630adb0e2..4bb41f2d7b 100644
--- a/deps/npm/man/man1/npm-install.1
+++ b/deps/npm/man/man1/npm-install.1
@@ -467,6 +467,9 @@ rather than using npm's default semver range operator\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1
index f59c746519..1b982044e4 100644
--- a/deps/npm/man/man1/npm-link.1
+++ b/deps/npm/man/man1/npm-link.1
@@ -145,6 +145,9 @@ rather than using npm's default semver range operator\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1
index 42f9baf965..1efd612984 100644
--- a/deps/npm/man/man1/npm-ls.1
+++ b/deps/npm/man/man1/npm-ls.1
@@ -26,7 +26,7 @@ example, running \fBnpm ls promzard\fP in npm's source tree will show:
.P
.RS 2
.nf
-npm@8\.10\.0 /path/to/npm
+npm@8\.11\.0 /path/to/npm
└─┬ init\-package\-json@0\.0\.4
└── promzard@0\.1\.5
.fi
@@ -127,6 +127,9 @@ Output parseable results from commands that write to standard output\. For
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1
index 9fe1ddf692..03bcf92588 100644
--- a/deps/npm/man/man1/npm-outdated.1
+++ b/deps/npm/man/man1/npm-outdated.1
@@ -159,6 +159,9 @@ Output parseable results from commands that write to standard output\. For
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1
index 2434c34678..e053f315ff 100644
--- a/deps/npm/man/man1/npm-prefix.1
+++ b/deps/npm/man/man1/npm-prefix.1
@@ -40,6 +40,9 @@ npm prefix \-g
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1
index dab000878d..f3c51a34e4 100644
--- a/deps/npm/man/man1/npm-rebuild.1
+++ b/deps/npm/man/man1/npm-rebuild.1
@@ -28,6 +28,9 @@ will be rebuilt\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1
index 4e1a94be7b..a9143ebe88 100644
--- a/deps/npm/man/man1/npm-root.1
+++ b/deps/npm/man/man1/npm-root.1
@@ -29,6 +29,9 @@ echo "Global packages installed in: ${global_node_modules}"
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm-set-script.1 b/deps/npm/man/man1/npm-set-script.1
index 96ee6e3e34..85106d95fb 100644
--- a/deps/npm/man/man1/npm-set-script.1
+++ b/deps/npm/man/man1/npm-set-script.1
@@ -5,6 +5,8 @@
.P
An npm command that lets you create a task in the \fBscripts\fP section of the \fBpackage\.json\fP\|\.
.P
+Deprecated\.
+.P
.RS 2
.nf
npm set\-script [<script>] [<command>]
diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1
index fa2903a18c..aebe0c8895 100644
--- a/deps/npm/man/man1/npm-update.1
+++ b/deps/npm/man/man1/npm-update.1
@@ -180,6 +180,9 @@ Will also prevent writing to \fBpackage\-lock\.json\fP if set to \fBfalse\fP\|\.
Default: false
.IP \(bu 2
Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
.RE
.P
diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1
index c540497252..6ac72ad35c 100644
--- a/deps/npm/man/man1/npm.1
+++ b/deps/npm/man/man1/npm.1
@@ -4,7 +4,7 @@
.SS Synopsis
.SS Version
.P
-8\.10\.0
+8\.11\.0
.SS Description
.P
npm is the package manager for the Node JavaScript platform\. It puts
diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7
index f727a19f25..e3dc9a9952 100644
--- a/deps/npm/man/man7/config.7
+++ b/deps/npm/man/man7/config.7
@@ -739,28 +739,6 @@ Type: Boolean
.P
Tag the commit when using the \fBnpm version\fP command\. Setting this to false
results in no commit being made at all\.
-.SS \fBglobal\fP
-.RS 0
-.IP \(bu 2
-Default: false
-.IP \(bu 2
-Type: Boolean
-
-.RE
-.P
-Operates in "global" mode, so that packages are installed into the \fBprefix\fP
-folder instead of the current working directory\. See
-npm help folders for more on the differences in behavior\.
-.RS 0
-.IP \(bu 2
-packages are installed into the \fB{prefix}/lib/node_modules\fP folder, instead
-of the current working directory\.
-.IP \(bu 2
-bin files are linked to \fB{prefix}/bin\fP
-.IP \(bu 2
-man pages are linked to \fB{prefix}/share/man\fP
-
-.RE
.SS \fBglobal\-style\fP
.RS 0
.IP \(bu 2
@@ -1066,6 +1044,20 @@ Type: "global", "user", or "project"
.RE
.P
When passed to \fBnpm config\fP this refers to which config file to use\.
+.P
+When set to "global" mode, packages are installed into the \fBprefix\fP folder
+instead of the current working directory\. See
+npm help folders for more on the differences in behavior\.
+.RS 0
+.IP \(bu 2
+packages are installed into the \fB{prefix}/lib/node_modules\fP folder, instead
+of the current working directory\.
+.IP \(bu 2
+bin files are linked to \fB{prefix}/bin\fP
+.IP \(bu 2
+man pages are linked to \fB{prefix}/share/man\fP
+
+.RE
.SS \fBlockfile\-version\fP
.RS 0
.IP \(bu 2
@@ -2027,6 +2019,31 @@ DEPRECATED: Please use \-\-include=dev instead\.
.RE
.P
Alias for \fB\-\-include=dev\fP\|\.
+.SS \fBglobal\fP
+.RS 0
+.IP \(bu 2
+Default: false
+.IP \(bu 2
+Type: Boolean
+.IP \(bu 2
+DEPRECATED: \fB\-\-global\fP, \fB\-\-local\fP are deprecated\. Use \fB\-\-location=global\fP
+instead\.
+
+.RE
+.P
+Operates in "global" mode, so that packages are installed into the \fBprefix\fP
+folder instead of the current working directory\. See
+npm help folders for more on the differences in behavior\.
+.RS 0
+.IP \(bu 2
+packages are installed into the \fB{prefix}/lib/node_modules\fP folder, instead
+of the current working directory\.
+.IP \(bu 2
+bin files are linked to \fB{prefix}/bin\fP
+.IP \(bu 2
+man pages are linked to \fB{prefix}/share/man\fP
+
+.RE
.SS \fBinit\.author\.email\fP
.RS 0
.IP \(bu 2
diff --git a/deps/npm/node_modules/cacache/lib/content/read.js b/deps/npm/node_modules/cacache/lib/content/read.js
index 0aeb454725..f5128fe185 100644
--- a/deps/npm/node_modules/cacache/lib/content/read.js
+++ b/deps/npm/node_modules/cacache/lib/content/read.js
@@ -1,42 +1,35 @@
'use strict'
-const util = require('util')
-
-const fs = require('fs')
+const fs = require('@npmcli/fs')
const fsm = require('fs-minipass')
const ssri = require('ssri')
const contentPath = require('./path')
const Pipeline = require('minipass-pipeline')
-const lstat = util.promisify(fs.lstat)
-const readFile = util.promisify(fs.readFile)
-const copyFile = util.promisify(fs.copyFile)
-
module.exports = read
const MAX_SINGLE_READ_SIZE = 64 * 1024 * 1024
-function read (cache, integrity, opts = {}) {
+async function read (cache, integrity, opts = {}) {
const { size } = opts
- return withContentSri(cache, integrity, (cpath, sri) => {
+ const { stat, cpath, sri } = await withContentSri(cache, integrity, async (cpath, sri) => {
// get size
- return lstat(cpath).then(stat => ({ stat, cpath, sri }))
- }).then(({ stat, cpath, sri }) => {
- if (typeof size === 'number' && stat.size !== size) {
- throw sizeError(size, stat.size)
- }
+ const stat = await fs.lstat(cpath)
+ return { stat, cpath, sri }
+ })
+ if (typeof size === 'number' && stat.size !== size) {
+ throw sizeError(size, stat.size)
+ }
- if (stat.size > MAX_SINGLE_READ_SIZE) {
- return readPipeline(cpath, stat.size, sri, new Pipeline()).concat()
- }
+ if (stat.size > MAX_SINGLE_READ_SIZE) {
+ return readPipeline(cpath, stat.size, sri, new Pipeline()).concat()
+ }
- return readFile(cpath, null).then((data) => {
- if (!ssri.checkData(data, sri)) {
- throw integrityError(sri, cpath)
- }
+ const data = await fs.readFile(cpath, { encoding: null })
+ if (!ssri.checkData(data, sri)) {
+ throw integrityError(sri, cpath)
+ }
- return data
- })
- })
+ return data
}
const readPipeline = (cpath, size, sri, stream) => {
@@ -58,7 +51,7 @@ module.exports.sync = readSync
function readSync (cache, integrity, opts = {}) {
const { size } = opts
return withContentSriSync(cache, integrity, (cpath, sri) => {
- const data = fs.readFileSync(cpath)
+ const data = fs.readFileSync(cpath, { encoding: null })
if (typeof size === 'number' && size !== data.length) {
throw sizeError(size, data.length)
}
@@ -77,16 +70,19 @@ module.exports.readStream = readStream
function readStream (cache, integrity, opts = {}) {
const { size } = opts
const stream = new Pipeline()
- withContentSri(cache, integrity, (cpath, sri) => {
- // just lstat to ensure it exists
- return lstat(cpath).then((stat) => ({ stat, cpath, sri }))
- }).then(({ stat, cpath, sri }) => {
+ // Set all this up to run on the stream and then just return the stream
+ Promise.resolve().then(async () => {
+ const { stat, cpath, sri } = await withContentSri(cache, integrity, async (cpath, sri) => {
+ // just lstat to ensure it exists
+ const stat = await fs.lstat(cpath)
+ return { stat, cpath, sri }
+ })
if (typeof size === 'number' && size !== stat.size) {
return stream.emit('error', sizeError(size, stat.size))
}
readPipeline(cpath, stat.size, sri, stream)
- }, er => stream.emit('error', er))
+ }).catch(err => stream.emit('error', err))
return stream
}
@@ -96,7 +92,7 @@ module.exports.copy.sync = copySync
function copy (cache, integrity, dest) {
return withContentSri(cache, integrity, (cpath, sri) => {
- return copyFile(cpath, dest)
+ return fs.copyFile(cpath, dest)
})
}
@@ -108,14 +104,17 @@ function copySync (cache, integrity, dest) {
module.exports.hasContent = hasContent
-function hasContent (cache, integrity) {
+async function hasContent (cache, integrity) {
if (!integrity) {
- return Promise.resolve(false)
+ return false
}
- return withContentSri(cache, integrity, (cpath, sri) => {
- return lstat(cpath).then((stat) => ({ size: stat.size, sri, stat }))
- }).catch((err) => {
+ try {
+ return await withContentSri(cache, integrity, async (cpath, sri) => {
+ const stat = await fs.lstat(cpath)
+ return { size: stat.size, sri, stat }
+ })
+ } catch (err) {
if (err.code === 'ENOENT') {
return false
}
@@ -128,7 +127,7 @@ function hasContent (cache, integrity) {
return false
}
}
- })
+ }
}
module.exports.hasContent.sync = hasContentSync
@@ -159,61 +158,47 @@ function hasContentSync (cache, integrity) {
})
}
-function withContentSri (cache, integrity, fn) {
- const tryFn = () => {
- const sri = ssri.parse(integrity)
- // If `integrity` has multiple entries, pick the first digest
- // with available local data.
- const algo = sri.pickAlgorithm()
- const digests = sri[algo]
-
- if (digests.length <= 1) {
- const cpath = contentPath(cache, digests[0])
- return fn(cpath, digests[0])
- } else {
- // Can't use race here because a generic error can happen before
- // a ENOENT error, and can happen before a valid result
- return Promise
- .all(digests.map((meta) => {
- return withContentSri(cache, meta, fn)
- .catch((err) => {
- if (err.code === 'ENOENT') {
- return Object.assign(
- new Error('No matching content found for ' + sri.toString()),
- { code: 'ENOENT' }
- )
- }
- return err
- })
- }))
- .then((results) => {
- // Return the first non error if it is found
- const result = results.find((r) => !(r instanceof Error))
- if (result) {
- return result
- }
-
- // Throw the No matching content found error
- const enoentError = results.find((r) => r.code === 'ENOENT')
- if (enoentError) {
- throw enoentError
- }
-
- // Throw generic error
- throw results.find((r) => r instanceof Error)
- })
+async function withContentSri (cache, integrity, fn) {
+ const sri = ssri.parse(integrity)
+ // If `integrity` has multiple entries, pick the first digest
+ // with available local data.
+ const algo = sri.pickAlgorithm()
+ const digests = sri[algo]
+
+ if (digests.length <= 1) {
+ const cpath = contentPath(cache, digests[0])
+ return fn(cpath, digests[0])
+ } else {
+ // Can't use race here because a generic error can happen before
+ // a ENOENT error, and can happen before a valid result
+ const results = await Promise.all(digests.map(async (meta) => {
+ try {
+ return await withContentSri(cache, meta, fn)
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ return Object.assign(
+ new Error('No matching content found for ' + sri.toString()),
+ { code: 'ENOENT' }
+ )
+ }
+ return err
+ }
+ }))
+ // Return the first non error if it is found
+ const result = results.find((r) => !(r instanceof Error))
+ if (result) {
+ return result
}
- }
- return new Promise((resolve, reject) => {
- try {
- tryFn()
- .then(resolve)
- .catch(reject)
- } catch (err) {
- reject(err)
+ // Throw the No matching content found error
+ const enoentError = results.find((r) => r.code === 'ENOENT')
+ if (enoentError) {
+ throw enoentError
}
- })
+
+ // Throw generic error
+ throw results.find((r) => r instanceof Error)
+ }
}
function withContentSriSync (cache, integrity, fn) {
diff --git a/deps/npm/node_modules/cacache/lib/content/rm.js b/deps/npm/node_modules/cacache/lib/content/rm.js
index 50612364e9..f7333053b3 100644
--- a/deps/npm/node_modules/cacache/lib/content/rm.js
+++ b/deps/npm/node_modules/cacache/lib/content/rm.js
@@ -8,13 +8,13 @@ const rimraf = util.promisify(require('rimraf'))
module.exports = rm
-function rm (cache, integrity) {
- return hasContent(cache, integrity).then((content) => {
- // ~pretty~ sure we can't end up with a content lacking sri, but be safe
- if (content && content.sri) {
- return rimraf(contentPath(cache, content.sri)).then(() => true)
- } else {
- return false
- }
- })
+async function rm (cache, integrity) {
+ const content = await hasContent(cache, integrity)
+ // ~pretty~ sure we can't end up with a content lacking sri, but be safe
+ if (content && content.sri) {
+ await rimraf(contentPath(cache, content.sri))
+ return true
+ } else {
+ return false
+ }
}
diff --git a/deps/npm/node_modules/cacache/lib/content/write.js b/deps/npm/node_modules/cacache/lib/content/write.js
index b0aa18c12b..62388dc81d 100644
--- a/deps/npm/node_modules/cacache/lib/content/write.js
+++ b/deps/npm/node_modules/cacache/lib/content/write.js
@@ -1,10 +1,11 @@
'use strict'
+const events = require('events')
const util = require('util')
const contentPath = require('./path')
const fixOwner = require('../util/fix-owner')
-const fs = require('fs')
+const fs = require('@npmcli/fs')
const moveFile = require('../util/move-file')
const Minipass = require('minipass')
const Pipeline = require('minipass-pipeline')
@@ -15,8 +16,6 @@ const ssri = require('ssri')
const uniqueFilename = require('unique-filename')
const fsm = require('fs-minipass')
-const writeFile = util.promisify(fs.writeFile)
-
module.exports = write
async function write (cache, data, opts = {}) {
@@ -36,7 +35,7 @@ async function write (cache, data, opts = {}) {
const tmp = await makeTmp(cache, opts)
try {
- await writeFile(tmp.target, data, { flag: 'wx' })
+ await fs.writeFile(tmp.target, data, { flag: 'wx' })
await moveToDestination(tmp, cache, sri, opts)
return { integrity: sri, size: data.length }
} finally {
@@ -115,7 +114,21 @@ async function handleContent (inputStream, cache, opts) {
}
}
-function pipeToTmp (inputStream, cache, tmpTarget, opts) {
+async function pipeToTmp (inputStream, cache, tmpTarget, opts) {
+ const outStream = new fsm.WriteStream(tmpTarget, {
+ flags: 'wx',
+ })
+
+ if (opts.integrityEmitter) {
+ // we need to create these all simultaneously since they can fire in any order
+ const [integrity, size] = await Promise.all([
+ events.once(opts.integrityEmitter, 'integrity').then(res => res[0]),
+ events.once(opts.integrityEmitter, 'size').then(res => res[0]),
+ new Pipeline(inputStream, outStream).promise(),
+ ])
+ return { integrity, size }
+ }
+
let integrity
let size
const hashStream = ssri.integrityStream({
@@ -130,43 +143,28 @@ function pipeToTmp (inputStream, cache, tmpTarget, opts) {
size = s
})
- const outStream = new fsm.WriteStream(tmpTarget, {
- flags: 'wx',
- })
-
- // NB: this can throw if the hashStream has a problem with
- // it, and the data is fully written. but pipeToTmp is only
- // called in promisory contexts where that is handled.
- const pipeline = new Pipeline(
- inputStream,
- hashStream,
- outStream
- )
-
- return pipeline.promise().then(() => ({ integrity, size }))
+ const pipeline = new Pipeline(inputStream, hashStream, outStream)
+ await pipeline.promise()
+ return { integrity, size }
}
-function makeTmp (cache, opts) {
+async function makeTmp (cache, opts) {
const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix)
- return fixOwner.mkdirfix(cache, path.dirname(tmpTarget)).then(() => ({
+ await fixOwner.mkdirfix(cache, path.dirname(tmpTarget))
+ return {
target: tmpTarget,
moved: false,
- }))
+ }
}
-function moveToDestination (tmp, cache, sri, opts) {
+async function moveToDestination (tmp, cache, sri, opts) {
const destination = contentPath(cache, sri)
const destDir = path.dirname(destination)
- return fixOwner
- .mkdirfix(cache, destDir)
- .then(() => {
- return moveFile(tmp.target, destination)
- })
- .then(() => {
- tmp.moved = true
- return fixOwner.chownr(cache, destination)
- })
+ await fixOwner.mkdirfix(cache, destDir)
+ await moveFile(tmp.target, destination)
+ tmp.moved = true
+ await fixOwner.chownr(cache, destination)
}
function sizeError (expected, found) {
diff --git a/deps/npm/node_modules/cacache/lib/entry-index.js b/deps/npm/node_modules/cacache/lib/entry-index.js
index 9d4485624a..cbfa619099 100644
--- a/deps/npm/node_modules/cacache/lib/entry-index.js
+++ b/deps/npm/node_modules/cacache/lib/entry-index.js
@@ -2,7 +2,7 @@
const util = require('util')
const crypto = require('crypto')
-const fs = require('fs')
+const fs = require('@npmcli/fs')
const Minipass = require('minipass')
const path = require('path')
const ssri = require('ssri')
@@ -17,11 +17,6 @@ const _rimraf = require('rimraf')
const rimraf = util.promisify(_rimraf)
rimraf.sync = _rimraf.sync
-const appendFile = util.promisify(fs.appendFile)
-const readFile = util.promisify(fs.readFile)
-const readdir = util.promisify(fs.readdir)
-const writeFile = util.promisify(fs.writeFile)
-
module.exports.NotFoundError = class NotFoundError extends Error {
constructor (cache, key) {
super(`No cache entry for ${key} found in ${cache}`)
@@ -85,7 +80,7 @@ async function compact (cache, key, matchFn, opts = {}) {
}
const write = async (tmp) => {
- await writeFile(tmp.target, newIndex, { flag: 'wx' })
+ await fs.writeFile(tmp.target, newIndex, { flag: 'wx' })
await fixOwner.mkdirfix(cache, path.dirname(bucket))
// we use @npmcli/move-file directly here because we
// want to overwrite the existing file
@@ -118,7 +113,7 @@ async function compact (cache, key, matchFn, opts = {}) {
module.exports.insert = insert
-function insert (cache, key, integrity, opts = {}) {
+async function insert (cache, key, integrity, opts = {}) {
const { metadata, size } = opts
const bucket = bucketPath(cache, key)
const entry = {
@@ -128,36 +123,32 @@ function insert (cache, key, integrity, opts = {}) {
size,
metadata,
}
- return fixOwner
- .mkdirfix(cache, path.dirname(bucket))
- .then(() => {
- const stringified = JSON.stringify(entry)
- // NOTE - Cleverness ahoy!
- //
- // This works because it's tremendously unlikely for an entry to corrupt
- // another while still preserving the string length of the JSON in
- // question. So, we just slap the length in there and verify it on read.
- //
- // Thanks to @isaacs for the whiteboarding session that ended up with
- // this.
- return appendFile(bucket, `\n${hashEntry(stringified)}\t${stringified}`)
- })
- .then(() => fixOwner.chownr(cache, bucket))
- .catch((err) => {
- if (err.code === 'ENOENT') {
- return undefined
- }
+ try {
+ await fixOwner.mkdirfix(cache, path.dirname(bucket))
+ const stringified = JSON.stringify(entry)
+ // NOTE - Cleverness ahoy!
+ //
+ // This works because it's tremendously unlikely for an entry to corrupt
+ // another while still preserving the string length of the JSON in
+ // question. So, we just slap the length in there and verify it on read.
+ //
+ // Thanks to @isaacs for the whiteboarding session that ended up with
+ // this.
+ await fs.appendFile(bucket, `\n${hashEntry(stringified)}\t${stringified}`)
+ await fixOwner.chownr(cache, bucket)
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ return undefined
+ }
- throw err
- // There's a class of race conditions that happen when things get deleted
- // during fixOwner, or between the two mkdirfix/chownr calls.
- //
- // It's perfectly fine to just not bother in those cases and lie
- // that the index entry was written. Because it's a cache.
- })
- .then(() => {
- return formatEntry(cache, entry)
- })
+ throw err
+ // There's a class of race conditions that happen when things get deleted
+ // during fixOwner, or between the two mkdirfix/chownr calls.
+ //
+ // It's perfectly fine to just not bother in those cases and lie
+ // that the index entry was written. Because it's a cache.
+ }
+ return formatEntry(cache, entry)
}
module.exports.insert.sync = insertSync
@@ -187,25 +178,24 @@ function insertSync (cache, key, integrity, opts = {}) {
module.exports.find = find
-function find (cache, key) {
+async function find (cache, key) {
const bucket = bucketPath(cache, key)
- return bucketEntries(bucket)
- .then((entries) => {
- return entries.reduce((latest, next) => {
- if (next && next.key === key) {
- return formatEntry(cache, next)
- } else {
- return latest
- }
- }, null)
- })
- .catch((err) => {
- if (err.code === 'ENOENT') {
- return null
+ try {
+ const entries = await bucketEntries(bucket)
+ return entries.reduce((latest, next) => {
+ if (next && next.key === key) {
+ return formatEntry(cache, next)
} else {
- throw err
+ return latest
}
- })
+ }, null)
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ return null
+ } else {
+ throw err
+ }
+ }
}
module.exports.find.sync = findSync
@@ -257,67 +247,64 @@ function lsStream (cache) {
const indexDir = bucketDir(cache)
const stream = new Minipass({ objectMode: true })
- readdirOrEmpty(indexDir).then(buckets => Promise.all(
- buckets.map(bucket => {
+ // Set all this up to run on the stream and then just return the stream
+ Promise.resolve().then(async () => {
+ const buckets = await readdirOrEmpty(indexDir)
+ await Promise.all(buckets.map(async (bucket) => {
const bucketPath = path.join(indexDir, bucket)
- return readdirOrEmpty(bucketPath).then(subbuckets => Promise.all(
- subbuckets.map(subbucket => {
- const subbucketPath = path.join(bucketPath, subbucket)
-
- // "/cachename/<bucket 0xFF>/<bucket 0xFF>./*"
- return readdirOrEmpty(subbucketPath).then(entries => Promise.all(
- entries.map(entry => {
- const entryPath = path.join(subbucketPath, entry)
- return bucketEntries(entryPath).then(entries =>
- // using a Map here prevents duplicate keys from
- // showing up twice, I guess?
- entries.reduce((acc, entry) => {
- acc.set(entry.key, entry)
- return acc
- }, new Map())
- ).then(reduced => {
- // reduced is a map of key => entry
- for (const entry of reduced.values()) {
- const formatted = formatEntry(cache, entry)
- if (formatted) {
- stream.write(formatted)
- }
- }
- }).catch(err => {
- if (err.code === 'ENOENT') {
- return undefined
- }
- throw err
- })
- })
- ))
- })
- ))
- })
- ))
- .then(
- () => stream.end(),
- err => stream.emit('error', err)
- )
+ const subbuckets = await readdirOrEmpty(bucketPath)
+ await Promise.all(subbuckets.map(async (subbucket) => {
+ const subbucketPath = path.join(bucketPath, subbucket)
+
+ // "/cachename/<bucket 0xFF>/<bucket 0xFF>./*"
+ const subbucketEntries = await readdirOrEmpty(subbucketPath)
+ await Promise.all(subbucketEntries.map(async (entry) => {
+ const entryPath = path.join(subbucketPath, entry)
+ try {
+ const entries = await bucketEntries(entryPath)
+ // using a Map here prevents duplicate keys from showing up
+ // twice, I guess?
+ const reduced = entries.reduce((acc, entry) => {
+ acc.set(entry.key, entry)
+ return acc
+ }, new Map())
+ // reduced is a map of key => entry
+ for (const entry of reduced.values()) {
+ const formatted = formatEntry(cache, entry)
+ if (formatted) {
+ stream.write(formatted)
+ }
+ }
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ return undefined
+ }
+ throw err
+ }
+ }))
+ }))
+ }))
+ stream.end()
+ }).catch(err => stream.emit('error', err))
return stream
}
module.exports.ls = ls
-function ls (cache) {
- return lsStream(cache).collect().then(entries =>
- entries.reduce((acc, xs) => {
- acc[xs.key] = xs
- return acc
- }, {})
- )
+async function ls (cache) {
+ const entries = await lsStream(cache).collect()
+ return entries.reduce((acc, xs) => {
+ acc[xs.key] = xs
+ return acc
+ }, {})
}
module.exports.bucketEntries = bucketEntries
-function bucketEntries (bucket, filter) {
- return readFile(bucket, 'utf8').then((data) => _bucketEntries(data, filter))
+async function bucketEntries (bucket, filter) {
+ const data = await fs.readFile(bucket, 'utf8')
+ return _bucketEntries(data, filter)
}
module.exports.bucketEntries.sync = bucketEntriesSync
@@ -406,7 +393,7 @@ function formatEntry (cache, entry, keepAll) {
}
function readdirOrEmpty (dir) {
- return readdir(dir).catch((err) => {
+ return fs.readdir(dir).catch((err) => {
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') {
return []
}
diff --git a/deps/npm/node_modules/cacache/lib/get.js b/deps/npm/node_modules/cacache/lib/get.js
index 58f357b1da..cc9d8f6796 100644
--- a/deps/npm/node_modules/cacache/lib/get.js
+++ b/deps/npm/node_modules/cacache/lib/get.js
@@ -8,52 +8,48 @@ const index = require('./entry-index')
const memo = require('./memoization')
const read = require('./content/read')
-function getData (cache, key, opts = {}) {
+async function getData (cache, key, opts = {}) {
const { integrity, memoize, size } = opts
const memoized = memo.get(cache, key, opts)
if (memoized && memoize !== false) {
- return Promise.resolve({
+ return {
metadata: memoized.entry.metadata,
data: memoized.data,
integrity: memoized.entry.integrity,
size: memoized.entry.size,
- })
+ }
}
- return index.find(cache, key, opts).then((entry) => {
- if (!entry) {
- throw new index.NotFoundError(cache, key)
- }
+ const entry = await index.find(cache, key, opts)
+ if (!entry) {
+ throw new index.NotFoundError(cache, key)
+ }
+ const data = await read(cache, entry.integrity, { integrity, size })
+ if (memoize) {
+ memo.put(cache, entry, data, opts)
+ }
- return read(cache, entry.integrity, { integrity, size }).then((data) => {
- if (memoize) {
- memo.put(cache, entry, data, opts)
- }
-
- return {
- data,
- metadata: entry.metadata,
- size: entry.size,
- integrity: entry.integrity,
- }
- })
- })
+ return {
+ data,
+ metadata: entry.metadata,
+ size: entry.size,
+ integrity: entry.integrity,
+ }
}
module.exports = getData
-function getDataByDigest (cache, key, opts = {}) {
+async function getDataByDigest (cache, key, opts = {}) {
const { integrity, memoize, size } = opts
const memoized = memo.get.byDigest(cache, key, opts)
if (memoized && memoize !== false) {
- return Promise.resolve(memoized)
+ return memoized
}
- return read(cache, key, { integrity, size }).then((res) => {
- if (memoize) {
- memo.put.byDigest(cache, key, res, opts)
- }
- return res
- })
+ const res = await read(cache, key, { integrity, size })
+ if (memoize) {
+ memo.put.byDigest(cache, key, res, opts)
+ }
+ return res
}
module.exports.byDigest = getDataByDigest
@@ -131,36 +127,35 @@ function getStream (cache, key, opts = {}) {
}
const stream = new Pipeline()
- index
- .find(cache, key)
- .then((entry) => {
- if (!entry) {
- throw new index.NotFoundError(cache, key)
- }
-
- stream.emit('metadata', entry.metadata)
- stream.emit('integrity', entry.integrity)
- stream.emit('size', entry.size)
- stream.on('newListener', function (ev, cb) {
- ev === 'metadata' && cb(entry.metadata)
- ev === 'integrity' && cb(entry.integrity)
- ev === 'size' && cb(entry.size)
- })
-
- const src = read.readStream(
- cache,
- entry.integrity,
- { ...opts, size: typeof size !== 'number' ? entry.size : size }
- )
-
- if (memoize) {
- const memoStream = new Collect.PassThrough()
- memoStream.on('collect', data => memo.put(cache, entry, data, opts))
- stream.unshift(memoStream)
- }
- stream.unshift(src)
+ // Set all this up to run on the stream and then just return the stream
+ Promise.resolve().then(async () => {
+ const entry = await index.find(cache, key)
+ if (!entry) {
+ throw new index.NotFoundError(cache, key)
+ }
+
+ stream.emit('metadata', entry.metadata)
+ stream.emit('integrity', entry.integrity)
+ stream.emit('size', entry.size)
+ stream.on('newListener', function (ev, cb) {
+ ev === 'metadata' && cb(entry.metadata)
+ ev === 'integrity' && cb(entry.integrity)
+ ev === 'size' && cb(entry.size)
})
- .catch((err) => stream.emit('error', err))
+
+ const src = read.readStream(
+ cache,
+ entry.integrity,
+ { ...opts, size: typeof size !== 'number' ? entry.size : size }
+ )
+
+ if (memoize) {
+ const memoStream = new Collect.PassThrough()
+ memoStream.on('collect', data => memo.put(cache, entry, data, opts))
+ stream.unshift(memoStream)
+ }
+ stream.unshift(src)
+ }).catch((err) => stream.emit('error', err))
return stream
}
@@ -204,27 +199,26 @@ function info (cache, key, opts = {}) {
}
module.exports.info = info
-function copy (cache, key, dest, opts = {}) {
- return index.find(cache, key, opts).then((entry) => {
- if (!entry) {
- throw new index.NotFoundError(cache, key)
- }
- return read.copy(cache, entry.integrity, dest, opts)
- .then(() => {
- return {
- metadata: entry.metadata,
- size: entry.size,
- integrity: entry.integrity,
- }
- })
- })
+async function copy (cache, key, dest, opts = {}) {
+ const entry = await index.find(cache, key, opts)
+ if (!entry) {
+ throw new index.NotFoundError(cache, key)
+ }
+ await read.copy(cache, entry.integrity, dest, opts)
+ return {
+ metadata: entry.metadata,
+ size: entry.size,
+ integrity: entry.integrity,
+ }
}
module.exports.copy = copy
-function copyByDigest (cache, key, dest, opts = {}) {
- return read.copy(cache, key, dest, opts).then(() => key)
+async function copyByDigest (cache, key, dest, opts = {}) {
+ await read.copy(cache, key, dest, opts)
+ return key
}
+
module.exports.copy.byDigest = copyByDigest
module.exports.hasContent = read.hasContent
diff --git a/deps/npm/node_modules/cacache/lib/put.js b/deps/npm/node_modules/cacache/lib/put.js
index eed51874f9..9fc932d5f6 100644
--- a/deps/npm/node_modules/cacache/lib/put.js
+++ b/deps/npm/node_modules/cacache/lib/put.js
@@ -14,20 +14,16 @@ const putOpts = (opts) => ({
module.exports = putData
-function putData (cache, key, data, opts = {}) {
+async function putData (cache, key, data, opts = {}) {
const { memoize } = opts
opts = putOpts(opts)
- return write(cache, data, opts).then((res) => {
- return index
- .insert(cache, key, res.integrity, { ...opts, size: res.size })
- .then((entry) => {
- if (memoize) {
- memo.put(cache, entry, data, opts)
- }
+ const res = await write(cache, data, opts)
+ const entry = await index.insert(cache, key, res.integrity, { ...opts, size: res.size })
+ if (memoize) {
+ memo.put(cache, entry, data, opts)
+ }
- return res.integrity
- })
- })
+ return res.integrity
}
module.exports.stream = putStream
@@ -68,17 +64,14 @@ function putStream (cache, key, opts = {}) {
// last but not least, we write the index and emit hash and size,
// and memoize if we're doing that
pipeline.push(new Flush({
- flush () {
+ async flush () {
if (!error) {
- return index
- .insert(cache, key, integrity, { ...opts, size })
- .then((entry) => {
- if (memoize && memoData) {
- memo.put(cache, entry, memoData, opts)
- }
- pipeline.emit('integrity', integrity)
- pipeline.emit('size', size)
- })
+ const entry = await index.insert(cache, key, integrity, { ...opts, size })
+ if (memoize && memoData) {
+ memo.put(cache, entry, memoData, opts)
+ }
+ pipeline.emit('integrity', integrity)
+ pipeline.emit('size', size)
}
},
}))
diff --git a/deps/npm/node_modules/cacache/lib/util/fix-owner.js b/deps/npm/node_modules/cacache/lib/util/fix-owner.js
index bc14def4e4..182fcb028f 100644
--- a/deps/npm/node_modules/cacache/lib/util/fix-owner.js
+++ b/deps/npm/node_modules/cacache/lib/util/fix-owner.js
@@ -33,40 +33,38 @@ const getSelf = () => {
module.exports.chownr = fixOwner
-function fixOwner (cache, filepath) {
+async function fixOwner (cache, filepath) {
if (!process.getuid) {
// This platform doesn't need ownership fixing
- return Promise.resolve()
+ return
}
getSelf()
if (self.uid !== 0) {
// almost certainly can't chown anyway
- return Promise.resolve()
+ return
}
- return Promise.resolve(inferOwner(cache)).then((owner) => {
- const { uid, gid } = owner
+ const { uid, gid } = await inferOwner(cache)
- // No need to override if it's already what we used.
- if (self.uid === uid && self.gid === gid) {
- return
- }
+ // No need to override if it's already what we used.
+ if (self.uid === uid && self.gid === gid) {
+ return
+ }
- return inflight('fixOwner: fixing ownership on ' + filepath, () =>
- chownr(
- filepath,
- typeof uid === 'number' ? uid : self.uid,
- typeof gid === 'number' ? gid : self.gid
- ).catch((err) => {
- if (err.code === 'ENOENT') {
- return null
- }
-
- throw err
- })
- )
- })
+ return inflight('fixOwner: fixing ownership on ' + filepath, () =>
+ chownr(
+ filepath,
+ typeof uid === 'number' ? uid : self.uid,
+ typeof gid === 'number' ? gid : self.gid
+ ).catch((err) => {
+ if (err.code === 'ENOENT') {
+ return null
+ }
+
+ throw err
+ })
+ )
}
module.exports.chownr.sync = fixOwnerSync
@@ -105,26 +103,25 @@ function fixOwnerSync (cache, filepath) {
module.exports.mkdirfix = mkdirfix
-function mkdirfix (cache, p, cb) {
+async function mkdirfix (cache, p, cb) {
// we have to infer the owner _before_ making the directory, even though
// we aren't going to use the results, since the cache itself might not
// exist yet. If we mkdirp it, then our current uid/gid will be assumed
// to be correct if it creates the cache folder in the process.
- return Promise.resolve(inferOwner(cache)).then(() => {
- return mkdirp(p)
- .then((made) => {
- if (made) {
- return fixOwner(cache, made).then(() => made)
- }
- })
- .catch((err) => {
- if (err.code === 'EEXIST') {
- return fixOwner(cache, p).then(() => null)
- }
-
- throw err
- })
- })
+ await inferOwner(cache)
+ try {
+ const made = await mkdirp(p)
+ if (made) {
+ await fixOwner(cache, made)
+ return made
+ }
+ } catch (err) {
+ if (err.code === 'EEXIST') {
+ await fixOwner(cache, p)
+ return null
+ }
+ throw err
+ }
}
module.exports.mkdirfix.sync = mkdirfixSync
diff --git a/deps/npm/node_modules/cacache/lib/util/move-file.js b/deps/npm/node_modules/cacache/lib/util/move-file.js
index 3739cea3df..a0b40413cb 100644
--- a/deps/npm/node_modules/cacache/lib/util/move-file.js
+++ b/deps/npm/node_modules/cacache/lib/util/move-file.js
@@ -1,18 +1,13 @@
'use strict'
-const fs = require('fs')
-const util = require('util')
-const chmod = util.promisify(fs.chmod)
-const unlink = util.promisify(fs.unlink)
-const stat = util.promisify(fs.stat)
+const fs = require('@npmcli/fs')
const move = require('@npmcli/move-file')
const pinflight = require('promise-inflight')
module.exports = moveFile
-function moveFile (src, dest) {
- const isWindows = global.__CACACHE_TEST_FAKE_WINDOWS__ ||
- process.platform === 'win32'
+async function moveFile (src, dest) {
+ const isWindows = process.platform === 'win32'
// This isn't quite an fs.rename -- the assumption is that
// if `dest` already exists, and we get certain errors while
@@ -23,47 +18,39 @@ function moveFile (src, dest) {
// content their own way.
//
// Note that, as the name suggests, this strictly only supports file moves.
- return new Promise((resolve, reject) => {
- fs.link(src, dest, (err) => {
- if (err) {
- if (isWindows && err.code === 'EPERM') {
- // XXX This is a really weird way to handle this situation, as it
- // results in the src file being deleted even though the dest
- // might not exist. Since we pretty much always write files to
- // deterministic locations based on content hash, this is likely
- // ok (or at worst, just ends in a future cache miss). But it would
- // be worth investigating at some time in the future if this is
- // really what we want to do here.
- return resolve()
- } else if (err.code === 'EEXIST' || err.code === 'EBUSY') {
- // file already exists, so whatever
- return resolve()
- } else {
- return reject(err)
+ try {
+ await fs.link(src, dest)
+ } catch (err) {
+ if (isWindows && err.code === 'EPERM') {
+ // XXX This is a really weird way to handle this situation, as it
+ // results in the src file being deleted even though the dest
+ // might not exist. Since we pretty much always write files to
+ // deterministic locations based on content hash, this is likely
+ // ok (or at worst, just ends in a future cache miss). But it would
+ // be worth investigating at some time in the future if this is
+ // really what we want to do here.
+ } else if (err.code === 'EEXIST' || err.code === 'EBUSY') {
+ // file already exists, so whatever
+ } else {
+ throw err
+ }
+ }
+ try {
+ await Promise.all([
+ fs.unlink(src),
+ !isWindows && fs.chmod(dest, '0444'),
+ ])
+ } catch (e) {
+ return pinflight('cacache-move-file:' + dest, async () => {
+ await fs.stat(dest).catch((err) => {
+ if (err.code !== 'ENOENT') {
+ // Something else is wrong here. Bail bail bail
+ throw err
}
- } else {
- return resolve()
- }
- })
- })
- .then(() => {
- // content should never change for any reason, so make it read-only
- return Promise.all([
- unlink(src),
- !isWindows && chmod(dest, '0444'),
- ])
- })
- .catch(() => {
- return pinflight('cacache-move-file:' + dest, () => {
- return stat(dest).catch((err) => {
- if (err.code !== 'ENOENT') {
- // Something else is wrong here. Bail bail bail
- throw err
- }
- // file doesn't already exist! let's try a rename -> copy fallback
- // only delete if it successfully copies
- return move(src, dest)
- })
})
+ // file doesn't already exist! let's try a rename -> copy fallback
+ // only delete if it successfully copies
+ return move(src, dest)
})
+ }
}
diff --git a/deps/npm/node_modules/cacache/lib/util/tmp.js b/deps/npm/node_modules/cacache/lib/util/tmp.js
index 0a5a50eba3..b4437cfcbe 100644
--- a/deps/npm/node_modules/cacache/lib/util/tmp.js
+++ b/deps/npm/node_modules/cacache/lib/util/tmp.js
@@ -7,15 +7,13 @@ const path = require('path')
module.exports.mkdir = mktmpdir
-function mktmpdir (cache, opts = {}) {
+async function mktmpdir (cache, opts = {}) {
const { tmpPrefix } = opts
const tmpDir = path.join(cache, 'tmp')
- return fs.mkdir(tmpDir, { recursive: true, owner: 'inherit' })
- .then(() => {
- // do not use path.join(), it drops the trailing / if tmpPrefix is unset
- const target = `${tmpDir}${path.sep}${tmpPrefix || ''}`
- return fs.mkdtemp(target, { owner: 'inherit' })
- })
+ await fs.mkdir(tmpDir, { recursive: true, owner: 'inherit' })
+ // do not use path.join(), it drops the trailing / if tmpPrefix is unset
+ const target = `${tmpDir}${path.sep}${tmpPrefix || ''}`
+ return fs.mkdtemp(target, { owner: 'inherit' })
}
module.exports.withTmp = withTmp
diff --git a/deps/npm/node_modules/cacache/lib/verify.js b/deps/npm/node_modules/cacache/lib/verify.js
index a39fb6ce1d..52692a01d1 100644
--- a/deps/npm/node_modules/cacache/lib/verify.js
+++ b/deps/npm/node_modules/cacache/lib/verify.js
@@ -5,7 +5,7 @@ const util = require('util')
const pMap = require('p-map')
const contentPath = require('./content/path')
const fixOwner = require('./util/fix-owner')
-const fs = require('fs')
+const fs = require('@npmcli/fs')
const fsm = require('fs-minipass')
const glob = util.promisify(require('glob'))
const index = require('./entry-index')
@@ -18,11 +18,6 @@ const globify = pattern => pattern.split('\\').join('/')
const hasOwnProperty = (obj, key) =>
Object.prototype.hasOwnProperty.call(obj, key)
-const stat = util.promisify(fs.stat)
-const truncate = util.promisify(fs.truncate)
-const writeFile = util.promisify(fs.writeFile)
-const readFile = util.promisify(fs.readFile)
-
const verifyOpts = (opts) => ({
concurrency: 20,
log: { silly () {} },
@@ -31,7 +26,7 @@ const verifyOpts = (opts) => ({
module.exports = verify
-function verify (cache, opts) {
+async function verify (cache, opts) {
opts = verifyOpts(opts)
opts.log.silly('verify', 'verifying cache at', cache)
@@ -45,56 +40,47 @@ function verify (cache, opts) {
markEndTime,
]
- return steps
- .reduce((promise, step, i) => {
- const label = step.name
- const start = new Date()
- return promise.then((stats) => {
- return step(cache, opts).then((s) => {
- s &&
- Object.keys(s).forEach((k) => {
- stats[k] = s[k]
- })
- const end = new Date()
- if (!stats.runTime) {
- stats.runTime = {}
- }
-
- stats.runTime[label] = end - start
- return Promise.resolve(stats)
- })
+ const stats = {}
+ for (const step of steps) {
+ const label = step.name
+ const start = new Date()
+ const s = await step(cache, opts)
+ if (s) {
+ Object.keys(s).forEach((k) => {
+ stats[k] = s[k]
})
- }, Promise.resolve({}))
- .then((stats) => {
- stats.runTime.total = stats.endTime - stats.startTime
- opts.log.silly(
- 'verify',
- 'verification finished for',
- cache,
- 'in',
- `${stats.runTime.total}ms`
- )
- return stats
- })
+ }
+ const end = new Date()
+ if (!stats.runTime) {
+ stats.runTime = {}
+ }
+ stats.runTime[label] = end - start
+ }
+ stats.runTime.total = stats.endTime - stats.startTime
+ opts.log.silly(
+ 'verify',
+ 'verification finished for',
+ cache,
+ 'in',
+ `${stats.runTime.total}ms`
+ )
+ return stats
}
-function markStartTime (cache, opts) {
- return Promise.resolve({ startTime: new Date() })
+async function markStartTime (cache, opts) {
+ return { startTime: new Date() }
}
-function markEndTime (cache, opts) {
- return Promise.resolve({ endTime: new Date() })
+async function markEndTime (cache, opts) {
+ return { endTime: new Date() }
}
-function fixPerms (cache, opts) {
+async function fixPerms (cache, opts) {
opts.log.silly('verify', 'fixing cache permissions')
- return fixOwner
- .mkdirfix(cache, cache)
- .then(() => {
- // TODO - fix file permissions too
- return fixOwner.chownr(cache, cache)
- })
- .then(() => null)
+ await fixOwner.mkdirfix(cache, cache)
+ // TODO - fix file permissions too
+ await fixOwner.chownr(cache, cache)
+ return null
}
// Implements a naive mark-and-sweep tracing garbage collector.
@@ -106,7 +92,7 @@ function fixPerms (cache, opts) {
// 4. If content is live, verify its checksum and delete it if it fails
// 5. If content is not marked as live, rimraf it.
//
-function garbageCollect (cache, opts) {
+async function garbageCollect (cache, opts) {
opts.log.silly('verify', 'garbage collecting content')
const indexStream = index.lsStream(cache)
const liveContent = new Set()
@@ -117,156 +103,135 @@ function garbageCollect (cache, opts) {
liveContent.add(entry.integrity.toString())
})
- return new Promise((resolve, reject) => {
+ await new Promise((resolve, reject) => {
indexStream.on('end', resolve).on('error', reject)
- }).then(() => {
- const contentDir = contentPath.contentDir(cache)
- return glob(globify(path.join(contentDir, '**')), {
- follow: false,
- nodir: true,
- nosort: true,
- }).then((files) => {
- return Promise.resolve({
- verifiedContent: 0,
- reclaimedCount: 0,
- reclaimedSize: 0,
- badContentCount: 0,
- keptSize: 0,
- }).then((stats) =>
- pMap(
- files,
- (f) => {
- const split = f.split(/[/\\]/)
- const digest = split.slice(split.length - 3).join('')
- const algo = split[split.length - 4]
- const integrity = ssri.fromHex(digest, algo)
- if (liveContent.has(integrity.toString())) {
- return verifyContent(f, integrity).then((info) => {
- if (!info.valid) {
- stats.reclaimedCount++
- stats.badContentCount++
- stats.reclaimedSize += info.size
- } else {
- stats.verifiedContent++
- stats.keptSize += info.size
- }
- return stats
- })
- } else {
- // No entries refer to this content. We can delete.
- stats.reclaimedCount++
- return stat(f).then((s) => {
- return rimraf(f).then(() => {
- stats.reclaimedSize += s.size
- return stats
- })
- })
- }
- },
- { concurrency: opts.concurrency }
- ).then(() => stats)
- )
- })
})
-}
-
-function verifyContent (filepath, sri) {
- return stat(filepath)
- .then((s) => {
- const contentInfo = {
- size: s.size,
- valid: true,
- }
- return ssri
- .checkStream(new fsm.ReadStream(filepath), sri)
- .catch((err) => {
- if (err.code !== 'EINTEGRITY') {
- throw err
- }
-
- return rimraf(filepath).then(() => {
- contentInfo.valid = false
- })
- })
- .then(() => contentInfo)
- })
- .catch((err) => {
- if (err.code === 'ENOENT') {
- return { size: 0, valid: false }
+ const contentDir = contentPath.contentDir(cache)
+ const files = await glob(globify(path.join(contentDir, '**')), {
+ follow: false,
+ nodir: true,
+ nosort: true,
+ })
+ const stats = {
+ verifiedContent: 0,
+ reclaimedCount: 0,
+ reclaimedSize: 0,
+ badContentCount: 0,
+ keptSize: 0,
+ }
+ await pMap(
+ files,
+ async (f) => {
+ const split = f.split(/[/\\]/)
+ const digest = split.slice(split.length - 3).join('')
+ const algo = split[split.length - 4]
+ const integrity = ssri.fromHex(digest, algo)
+ if (liveContent.has(integrity.toString())) {
+ const info = await verifyContent(f, integrity)
+ if (!info.valid) {
+ stats.reclaimedCount++
+ stats.badContentCount++
+ stats.reclaimedSize += info.size
+ } else {
+ stats.verifiedContent++
+ stats.keptSize += info.size
+ }
+ } else {
+ // No entries refer to this content. We can delete.
+ stats.reclaimedCount++
+ const s = await fs.stat(f)
+ await rimraf(f)
+ stats.reclaimedSize += s.size
}
+ return stats
+ },
+ { concurrency: opts.concurrency }
+ )
+ return stats
+}
+async function verifyContent (filepath, sri) {
+ const contentInfo = {}
+ try {
+ const { size } = await fs.stat(filepath)
+ contentInfo.size = size
+ contentInfo.valid = true
+ await ssri.checkStream(new fsm.ReadStream(filepath), sri)
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ return { size: 0, valid: false }
+ }
+ if (err.code !== 'EINTEGRITY') {
throw err
- })
+ }
+
+ await rimraf(filepath)
+ contentInfo.valid = false
+ }
+ return contentInfo
}
-function rebuildIndex (cache, opts) {
+async function rebuildIndex (cache, opts) {
opts.log.silly('verify', 'rebuilding index')
- return index.ls(cache).then((entries) => {
- const stats = {
- missingContent: 0,
- rejectedEntries: 0,
- totalEntries: 0,
- }
- const buckets = {}
- for (const k in entries) {
- /* istanbul ignore else */
- if (hasOwnProperty(entries, k)) {
- const hashed = index.hashKey(k)
- const entry = entries[k]
- const excluded = opts.filter && !opts.filter(entry)
- excluded && stats.rejectedEntries++
- if (buckets[hashed] && !excluded) {
- buckets[hashed].push(entry)
- } else if (buckets[hashed] && excluded) {
- // skip
- } else if (excluded) {
- buckets[hashed] = []
- buckets[hashed]._path = index.bucketPath(cache, k)
- } else {
- buckets[hashed] = [entry]
- buckets[hashed]._path = index.bucketPath(cache, k)
- }
+ const entries = await index.ls(cache)
+ const stats = {
+ missingContent: 0,
+ rejectedEntries: 0,
+ totalEntries: 0,
+ }
+ const buckets = {}
+ for (const k in entries) {
+ /* istanbul ignore else */
+ if (hasOwnProperty(entries, k)) {
+ const hashed = index.hashKey(k)
+ const entry = entries[k]
+ const excluded = opts.filter && !opts.filter(entry)
+ excluded && stats.rejectedEntries++
+ if (buckets[hashed] && !excluded) {
+ buckets[hashed].push(entry)
+ } else if (buckets[hashed] && excluded) {
+ // skip
+ } else if (excluded) {
+ buckets[hashed] = []
+ buckets[hashed]._path = index.bucketPath(cache, k)
+ } else {
+ buckets[hashed] = [entry]
+ buckets[hashed]._path = index.bucketPath(cache, k)
}
}
- return pMap(
- Object.keys(buckets),
- (key) => {
- return rebuildBucket(cache, buckets[key], stats, opts)
- },
- { concurrency: opts.concurrency }
- ).then(() => stats)
- })
+ }
+ await pMap(
+ Object.keys(buckets),
+ (key) => {
+ return rebuildBucket(cache, buckets[key], stats, opts)
+ },
+ { concurrency: opts.concurrency }
+ )
+ return stats
}
-function rebuildBucket (cache, bucket, stats, opts) {
- return truncate(bucket._path).then(() => {
- // This needs to be serialized because cacache explicitly
- // lets very racy bucket conflicts clobber each other.
- return bucket.reduce((promise, entry) => {
- return promise.then(() => {
- const content = contentPath(cache, entry.integrity)
- return stat(content)
- .then(() => {
- return index
- .insert(cache, entry.key, entry.integrity, {
- metadata: entry.metadata,
- size: entry.size,
- })
- .then(() => {
- stats.totalEntries++
- })
- })
- .catch((err) => {
- if (err.code === 'ENOENT') {
- stats.rejectedEntries++
- stats.missingContent++
- return
- }
- throw err
- })
+async function rebuildBucket (cache, bucket, stats, opts) {
+ await fs.truncate(bucket._path)
+ // This needs to be serialized because cacache explicitly
+ // lets very racy bucket conflicts clobber each other.
+ for (const entry of bucket) {
+ const content = contentPath(cache, entry.integrity)
+ try {
+ await fs.stat(content)
+ await index.insert(cache, entry.key, entry.integrity, {
+ metadata: entry.metadata,
+ size: entry.size,
})
- }, Promise.resolve())
- })
+ stats.totalEntries++
+ } catch (err) {
+ if (err.code === 'ENOENT') {
+ stats.rejectedEntries++
+ stats.missingContent++
+ } else {
+ throw err
+ }
+ }
+ }
}
function cleanTmp (cache, opts) {
@@ -278,7 +243,7 @@ function writeVerifile (cache, opts) {
const verifile = path.join(cache, '_lastverified')
opts.log.silly('verify', 'writing verifile to ' + verifile)
try {
- return writeFile(verifile, '' + +new Date())
+ return fs.writeFile(verifile, `${Date.now()}`)
} finally {
fixOwner.chownr.sync(cache, verifile)
}
@@ -286,8 +251,7 @@ function writeVerifile (cache, opts) {
module.exports.lastRun = lastRun
-function lastRun (cache) {
- return readFile(path.join(cache, '_lastverified'), 'utf8').then(
- (data) => new Date(+data)
- )
+async function lastRun (cache) {
+ const data = await fs.readFile(path.join(cache, '_lastverified'), { encoding: 'utf8' })
+ return new Date(+data)
}
diff --git a/deps/npm/node_modules/cacache/package.json b/deps/npm/node_modules/cacache/package.json
index cd7e4de5e0..8e54901b45 100644
--- a/deps/npm/node_modules/cacache/package.json
+++ b/deps/npm/node_modules/cacache/package.json
@@ -1,6 +1,6 @@
{
"name": "cacache",
- "version": "16.0.7",
+ "version": "16.1.0",
"cache-version": {
"content": "2",
"index": "5"
@@ -69,20 +69,16 @@
},
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
- "@npmcli/template-oss": "3.4.1",
+ "@npmcli/template-oss": "3.4.3",
"tap": "^16.0.0"
},
- "tap": {
- "100": true,
- "test-regex": "test/[^/]*.js"
- },
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"windowsCI": false,
- "version": "3.4.1"
+ "version": "3.4.3"
},
"author": "GitHub Inc."
}
diff --git a/deps/npm/node_modules/libnpmpack/package.json b/deps/npm/node_modules/libnpmpack/package.json
index 3fcf630cce..02f06a8bbf 100644
--- a/deps/npm/node_modules/libnpmpack/package.json
+++ b/deps/npm/node_modules/libnpmpack/package.json
@@ -1,6 +1,6 @@
{
"name": "libnpmpack",
- "version": "4.0.3",
+ "version": "4.1.0",
"description": "Programmatic API for the bits behind npm pack",
"author": "GitHub Inc.",
"main": "lib/index.js",
@@ -40,7 +40,7 @@
"dependencies": {
"@npmcli/run-script": "^3.0.0",
"npm-package-arg": "^9.0.1",
- "pacote": "^13.0.5"
+ "pacote": "^13.5.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
diff --git a/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js b/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js
index ae2ad8c766..7a7572ba03 100644
--- a/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js
+++ b/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js
@@ -1,21 +1,16 @@
const { Request, Response } = require('minipass-fetch')
const Minipass = require('minipass')
-const MinipassCollect = require('minipass-collect')
const MinipassFlush = require('minipass-flush')
-const MinipassPipeline = require('minipass-pipeline')
const cacache = require('cacache')
const url = require('url')
+const CachingMinipassPipeline = require('../pipeline.js')
const CachePolicy = require('./policy.js')
const cacheKey = require('./key.js')
const remote = require('../remote.js')
const hasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
-// maximum amount of data we will buffer into memory
-// if we'll exceed this, we switch to streaming
-const MAX_MEM_SIZE = 5 * 1024 * 1024 // 5MB
-
// allow list for request headers that will be written to the cache index
// note: we will also store any request headers
// that are named in a response's vary header
@@ -256,13 +251,12 @@ class CacheEntry {
}
const size = this.response.headers.get('content-length')
- const fitsInMemory = !!size && Number(size) < MAX_MEM_SIZE
- const shouldBuffer = this.options.memoize !== false && fitsInMemory
const cacheOpts = {
algorithms: this.options.algorithms,
metadata: getMetadata(this.request, this.response, this.options),
size,
- memoize: fitsInMemory && this.options.memoize,
+ integrity: this.options.integrity,
+ integrityEmitter: this.response.body.hasIntegrityEmitter && this.response.body,
}
let body = null
@@ -275,52 +269,31 @@ class CacheEntry {
cacheWriteReject = reject
})
- body = new MinipassPipeline(new MinipassFlush({
+ body = new CachingMinipassPipeline({ events: ['integrity', 'size'] }, new MinipassFlush({
flush () {
return cacheWritePromise
},
}))
-
- let abortStream, onResume
- if (shouldBuffer) {
- // if the result fits in memory, use a collect stream to gather
- // the response and write it to cacache while also passing it through
- // to the user
- onResume = () => {
- const collector = new MinipassCollect.PassThrough()
- abortStream = collector
- collector.on('collect', (data) => {
- // TODO if the cache write fails, log a warning but return the response anyway
- cacache.put(this.options.cachePath, this.key, data, cacheOpts)
- .then(cacheWriteResolve, cacheWriteReject)
- })
- body.unshift(collector)
- body.unshift(this.response.body)
- }
- } else {
- // if it does not fit in memory, create a tee stream and use
- // that to pipe to both the cache and the user simultaneously
- onResume = () => {
- const tee = new Minipass()
- const cacheStream = cacache.put.stream(this.options.cachePath, this.key, cacheOpts)
- abortStream = cacheStream
- tee.pipe(cacheStream)
- // TODO if the cache write fails, log a warning but return the response anyway
- cacheStream.promise().then(cacheWriteResolve, cacheWriteReject)
- body.unshift(tee)
- body.unshift(this.response.body)
- }
+ // this is always true since if we aren't reusing the one from the remote fetch, we
+ // are using the one from cacache
+ body.hasIntegrityEmitter = true
+
+ const onResume = () => {
+ const tee = new Minipass()
+ const cacheStream = cacache.put.stream(this.options.cachePath, this.key, cacheOpts)
+ // re-emit the integrity and size events on our new response body so they can be reused
+ cacheStream.on('integrity', i => body.emit('integrity', i))
+ cacheStream.on('size', s => body.emit('size', s))
+ // stick a flag on here so downstream users will know if they can expect integrity events
+ tee.pipe(cacheStream)
+ // TODO if the cache write fails, log a warning but return the response anyway
+ cacheStream.promise().then(cacheWriteResolve, cacheWriteReject)
+ body.unshift(tee)
+ body.unshift(this.response.body)
}
body.once('resume', onResume)
body.once('end', () => body.removeListener('resume', onResume))
- this.response.body.on('error', (err) => {
- // the abortStream will either be a MinipassCollect if we buffer
- // or a cacache write stream, either way be sure to listen for
- // errors from the actual response and avoid writing data that we
- // know to be invalid to the cache
- abortStream.destroy(err)
- })
} else {
await cacache.index.insert(this.options.cachePath, this.key, null, cacheOpts)
}
@@ -331,7 +304,7 @@ class CacheEntry {
// the header anyway
this.response.headers.set('x-local-cache', encodeURIComponent(this.options.cachePath))
this.response.headers.set('x-local-cache-key', encodeURIComponent(this.key))
- this.response.headers.set('x-local-cache-mode', shouldBuffer ? 'buffer' : 'stream')
+ this.response.headers.set('x-local-cache-mode', 'stream')
this.response.headers.set('x-local-cache-status', status)
this.response.headers.set('x-local-cache-time', new Date().toISOString())
const newResponse = new Response(body, {
@@ -346,9 +319,6 @@ class CacheEntry {
// use the cached data to create a response and return it
async respond (method, options, status) {
let response
- const size = Number(this.response.headers.get('content-length'))
- const fitsInMemory = !!size && size < MAX_MEM_SIZE
- const shouldBuffer = this.options.memoize !== false && fitsInMemory
if (method === 'HEAD' || [301, 308].includes(this.response.status)) {
// if the request is a HEAD, or the response is a redirect,
// then the metadata in the entry already includes everything
@@ -358,66 +328,44 @@ class CacheEntry {
// we're responding with a full cached response, so create a body
// that reads from cacache and attach it to a new Response
const body = new Minipass()
- const removeOnResume = () => body.removeListener('resume', onResume)
- let onResume
- if (shouldBuffer) {
- onResume = async () => {
- removeOnResume()
- try {
- const content = await cacache.get.byDigest(
+ const headers = { ...this.policy.responseHeaders() }
+ const onResume = () => {
+ const cacheStream = cacache.get.stream.byDigest(
+ this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize }
+ )
+ cacheStream.on('error', async (err) => {
+ cacheStream.pause()
+ if (err.code === 'EINTEGRITY') {
+ await cacache.rm.content(
this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize }
)
- body.end(content)
- } catch (err) {
- if (err.code === 'EINTEGRITY') {
- await cacache.rm.content(
- this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize }
- )
- }
- if (err.code === 'ENOENT' || err.code === 'EINTEGRITY') {
- await CacheEntry.invalidate(this.request, this.options)
- }
- body.emit('error', err)
}
- }
- } else {
- onResume = () => {
- const cacheStream = cacache.get.stream.byDigest(
- this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize }
- )
- cacheStream.on('error', async (err) => {
- cacheStream.pause()
- if (err.code === 'EINTEGRITY') {
- await cacache.rm.content(
- this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize }
- )
- }
- if (err.code === 'ENOENT' || err.code === 'EINTEGRITY') {
- await CacheEntry.invalidate(this.request, this.options)
- }
- body.emit('error', err)
- cacheStream.resume()
- })
- cacheStream.pipe(body)
- }
+ if (err.code === 'ENOENT' || err.code === 'EINTEGRITY') {
+ await CacheEntry.invalidate(this.request, this.options)
+ }
+ body.emit('error', err)
+ cacheStream.resume()
+ })
+ // emit the integrity and size events based on our metadata so we're consistent
+ body.emit('integrity', this.entry.integrity)
+ body.emit('size', Number(headers['content-length']))
+ cacheStream.pipe(body)
}
body.once('resume', onResume)
- body.once('end', removeOnResume)
+ body.once('end', () => body.removeListener('resume', onResume))
response = new Response(body, {
url: this.entry.metadata.url,
counter: options.counter,
status: 200,
- headers: {
- ...this.policy.responseHeaders(),
- },
+ headers,
})
}
response.headers.set('x-local-cache', encodeURIComponent(this.options.cachePath))
response.headers.set('x-local-cache-hash', encodeURIComponent(this.entry.integrity))
response.headers.set('x-local-cache-key', encodeURIComponent(this.key))
- response.headers.set('x-local-cache-mode', shouldBuffer ? 'buffer' : 'stream')
+ response.headers.set('x-local-cache-mode', 'stream')
response.headers.set('x-local-cache-status', status)
response.headers.set('x-local-cache-time', new Date(this.entry.metadata.time).toUTCString())
return response
diff --git a/deps/npm/node_modules/make-fetch-happen/lib/pipeline.js b/deps/npm/node_modules/make-fetch-happen/lib/pipeline.js
new file mode 100644
index 0000000000..b1d221b2d0
--- /dev/null
+++ b/deps/npm/node_modules/make-fetch-happen/lib/pipeline.js
@@ -0,0 +1,41 @@
+'use strict'
+
+const MinipassPipeline = require('minipass-pipeline')
+
+class CachingMinipassPipeline extends MinipassPipeline {
+ #events = []
+ #data = new Map()
+
+ constructor (opts, ...streams) {
+ // CRITICAL: do NOT pass the streams to the call to super(), this will start
+ // the flow of data and potentially cause the events we need to catch to emit
+ // before we've finished our own setup. instead we call super() with no args,
+ // finish our setup, and then push the streams into ourselves to start the
+ // data flow
+ super()
+ this.#events = opts.events
+
+ /* istanbul ignore next - coverage disabled because this is pointless to test here */
+ if (streams.length) {
+ this.push(...streams)
+ }
+ }
+
+ on (event, handler) {
+ if (this.#events.includes(event) && this.#data.has(event)) {
+ return handler(...this.#data.get(event))
+ }
+
+ return super.on(event, handler)
+ }
+
+ emit (event, ...data) {
+ if (this.#events.includes(event)) {
+ this.#data.set(event, data)
+ }
+
+ return super.emit(event, ...data)
+ }
+}
+
+module.exports = CachingMinipassPipeline
diff --git a/deps/npm/node_modules/make-fetch-happen/lib/remote.js b/deps/npm/node_modules/make-fetch-happen/lib/remote.js
index a8b8d2a019..763fc0d488 100644
--- a/deps/npm/node_modules/make-fetch-happen/lib/remote.js
+++ b/deps/npm/node_modules/make-fetch-happen/lib/remote.js
@@ -1,9 +1,9 @@
const Minipass = require('minipass')
-const MinipassPipeline = require('minipass-pipeline')
const fetch = require('minipass-fetch')
const promiseRetry = require('promise-retry')
const ssri = require('ssri')
+const CachingMinipassPipeline = require('./pipeline.js')
const getAgent = require('./agent.js')
const pkg = require('../package.json')
@@ -53,7 +53,16 @@ const remoteFetch = (request, options) => {
// we got a 200 response and the user has specified an expected
// integrity value, so wrap the response in an ssri stream to verify it
const integrityStream = ssri.integrityStream({ integrity: _opts.integrity })
- res = new fetch.Response(new MinipassPipeline(res.body, integrityStream), res)
+ const pipeline = new CachingMinipassPipeline({
+ events: ['integrity', 'size'],
+ }, res.body, integrityStream)
+ // we also propagate the integrity and size events out to the pipeline so we can use
+ // this new response body as an integrityEmitter for cacache
+ integrityStream.on('integrity', i => pipeline.emit('integrity', i))
+ integrityStream.on('size', s => pipeline.emit('size', s))
+ res = new fetch.Response(pipeline, res)
+ // set an explicit flag so we know if our response body will emit integrity and size
+ res.body.hasIntegrityEmitter = true
}
res.headers.set('x-fetch-attempts', attemptNum)
diff --git a/deps/npm/node_modules/make-fetch-happen/package.json b/deps/npm/node_modules/make-fetch-happen/package.json
index e1e8e97518..2e6153b99f 100644
--- a/deps/npm/node_modules/make-fetch-happen/package.json
+++ b/deps/npm/node_modules/make-fetch-happen/package.json
@@ -1,6 +1,6 @@
{
"name": "make-fetch-happen",
- "version": "10.1.3",
+ "version": "10.1.5",
"description": "Opinionated, caching, retrying fetch client",
"main": "lib/index.js",
"files": [
@@ -37,7 +37,7 @@
"license": "ISC",
"dependencies": {
"agentkeepalive": "^4.2.1",
- "cacache": "^16.0.2",
+ "cacache": "^16.1.0",
"http-cache-semantics": "^4.1.0",
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
@@ -55,7 +55,7 @@
},
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
- "@npmcli/template-oss": "3.4.3",
+ "@npmcli/template-oss": "3.5.0",
"mkdirp": "^1.0.4",
"nock": "^13.2.4",
"rimraf": "^3.0.2",
@@ -73,6 +73,6 @@
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
- "version": "3.4.3"
+ "version": "3.5.0"
}
}
diff --git a/deps/npm/node_modules/npm-packlist/lib/index.js b/deps/npm/node_modules/npm-packlist/lib/index.js
index c7b0db5f60..e4a2e76c54 100644
--- a/deps/npm/node_modules/npm-packlist/lib/index.js
+++ b/deps/npm/node_modules/npm-packlist/lib/index.js
@@ -33,6 +33,33 @@ const fs = require('fs')
const glob = require('glob')
const globify = pattern => pattern.split('\\').join('/')
+const readOutOfTreeIgnoreFiles = (root, rel, result = '') => {
+ for (const file of ['.gitignore', '.npmignore']) {
+ try {
+ const ignoreContent = fs.readFileSync(path.join(root, file), { encoding: 'utf8' })
+ result += ignoreContent + '\n'
+ } catch (err) {
+ // we ignore ENOENT errors completely because we don't care if the file doesn't exist
+ // but we throw everything else because failing to read a file that does exist is
+ // something that the user likely wants to know about. we don't need to test this.
+ /* istanbul ignore next */
+ if (err.code !== 'ENOENT') {
+ throw err
+ }
+ }
+ }
+
+ if (!rel) {
+ return result
+ }
+
+ const firstRel = rel.split(path.sep)[0]
+ const newRoot = path.join(root, firstRel)
+ const newRel = path.relative(newRoot, path.join(root, rel))
+
+ return readOutOfTreeIgnoreFiles(newRoot, newRel, result)
+}
+
const pathHasPkg = (input) => {
if (!input.startsWith('node_modules/')) {
return false
@@ -119,9 +146,31 @@ class Walker extends IgnoreWalker {
this.bundledScopes = Array.from(new Set(
this.bundled.filter(f => /^@/.test(f))
.map(f => f.split('/')[0])))
- const rules = defaultRules.join('\n') + '\n'
this.packageJsonCache = this.parent ? this.parent.packageJsonCache
: (opt.packageJsonCache || new Map())
+ let rules = defaultRules.join('\n') + '\n'
+
+ if (opt.prefix && opt.workspaces) {
+ const gPath = globify(opt.path)
+ const gPrefix = globify(opt.prefix)
+ const gWorkspaces = opt.workspaces.map((ws) => globify(ws))
+ // if opt.path and opt.prefix are not the same directory, and opt.workspaces has opt.path
+ // in it, then we know that opt.path is a workspace directory. in order to not drop ignore
+ // rules from directories between the workspace root (opt.prefix) and the workspace itself
+ // (opt.path), we need to find and read those now
+ /* istanbul ignore else */
+ if (gPath !== gPrefix && gWorkspaces.includes(gPath)) {
+ // relpath is the relative path between the prefix and the parent of opt.path
+ // we use the parent because ignore-walk will read the files in opt.path already
+ const relpath = path.relative(opt.prefix, path.dirname(opt.path))
+ rules += readOutOfTreeIgnoreFiles(opt.prefix, relpath)
+ } else if (gPath === gPrefix) {
+ // on the other hand, if the path and the prefix are the same, then we ignore workspaces
+ // so that we don't pack workspaces inside of a root project
+ rules += opt.workspaces.map((ws) => globify(path.relative(opt.path, ws))).join('\n')
+ }
+ }
+
super.onReadIgnoreFile(rootBuiltinRules, rules, _ => _)
} else {
this.bundled = []
diff --git a/deps/npm/node_modules/npm-packlist/package.json b/deps/npm/node_modules/npm-packlist/package.json
index e79d1d4b82..dfa0188b4c 100644
--- a/deps/npm/node_modules/npm-packlist/package.json
+++ b/deps/npm/node_modules/npm-packlist/package.json
@@ -1,6 +1,6 @@
{
"name": "npm-packlist",
- "version": "5.0.3",
+ "version": "5.1.0",
"description": "Get a list of the files to add from a folder into an npm package",
"directories": {
"test": "test"
@@ -20,7 +20,7 @@
],
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
- "@npmcli/template-oss": "3.4.2",
+ "@npmcli/template-oss": "3.5.0",
"mutate-fs": "^2.1.1",
"tap": "^16.0.1"
},
@@ -56,6 +56,6 @@
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
- "version": "3.4.2"
+ "version": "3.5.0"
}
}
diff --git a/deps/npm/node_modules/pacote/README.md b/deps/npm/node_modules/pacote/README.md
index 11822dbb48..eac48f69fe 100644
--- a/deps/npm/node_modules/pacote/README.md
+++ b/deps/npm/node_modules/pacote/README.md
@@ -168,6 +168,10 @@ resolved, and other properties, as they are determined.
is unlikely to change in the span of a single command.
* `silent` A boolean that determines whether the banner is displayed
when calling `@npmcli/run-script`.
+* `verifySignatures` A boolean that will make pacote verify the
+ integrity signature of a manifest, if present. There must be a
+ configured `_keys` entry in the config that is scoped to the
+ registry the manifest is being fetched from.
### Advanced API
diff --git a/deps/npm/node_modules/pacote/lib/dir.js b/deps/npm/node_modules/pacote/lib/dir.js
index 598b029f7a..502379810a 100644
--- a/deps/npm/node_modules/pacote/lib/dir.js
+++ b/deps/npm/node_modules/pacote/lib/dir.js
@@ -63,10 +63,12 @@ class DirFetcher extends Fetcher {
stream.resolved = this.resolved
stream.integrity = this.integrity
+ const { prefix, workspaces } = this.opts
+
// run the prepare script, get the list of files, and tar it up
// pipe to the stream, and proxy errors the chain.
this[_prepareDir]()
- .then(() => packlist({ path: this.resolved }))
+ .then(() => packlist({ path: this.resolved, prefix, workspaces }))
.then(files => tar.c(tarCreateOptions(this.package), files)
.on('error', er => stream.emit('error', er)).pipe(stream))
.catch(er => stream.emit('error', er))
diff --git a/deps/npm/node_modules/pacote/lib/registry.js b/deps/npm/node_modules/pacote/lib/registry.js
index e8ca16f596..2eb37bcecc 100644
--- a/deps/npm/node_modules/pacote/lib/registry.js
+++ b/deps/npm/node_modules/pacote/lib/registry.js
@@ -7,6 +7,7 @@ const npa = require('npm-package-arg')
const rpj = require('read-package-json-fast')
const pickManifest = require('npm-pick-manifest')
const ssri = require('ssri')
+const crypto = require('crypto')
// Corgis are cute. 🐕🐶
const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*'
@@ -14,8 +15,6 @@ const fullDoc = 'application/json'
const fetch = require('npm-registry-fetch')
-// TODO: memoize reg requests, so we don't even have to check cache
-
const _headers = Symbol('_headers')
class RegistryFetcher extends Fetcher {
constructor (spec, opts) {
@@ -39,28 +38,30 @@ class RegistryFetcher extends Fetcher {
this.packumentUrl = removeTrailingSlashes(this.registry) + '/' +
this.spec.escapedName
+ const parsed = new URL(this.registry)
+ const regKey = `//${parsed.host}${parsed.pathname}`
+ // unlike the nerf-darted auth keys, this one does *not* allow a mismatch
+ // of trailing slashes. It must match exactly.
+ if (this.opts[`${regKey}:_keys`]) {
+ this.registryKeys = this.opts[`${regKey}:_keys`]
+ }
+
// XXX pacote <=9 has some logic to ignore opts.resolved if
// the resolved URL doesn't go to the same registry.
// Consider reproducing that here, to throw away this.resolved
// in that case.
}
- resolve () {
- if (this.resolved) {
- return Promise.resolve(this.resolved)
- }
-
- // fetching the manifest sets resolved and (usually) integrity
- return this.manifest().then(() => {
- if (this.resolved) {
- return this.resolved
- }
-
+ async resolve () {
+ // fetching the manifest sets resolved and (if present) integrity
+ await this.manifest()
+ if (!this.resolved) {
throw Object.assign(
new Error('Invalid package manifest: no `dist.tarball` field'),
{ package: this.spec.toString() }
)
- })
+ }
+ return this.resolved
}
[_headers] () {
@@ -87,91 +88,127 @@ class RegistryFetcher extends Fetcher {
// npm-registry-fetch the packument
// set the appropriate header for corgis if fullMetadata isn't set
// return the res.json() promise
- const p = fetch(this.packumentUrl, {
- ...this.opts,
- headers: this[_headers](),
- spec: this.spec,
- // never check integrity for packuments themselves
- integrity: null,
- }).then(res => res.json().then(packument => {
+ try {
+ const res = await fetch(this.packumentUrl, {
+ ...this.opts,
+ headers: this[_headers](),
+ spec: this.spec,
+ // never check integrity for packuments themselves
+ integrity: null,
+ })
+ const packument = await res.json()
packument._cached = res.headers.has('x-local-cache')
packument._contentLength = +res.headers.get('content-length')
if (this.packumentCache) {
this.packumentCache.set(this.packumentUrl, packument)
}
return packument
- })).catch(er => {
+ } catch (err) {
if (this.packumentCache) {
this.packumentCache.delete(this.packumentUrl)
}
- if (er.code === 'E404' && !this.fullMetadata) {
- // possible that corgis are not supported by this registry
- this.fullMetadata = true
- return this.packument()
+ if (err.code !== 'E404' || this.fullMetadata) {
+ throw err
}
- throw er
- })
- if (this.packumentCache) {
- this.packumentCache.set(this.packumentUrl, p)
+ // possible that corgis are not supported by this registry
+ this.fullMetadata = true
+ return this.packument()
}
- return p
}
- manifest () {
+ async manifest () {
if (this.package) {
- return Promise.resolve(this.package)
+ return this.package
}
- return this.packument()
- .then(packument => pickManifest(packument, this.spec.fetchSpec, {
- ...this.opts,
- defaultTag: this.defaultTag,
- before: this.before,
- }) /* XXX add ETARGET and E403 revalidation of cached packuments here */)
- .then(mani => {
- // add _resolved and _integrity from dist object
- const { dist } = mani
- if (dist) {
- this.resolved = mani._resolved = dist.tarball
- mani._from = this.from
- const distIntegrity = dist.integrity ? ssri.parse(dist.integrity)
- : dist.shasum ? ssri.fromHex(dist.shasum, 'sha1', { ...this.opts })
- : null
- if (distIntegrity) {
- if (!this.integrity) {
- this.integrity = distIntegrity
- } else if (!this.integrity.match(distIntegrity)) {
- // only bork if they have algos in common.
- // otherwise we end up breaking if we have saved a sha512
- // previously for the tarball, but the manifest only
- // provides a sha1, which is possible for older publishes.
- // Otherwise, this is almost certainly a case of holding it
- // wrong, and will result in weird or insecure behavior
- // later on when building package tree.
- for (const algo of Object.keys(this.integrity)) {
- if (distIntegrity[algo]) {
- throw Object.assign(new Error(
- `Integrity checksum failed when using ${algo}: ` +
- `wanted ${this.integrity} but got ${distIntegrity}.`
- ), { code: 'EINTEGRITY' })
- }
- }
- // made it this far, the integrity is worthwhile. accept it.
- // the setter here will take care of merging it into what we
- // already had.
- this.integrity = distIntegrity
+ const packument = await this.packument()
+ const mani = await pickManifest(packument, this.spec.fetchSpec, {
+ ...this.opts,
+ defaultTag: this.defaultTag,
+ before: this.before,
+ })
+ /* XXX add ETARGET and E403 revalidation of cached packuments here */
+
+ // add _resolved and _integrity from dist object
+ const { dist } = mani
+ if (dist) {
+ this.resolved = mani._resolved = dist.tarball
+ mani._from = this.from
+ const distIntegrity = dist.integrity ? ssri.parse(dist.integrity)
+ : dist.shasum ? ssri.fromHex(dist.shasum, 'sha1', { ...this.opts })
+ : null
+ if (distIntegrity) {
+ if (this.integrity && !this.integrity.match(distIntegrity)) {
+ // only bork if they have algos in common.
+ // otherwise we end up breaking if we have saved a sha512
+ // previously for the tarball, but the manifest only
+ // provides a sha1, which is possible for older publishes.
+ // Otherwise, this is almost certainly a case of holding it
+ // wrong, and will result in weird or insecure behavior
+ // later on when building package tree.
+ for (const algo of Object.keys(this.integrity)) {
+ if (distIntegrity[algo]) {
+ throw Object.assign(new Error(
+ `Integrity checksum failed when using ${algo}: ` +
+ `wanted ${this.integrity} but got ${distIntegrity}.`
+ ), { code: 'EINTEGRITY' })
}
}
}
- if (this.integrity) {
- mani._integrity = String(this.integrity)
- if (dist.signatures) {
+ // made it this far, the integrity is worthwhile. accept it.
+ // the setter here will take care of merging it into what we already
+ // had.
+ this.integrity = distIntegrity
+ }
+ }
+ if (this.integrity) {
+ mani._integrity = String(this.integrity)
+ if (dist.signatures) {
+ if (this.opts.verifySignatures) {
+ if (this.registryKeys) {
+ // validate and throw on error, then set _signatures
+ const message = `${mani._id}:${mani._integrity}`
+ for (const signature of dist.signatures) {
+ const publicKey = this.registryKeys.filter(key => (key.keyid === signature.keyid))[0]
+ if (!publicKey) {
+ throw Object.assign(new Error(
+ `${mani._id} has a signature with keyid: ${signature.keyid} ` +
+ 'but no corresponding public key can be found.'
+ ), { code: 'EMISSINGSIGNATUREKEY' })
+ }
+ const validPublicKey =
+ !publicKey.expires || (Date.parse(publicKey.expires) > Date.now())
+ if (!validPublicKey) {
+ throw Object.assign(new Error(
+ `${mani._id} has a signature with keyid: ${signature.keyid} ` +
+ `but the corresponding public key has expired ${publicKey.expires}`
+ ), { code: 'EEXPIREDSIGNATUREKEY' })
+ }
+ const verifier = crypto.createVerify('SHA256')
+ verifier.write(message)
+ verifier.end()
+ const valid = verifier.verify(
+ publicKey.pemkey,
+ signature.sig,
+ 'base64'
+ )
+ if (!valid) {
+ throw Object.assign(new Error(
+ 'Integrity checksum signature failed: ' +
+ `key ${publicKey.keyid} signature ${signature.sig}`
+ ), { code: 'EINTEGRITYSIGNATURE' })
+ }
+ }
mani._signatures = dist.signatures
}
+ // if no keys, don't set _signatures
+ } else {
+ mani._signatures = dist.signatures
}
- this.package = rpj.normalize(mani)
- return this.package
- })
+ }
+ }
+ this.package = rpj.normalize(mani)
+ return this.package
}
[_tarballFromResolved] () {
diff --git a/deps/npm/node_modules/pacote/package.json b/deps/npm/node_modules/pacote/package.json
index 2f4323c441..5045e3f06a 100644
--- a/deps/npm/node_modules/pacote/package.json
+++ b/deps/npm/node_modules/pacote/package.json
@@ -1,6 +1,6 @@
{
"name": "pacote",
- "version": "13.3.0",
+ "version": "13.5.0",
"description": "JavaScript package downloader",
"author": "GitHub Inc.",
"bin": {
@@ -26,7 +26,7 @@
},
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
- "@npmcli/template-oss": "3.4.3",
+ "@npmcli/template-oss": "3.5.0",
"hosted-git-info": "^5.0.0",
"mutate-fs": "^2.1.1",
"nock": "^13.2.4",
@@ -54,7 +54,7 @@
"minipass": "^3.1.6",
"mkdirp": "^1.0.4",
"npm-package-arg": "^9.0.0",
- "npm-packlist": "^5.0.0",
+ "npm-packlist": "^5.1.0",
"npm-pick-manifest": "^7.0.0",
"npm-registry-fetch": "^13.0.1",
"proc-log": "^2.0.0",
@@ -74,7 +74,7 @@
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
- "version": "3.4.3",
+ "version": "3.5.0",
"windowsCI": false
}
}
diff --git a/deps/npm/node_modules/ssri/lib/index.js b/deps/npm/node_modules/ssri/lib/index.js
index e2732fd072..1443137cbc 100644
--- a/deps/npm/node_modules/ssri/lib/index.js
+++ b/deps/npm/node_modules/ssri/lib/index.js
@@ -30,6 +30,10 @@ const getOptString = options => !options || !options.length
const _onEnd = Symbol('_onEnd')
const _getOptions = Symbol('_getOptions')
+const _emittedSize = Symbol('_emittedSize')
+const _emittedIntegrity = Symbol('_emittedIntegrity')
+const _emittedVerified = Symbol('_emittedVerified')
+
class IntegrityStream extends MiniPass {
constructor (opts) {
super()
@@ -63,6 +67,22 @@ class IntegrityStream extends MiniPass {
this.optString = getOptString(options)
}
+ on (ev, handler) {
+ if (ev === 'size' && this[_emittedSize]) {
+ return handler(this[_emittedSize])
+ }
+
+ if (ev === 'integrity' && this[_emittedIntegrity]) {
+ return handler(this[_emittedIntegrity])
+ }
+
+ if (ev === 'verified' && this[_emittedVerified]) {
+ return handler(this[_emittedVerified])
+ }
+
+ return super.on(ev, handler)
+ }
+
emit (ev, data) {
if (ev === 'end') {
this[_onEnd]()
@@ -103,9 +123,14 @@ class IntegrityStream extends MiniPass {
err.sri = this.sri
this.emit('error', err)
} else {
+ this[_emittedSize] = this.size
this.emit('size', this.size)
+ this[_emittedIntegrity] = newSri
this.emit('integrity', newSri)
- match && this.emit('verified', match)
+ if (match) {
+ this[_emittedVerified] = match
+ this.emit('verified', match)
+ }
}
}
}
diff --git a/deps/npm/node_modules/ssri/package.json b/deps/npm/node_modules/ssri/package.json
index 84448afc3c..91c1f91978 100644
--- a/deps/npm/node_modules/ssri/package.json
+++ b/deps/npm/node_modules/ssri/package.json
@@ -1,6 +1,6 @@
{
"name": "ssri",
- "version": "9.0.0",
+ "version": "9.0.1",
"description": "Standard Subresource Integrity library -- parses, serializes, generates, and verifies integrity metadata according to the SRI spec.",
"main": "lib/index.js",
"files": [
@@ -50,7 +50,7 @@
},
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
- "@npmcli/template-oss": "3.2.2",
+ "@npmcli/template-oss": "3.5.0",
"tap": "^16.0.1"
},
"engines": {
@@ -58,6 +58,6 @@
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
- "version": "3.2.2"
+ "version": "3.5.0"
}
}
diff --git a/deps/npm/package.json b/deps/npm/package.json
index e654f94102..f616f038db 100644
--- a/deps/npm/package.json
+++ b/deps/npm/package.json
@@ -1,5 +1,5 @@
{
- "version": "8.10.0",
+ "version": "8.11.0",
"name": "npm",
"description": "a package manager for JavaScript",
"workspaces": [
@@ -65,7 +65,7 @@
"@npmcli/run-script": "^3.0.1",
"abbrev": "~1.1.1",
"archy": "~1.0.0",
- "cacache": "^16.0.7",
+ "cacache": "^16.1.0",
"chalk": "^4.1.2",
"chownr": "^2.0.0",
"cli-columns": "^4.0.0",
@@ -90,7 +90,7 @@
"libnpmsearch": "^5.0.2",
"libnpmteam": "^4.0.2",
"libnpmversion": "^3.0.1",
- "make-fetch-happen": "^10.1.3",
+ "make-fetch-happen": "^10.1.5",
"minipass": "^3.1.6",
"minipass-pipeline": "^1.2.4",
"mkdirp": "^1.0.4",
@@ -107,7 +107,7 @@
"npm-user-validate": "^1.0.1",
"npmlog": "^6.0.2",
"opener": "^1.5.2",
- "pacote": "^13.3.0",
+ "pacote": "^13.4.1",
"parse-conflict-json": "^2.0.2",
"proc-log": "^2.0.1",
"qrcode-terminal": "^0.12.0",
@@ -117,7 +117,7 @@
"readdir-scoped-modules": "^1.1.0",
"rimraf": "^3.0.2",
"semver": "^7.3.7",
- "ssri": "^9.0.0",
+ "ssri": "^9.0.1",
"tar": "^6.1.11",
"text-table": "~0.2.0",
"tiny-relative-date": "^1.3.0",
diff --git a/deps/npm/tap-snapshots/test/lib/commands/cache.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/cache.js.test.cjs
new file mode 100644
index 0000000000..1cd6994534
--- /dev/null
+++ b/deps/npm/tap-snapshots/test/lib/commands/cache.js.test.cjs
@@ -0,0 +1,63 @@
+/* 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/commands/cache.js TAP cache ls > logs cache entries 1`] = `
+make-fetch-happen:request-cache:https://registry.npmjs.org/test-package
+make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz
+`
+
+exports[`test/lib/commands/cache.js TAP cache ls corrupted > logs cache entries with bad data 1`] = `
+make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted
+make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted/-/corrupted-3.1.0.tgz
+`
+
+exports[`test/lib/commands/cache.js TAP cache ls missing packument version not an object > logs cache entry for packument 1`] = `
+make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version
+`
+
+exports[`test/lib/commands/cache.js TAP cache ls nonpublic registry > logs cache entry for extemporaneously and its tarball 1`] = `
+make-fetch-happen:request-cache:https://somerepo.github.org/aabbcc/
+make-fetch-happen:request-cache:https://somerepo.github.org/extemporaneously
+`
+
+exports[`test/lib/commands/cache.js TAP cache ls pkgs > logs cache entries for npm and webpack and one webpack tgz 1`] = `
+make-fetch-happen:request-cache:https://registry.npmjs.org/npm
+make-fetch-happen:request-cache:https://registry.npmjs.org/npm/-/npm-1.2.0.tgz
+make-fetch-happen:request-cache:https://registry.npmjs.org/webpack
+make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz
+`
+
+exports[`test/lib/commands/cache.js TAP cache ls scoped and scoped slash > logs cache entries for @gar and @fritzy 1`] = `
+make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy%2fstaydown
+make-fetch-happen:request-cache:https://registry.npmjs.org/@gar%2fnpm-expansion
+`
+
+exports[`test/lib/commands/cache.js TAP cache ls special > logs cache entries for foo 1`] = `
+make-fetch-happen:request-cache:https://registry.npmjs.org/foo
+make-fetch-happen:request-cache:https://registry.npmjs.org/foo/-/foo-1.2.3-beta.tgz
+`
+
+exports[`test/lib/commands/cache.js TAP cache rm > logs deleting single entry 1`] = `
+Deleted: make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz
+`
+
+exports[`test/lib/commands/cache.js TAP cache verify > shows verified cache output 1`] = `
+Cache verified and compressed ({PATH})
+Content verified: 0 (0 bytes)
+Index entries: 0
+Finished in xxxs
+`
+
+exports[`test/lib/commands/cache.js TAP cache verify w/ extra output > shows extra output 1`] = `
+Cache verified and compressed ({PATH})
+Content verified: 17057 (1644485260 bytes)
+Corrupted content removed: 12345
+Content garbage-collected: 1144 (248164665 bytes)
+Missing content: 92
+Index entries: 20175
+Finished in xxxs
+`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/ci.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/ci.js.test.cjs
deleted file mode 100644
index d6a7471778..0000000000
--- a/deps/npm/tap-snapshots/test/lib/commands/ci.js.test.cjs
+++ /dev/null
@@ -1,13 +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/commands/ci.js TAP should throw error when ideal inventory mismatches virtual > must match snapshot 1`] = `
-\`npm ci\` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with \`npm install\` before continuing.
-
-Invalid: lock file's foo@1.0.0 does not satisfy foo@2.0.0
-
-`
diff --git a/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs
index 20915cdd87..b8c274b085 100644
--- a/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs
@@ -69,7 +69,7 @@ Run "npm help bin" for more info
`
exports[`test/lib/load-all-commands.js TAP load each command birthday > must match snapshot 1`] = `
-Birthday
+Birthday, deprecated
Usage:
npm birthday
@@ -113,7 +113,7 @@ Run "npm help cache" for more info
`
exports[`test/lib/load-all-commands.js TAP load each command ci > must match snapshot 1`] = `
-Install a project with a clean slate
+Clean install a project
Usage:
npm ci
@@ -802,7 +802,7 @@ Run "npm help set" for more info
`
exports[`test/lib/load-all-commands.js TAP load each command set-script > must match snapshot 1`] = `
-Set tasks in the scripts section of package.json
+Set tasks in the scripts section of package.json, deprecated
Usage:
npm set-script [<script>] [<command>]
diff --git a/deps/npm/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs b/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs
index 8d7dbfedc3..c7c75ce84b 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs
@@ -5,7 +5,7 @@
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
-exports[`test/lib/utils/npm-usage.js TAP usage basic usage > must match snapshot 1`] = `
+exports[`test/lib/npm.js TAP usage basic usage > must match snapshot 1`] = `
npm <command>
Usage:
@@ -41,7 +41,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`
-exports[`test/lib/utils/npm-usage.js TAP usage set process.stdout.columns columns=0 > must match snapshot 1`] = `
+exports[`test/lib/npm.js TAP usage set process.stdout.columns columns=0 > must match snapshot 1`] = `
npm <command>
Usage:
@@ -77,7 +77,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`
-exports[`test/lib/utils/npm-usage.js TAP usage set process.stdout.columns columns=90 > must match snapshot 1`] = `
+exports[`test/lib/npm.js TAP usage set process.stdout.columns columns=90 > must match snapshot 1`] = `
npm <command>
Usage:
@@ -113,7 +113,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`
-exports[`test/lib/utils/npm-usage.js TAP usage with browser > must match snapshot 1`] = `
+exports[`test/lib/npm.js TAP usage with browser > must match snapshot 1`] = `
npm <command>
Usage:
@@ -149,7 +149,7 @@ Configuration fields: npm help 7 config
npm@{VERSION} {BASEDIR}
`
-exports[`test/lib/utils/npm-usage.js TAP usage with long > must match snapshot 1`] = `
+exports[`test/lib/npm.js TAP usage with long > must match snapshot 1`] = `
npm <command>
Usage:
@@ -166,7 +166,7 @@ npm help npm more involved overview
All commands:
access Set access level on published packages
-
+
Usage:
npm access public [<package>]
npm access restricted [<package>]
@@ -177,29 +177,29 @@ All commands:
npm access ls-packages [<user>|<scope>|<scope:team>]
npm access ls-collaborators [<package> [<user>]]
npm access edit [<package>]
-
+
Options:
[--registry <registry>] [--otp <otp>]
-
+
Run "npm help access" for more info
adduser Add a registry user account
-
+
Usage:
npm adduser
-
+
Options:
[--registry <registry>] [--scope <@scope>]
-
+
aliases: login, add-user
-
+
Run "npm help adduser" for more info
audit Run a security audit
-
+
Usage:
npm audit [fix]
-
+
Options:
[--audit-level <info|low|moderate|high|critical|none>] [--dry-run] [-f|--force]
[--json] [--package-lock-only]
@@ -207,35 +207,35 @@ All commands:
[--foreground-scripts] [--ignore-scripts]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
Run "npm help audit" for more info
bin Display npm bin folder
-
+
Usage:
npm bin
-
+
Options:
[-g|--global]
-
+
Run "npm help bin" for more info
bugs Report bugs for a package in a web browser
-
+
Usage:
npm bugs [<pkgname> [<pkgname> ...]]
-
+
Options:
[--no-browser|--browser <browser>] [--registry <registry>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
alias: issues
-
+
Run "npm help bugs" for more info
cache Manipulates packages cache
-
+
Usage:
npm cache add <tarball file>
npm cache add <folder>
@@ -245,80 +245,80 @@ All commands:
npm cache clean [<key>]
npm cache ls [<name>@<version>]
npm cache verify
-
+
Options:
[--cache <cache>]
-
+
Run "npm help cache" for more info
- ci Install a project with a clean slate
-
+ ci Clean install a project
+
Usage:
npm ci
-
+
Options:
[--no-audit] [--foreground-scripts] [--ignore-scripts]
[--script-shell <script-shell>]
-
+
aliases: clean-install, ic, install-clean, isntall-clean
-
+
Run "npm help ci" for more info
completion Tab Completion for npm
-
+
Usage:
npm completion
-
+
Run "npm help completion" for more info
config Manage the npm configuration files
-
+
Usage:
npm config set <key>=<value> [<key>=<value> ...]
npm config get [<key> [<key> ...]]
npm config delete <key> [<key> ...]
npm config list [--json]
npm config edit
-
+
Options:
[--json] [-g|--global] [--editor <editor>] [-L|--location <global|user|project>]
[-l|--long]
-
+
alias: c
-
+
Run "npm help config" for more info
dedupe Reduce duplication in the package tree
-
+
Usage:
npm dedupe
-
+
Options:
[--global-style] [--legacy-bundling] [--strict-peer-deps] [--no-package-lock]
[--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts]
[--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
alias: ddp
-
+
Run "npm help dedupe" for more info
deprecate Deprecate a version of a package
-
+
Usage:
npm deprecate <pkg>[@<version>] <message>
-
+
Options:
[--registry <registry>] [--otp <otp>]
-
+
Run "npm help deprecate" for more info
diff The registry diff command
-
+
Usage:
npm diff [...<paths>]
-
+
Options:
[--diff <pkg-name|spec|version> [--diff <pkg-name|spec|version> ...]]
[--diff-name-only] [--diff-unified <number>] [--diff-ignore-all-space]
@@ -326,174 +326,174 @@ All commands:
[--diff-text] [-g|--global] [--tag <tag>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
Run "npm help diff" for more info
dist-tag Modify package distribution tags
-
+
Usage:
npm dist-tag add <pkg>@<version> [<tag>]
npm dist-tag rm <pkg> <tag>
npm dist-tag ls [<pkg>]
-
+
Options:
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
alias: dist-tags
-
+
Run "npm help dist-tag" for more info
docs Open documentation for a package in a web browser
-
+
Usage:
npm docs [<pkgname> [<pkgname> ...]]
-
+
Options:
[--no-browser|--browser <browser>] [--registry <registry>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
alias: home
-
+
Run "npm help docs" for more info
doctor Check your npm environment
-
+
Usage:
npm doctor
-
+
Options:
[--registry <registry>]
-
+
Run "npm help doctor" for more info
edit Edit an installed package
-
+
Usage:
npm edit <pkg>[/<subpkg>...]
-
+
Options:
[--editor <editor>]
-
+
Run "npm help edit" for more info
exec Run a command from a local or remote npm package
-
+
Usage:
npm exec -- <pkg>[@<version>] [args...]
npm exec --package=<pkg>[@<version>] -- <cmd> [args...]
npm exec -c '<cmd> [args...]'
npm exec --package=foo -c '<cmd> [args...]'
-
+
Options:
[--package <pkg>[@<version>] [--package <pkg>[@<version>] ...]]
[-c|--call <call>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
alias: x
-
+
Run "npm help exec" for more info
explain Explain installed packages
-
+
Usage:
npm explain <folder | specifier>
-
+
Options:
[--json] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
-
+
alias: why
-
+
Run "npm help explain" for more info
explore Browse an installed package
-
+
Usage:
npm explore <pkg> [ -- <command>]
-
+
Options:
[--shell <shell>]
-
+
Run "npm help explore" for more info
find-dupes Find duplication in the package tree
-
+
Usage:
npm find-dupes
-
+
Options:
[--global-style] [--legacy-bundling] [--strict-peer-deps] [--no-package-lock]
[--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts]
[--no-audit] [--no-bin-links] [--no-fund]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
Run "npm help find-dupes" for more info
fund Retrieve funding information
-
+
Usage:
npm fund [[<@scope>/]<pkg>]
-
+
Options:
[--json] [--no-browser|--browser <browser>] [--unicode]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[--which <fundingSourceNumber>]
-
+
Run "npm help fund" for more info
get Get a value from the npm configuration
-
+
Usage:
npm get [<key> ...] (See \`npm config\`)
-
+
Run "npm help get" for more info
help Get help on npm
-
+
Usage:
npm help <term> [<terms..>]
-
+
Options:
[--viewer <viewer>]
-
+
alias: hlep
-
+
Run "npm help help" for more info
hook Manage registry hooks
-
+
Usage:
npm hook add <pkg> <url> <secret> [--type=<type>]
npm hook ls [pkg]
npm hook rm <id>
npm hook update <id> <url> <secret>
-
+
Options:
[--registry <registry>] [--otp <otp>]
-
+
Run "npm help hook" for more info
init Create a package.json file
-
+
Usage:
npm init [--force|-f|--yes|-y|--scope]
npm init <@scope> (same as \`npx <@scope>/create\`)
npm init [<@scope>/]<name> (same as \`npx [<@scope>/]create-<name>\`)
-
+
Options:
[-y|--yes] [-f|--force]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
aliases: create, innit
-
+
Run "npm help init" for more info
install Install a package
-
+
Usage:
npm install [<@scope>/]<pkg>
npm install [<@scope>/]<pkg>@<tag>
@@ -505,7 +505,7 @@ All commands:
npm install <tarball url>
npm install <git:// url>
npm install <github username>/<github project>
-
+
Options:
[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle]
[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling]
@@ -514,26 +514,26 @@ All commands:
[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall
-
+
Run "npm help install" for more info
install-ci-test Install a project with a clean slate and run tests
-
+
Usage:
npm install-ci-test
-
+
Options:
[--no-audit] [--foreground-scripts] [--ignore-scripts]
[--script-shell <script-shell>]
-
+
alias: cit
-
+
Run "npm help install-ci-test" for more info
install-test Install package(s) and run tests
-
+
Usage:
npm install-test [<@scope>/]<pkg>
npm install-test [<@scope>/]<pkg>@<tag>
@@ -545,7 +545,7 @@ All commands:
npm install-test <tarball url>
npm install-test <git:// url>
npm install-test <github username>/<github project>
-
+
Options:
[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle]
[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling]
@@ -554,17 +554,17 @@ All commands:
[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
alias: it
-
+
Run "npm help install-test" for more info
link Symlink a package folder
-
+
Usage:
npm link (in package dir)
npm link [<@scope>/]<pkg>[@<version>]
-
+
Options:
[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle]
[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling]
@@ -573,126 +573,126 @@ All commands:
[--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
alias: ln
-
+
Run "npm help link" for more info
ll List installed packages
-
+
Usage:
npm ll [[<@scope>/]<pkg> ...]
-
+
Options:
[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] [--depth <depth>]
[--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--link]
[--package-lock-only] [--unicode]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
alias: la
-
+
Run "npm help ll" for more info
login Add a registry user account
-
+
Usage:
npm adduser
-
+
Options:
[--registry <registry>] [--scope <@scope>]
-
+
aliases: login, add-user
-
+
Run "npm help adduser" for more info
logout Log out of the registry
-
+
Usage:
npm logout
-
+
Options:
[--registry <registry>] [--scope <@scope>]
-
+
Run "npm help logout" for more info
ls List installed packages
-
+
Usage:
npm ls [[<@scope>/]<pkg> ...]
-
+
Options:
[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] [--depth <depth>]
[--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--link]
[--package-lock-only] [--unicode]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
alias: list
-
+
Run "npm help ls" for more info
org Manage orgs
-
+
Usage:
npm org set orgname username [developer | admin | owner]
npm org rm orgname username
npm org ls orgname [<username>]
-
+
Options:
[--registry <registry>] [--otp <otp>] [--json] [-p|--parseable]
-
+
alias: ogr
-
+
Run "npm help org" for more info
outdated Check for outdated packages
-
+
Usage:
npm outdated [[<@scope>/]<pkg> ...]
-
+
Options:
[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
-
+
Run "npm help outdated" for more info
owner Manage package owners
-
+
Usage:
npm owner add <user> [<@scope>/]<pkg>
npm owner rm <user> [<@scope>/]<pkg>
npm owner ls [<@scope>/]<pkg>
-
+
Options:
[--registry <registry>] [--otp <otp>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces]
-
+
alias: author
-
+
Run "npm help owner" for more info
pack Create a tarball from a package
-
+
Usage:
npm pack [[<@scope>/]<pkg>...]
-
+
Options:
[--dry-run] [--json] [--pack-destination <pack-destination>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
Run "npm help pack" for more info
ping Ping npm registry
-
+
Usage:
npm ping
-
+
Options:
[--registry <registry>]
-
+
Run "npm help ping" for more info
pkg Manages your package.json
@@ -712,272 +712,272 @@ All commands:
Run "npm help pkg" for more info
prefix Display prefix
-
+
Usage:
npm prefix [-g]
-
+
Options:
[-g|--global]
-
+
Run "npm help prefix" for more info
profile Change settings on your registry profile
-
+
Usage:
npm profile enable-2fa [auth-only|auth-and-writes]
npm profile disable-2fa
npm profile get [<key>]
npm profile set <key> <value>
-
+
Options:
[--registry <registry>] [--json] [-p|--parseable] [--otp <otp>]
-
+
Run "npm help profile" for more info
prune Remove extraneous packages
-
+
Usage:
npm prune [[<@scope>/]<pkg>...]
-
+
Options:
[--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--dry-run]
[--json] [--foreground-scripts] [--ignore-scripts]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
Run "npm help prune" for more info
publish Publish a package
-
+
Usage:
npm publish [<folder>]
-
+
Options:
[--tag <tag>] [--access <restricted|public>] [--dry-run] [--otp <otp>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
Run "npm help publish" for more info
rebuild Rebuild a package
-
+
Usage:
npm rebuild [[<@scope>/]<name>[@<version>] ...]
-
+
Options:
[-g|--global] [--no-bin-links] [--foreground-scripts] [--ignore-scripts]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
alias: rb
-
+
Run "npm help rebuild" for more info
repo Open package repository page in the browser
-
+
Usage:
npm repo [<pkgname> [<pkgname> ...]]
-
+
Options:
[--no-browser|--browser <browser>] [--registry <registry>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
Run "npm help repo" for more info
restart Restart a package
-
+
Usage:
npm restart [-- <args>]
-
+
Options:
[--ignore-scripts] [--script-shell <script-shell>]
-
+
Run "npm help restart" for more info
root Display npm root
-
+
Usage:
npm root
-
+
Options:
[-g|--global]
-
+
Run "npm help root" for more info
run-script Run arbitrary package scripts
-
+
Usage:
npm run-script <command> [-- <args>]
-
+
Options:
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--if-present] [--ignore-scripts]
[--script-shell <script-shell>]
-
+
aliases: run, rum, urn
-
+
Run "npm help run-script" for more info
search Search for packages
-
+
Usage:
npm search [search terms ...]
-
+
Options:
[-l|--long] [--json] [--color|--no-color|--color always] [-p|--parseable]
[--no-description] [--searchopts <searchopts>] [--searchexclude <searchexclude>]
[--registry <registry>] [--prefer-online] [--prefer-offline] [--offline]
-
+
aliases: find, s, se
-
+
Run "npm help search" for more info
set Set a value in the npm configuration
-
+
Usage:
npm set <key>=<value> [<key>=<value> ...] (See \`npm config\`)
-
+
Run "npm help set" for more info
- set-script Set tasks in the scripts section of package.json
-
+ set-script Set tasks in the scripts section of package.json, deprecated
+
Usage:
npm set-script [<script>] [<command>]
-
+
Options:
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
Run "npm help set-script" for more info
shrinkwrap Lock down dependency versions for publication
-
+
Usage:
npm shrinkwrap
-
+
Run "npm help shrinkwrap" for more info
star Mark your favorite packages
-
+
Usage:
npm star [<pkg>...]
-
+
Options:
[--registry <registry>] [--unicode] [--otp <otp>]
-
+
Run "npm help star" for more info
stars View packages marked as favorites
-
+
Usage:
npm stars [<user>]
-
+
Options:
[--registry <registry>]
-
+
Run "npm help stars" for more info
start Start a package
-
+
Usage:
npm start [-- <args>]
-
+
Options:
[--ignore-scripts] [--script-shell <script-shell>]
-
+
Run "npm help start" for more info
stop Stop a package
-
+
Usage:
npm stop [-- <args>]
-
+
Options:
[--ignore-scripts] [--script-shell <script-shell>]
-
+
Run "npm help stop" for more info
team Manage organization teams and team memberships
-
+
Usage:
npm team create <scope:team> [--otp <otpcode>]
npm team destroy <scope:team> [--otp <otpcode>]
npm team add <scope:team> <user> [--otp <otpcode>]
npm team rm <scope:team> <user> [--otp <otpcode>]
npm team ls <scope>|<scope:team>
-
+
Options:
[--registry <registry>] [--otp <otp>] [-p|--parseable] [--json]
-
+
Run "npm help team" for more info
test Test a package
-
+
Usage:
npm test [-- <args>]
-
+
Options:
[--ignore-scripts] [--script-shell <script-shell>]
-
+
aliases: tst, t
-
+
Run "npm help test" for more info
token Manage your authentication tokens
-
+
Usage:
npm token list
npm token revoke <id|token>
npm token create [--read-only] [--cidr=list]
-
+
Options:
[--read-only] [--cidr <cidr> [--cidr <cidr> ...]] [--registry <registry>]
[--otp <otp>]
-
+
Run "npm help token" for more info
uninstall Remove a package
-
+
Usage:
npm uninstall [<@scope>/]<pkg>...
-
+
Options:
[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
aliases: unlink, remove, rm, r, un
-
+
Run "npm help uninstall" for more info
unpublish Remove a package from the registry
-
+
Usage:
npm unpublish [<@scope>/]<pkg>[@<version>]
-
+
Options:
[--dry-run] [-f|--force]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces]
-
+
Run "npm help unpublish" for more info
unstar Remove an item from your favorite packages
-
+
Usage:
npm unstar [<pkg>...]
-
+
Options:
[--registry <registry>] [--unicode] [--otp <otp>]
-
+
Run "npm help unstar" for more info
update Update packages
-
+
Usage:
npm update [<pkg>...]
-
+
Options:
[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle]
[-g|--global] [--global-style] [--legacy-bundling]
@@ -986,47 +986,47 @@ All commands:
[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
-
+
aliases: up, upgrade, udpate
-
+
Run "npm help update" for more info
version Bump a package version
-
+
Usage:
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
-
+
Options:
[--allow-same-version] [--no-commit-hooks] [--no-git-tag-version] [--json]
[--preid prerelease-id] [--sign-git-tag]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--no-workspaces-update] [--include-workspace-root]
-
+
alias: verison
-
+
Run "npm help version" for more info
view View registry info
-
+
Usage:
npm view [<@scope>/]<pkg>[@<version>] [<field>[.subfield]...]
-
+
Options:
[--json] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
-
+
aliases: info, show, v
-
+
Run "npm help view" for more info
whoami Display npm username
-
+
Usage:
npm whoami
-
+
Options:
[--registry <registry>]
-
+
Run "npm help whoami" for more info
Specify configs in the ini-formatted file:
diff --git a/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs
index c31a6b7dc7..b12dccdb76 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs
@@ -731,6 +731,8 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for globa
* Default: false
* Type: Boolean
+* DEPRECATED: \`--global\`, \`--local\` are deprecated. Use \`--location=global\`
+ instead.
Operates in "global" mode, so that packages are installed into the \`prefix\`
folder instead of the current working directory. See
@@ -1077,6 +1079,15 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for locat
* Type: "global", "user", or "project"
When passed to \`npm config\` this refers to which config file to use.
+
+When set to "global" mode, 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\`
`
exports[`test/lib/utils/config/definitions.js TAP > config description for lockfile-version 1`] = `
diff --git a/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs
index 0ec2ca17a4..cacbe96a74 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs
@@ -560,23 +560,6 @@ results in no commit being made at all.
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
-#### \`global\`
-
-* Default: false
-* Type: Boolean
-
-Operates in "global" mode, so that packages are installed into the \`prefix\`
-folder instead of the current working directory. See
-[folders](/configuring-npm/folders) for more on the differences in behavior.
-
-* packages are installed into the \`{prefix}/lib/node_modules\` folder, instead
- of the current working directory.
-* bin files are linked to \`{prefix}/bin\`
-* man pages are linked to \`{prefix}/share/man\`
-
-<!-- automatically generated, do not edit manually -->
-<!-- see lib/utils/config/definitions.js -->
-
#### \`global-style\`
* Default: false
@@ -874,6 +857,15 @@ npm registry. Must be IPv4 in versions of Node prior to 0.12.
When passed to \`npm config\` this refers to which config file to use.
+When set to "global" mode, packages are installed into the \`prefix\` folder
+instead of the current working directory. See
+[folders](/configuring-npm/folders) for more on the differences in behavior.
+
+* packages are installed into the \`{prefix}/lib/node_modules\` folder, instead
+ of the current working directory.
+* bin files are linked to \`{prefix}/bin\`
+* man pages are linked to \`{prefix}/share/man\`
+
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
@@ -1814,6 +1806,25 @@ Alias for \`--include=dev\`.
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
+#### \`global\`
+
+* Default: false
+* Type: Boolean
+* DEPRECATED: \`--global\`, \`--local\` are deprecated. Use \`--location=global\`
+ instead.
+
+Operates in "global" mode, so that packages are installed into the \`prefix\`
+folder instead of the current working directory. See
+[folders](/configuring-npm/folders) for more on the differences in behavior.
+
+* packages are installed into the \`{prefix}/lib/node_modules\` folder, instead
+ of the current working directory.
+* bin files are linked to \`{prefix}/bin\`
+* man pages are linked to \`{prefix}/share/man\`
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+
#### \`init.author.email\`
* Default: ""
diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js
index c9701ebc23..a79812fb71 100644
--- a/deps/npm/test/fixtures/mock-npm.js
+++ b/deps/npm/test/fixtures/mock-npm.js
@@ -224,6 +224,10 @@ class MockNpm {
}
}
+ get global () {
+ return this.config.get('global') || this.config.get('location') === 'global'
+ }
+
output (...msg) {
if (this.base.output) {
return this.base.output(msg)
diff --git a/deps/npm/test/fixtures/mock-registry.js b/deps/npm/test/fixtures/mock-registry.js
index a62890b72e..8fb5a055ff 100644
--- a/deps/npm/test/fixtures/mock-registry.js
+++ b/deps/npm/test/fixtures/mock-registry.js
@@ -192,6 +192,10 @@ class MockRegistry {
}).reply(200, { ...manifest, users })
}
+ ping ({ body = {}, responseCode = 200 } = {}) {
+ this.nock = this.nock.get('/-/ping?write=true').reply(responseCode, body)
+ }
+
async package ({ manifest, times = 1, query, tarballs }) {
let nock = this.nock
const spec = npa(manifest.name)
@@ -202,16 +206,21 @@ class MockRegistry {
nock = nock.reply(200, manifest)
if (tarballs) {
for (const version in tarballs) {
- // for (const version in manifest.versions) {
- const packument = manifest.versions[version]
- const dist = new URL(packument.dist.tarball)
- const tarball = await pacote.tarball(tarballs[version])
- nock.get(dist.pathname).reply(200, tarball)
+ const m = manifest.versions[version]
+ nock = await this.tarball({ manifest: m, tarball: tarballs[version] })
}
}
this.nock = nock
}
+ async tarball ({ manifest, tarball }) {
+ const nock = this.nock
+ const dist = new URL(manifest.dist.tarball)
+ const tar = await pacote.tarball(tarball)
+ nock.get(dist.pathname).reply(200, tar)
+ return nock
+ }
+
// either pass in packuments if you need to set specific attributes besides version,
// or an array of versions
// the last packument in the packuments or versions array will be tagged latest
diff --git a/deps/npm/test/lib/commands/cache.js b/deps/npm/test/lib/commands/cache.js
index 6023127691..72a7ce96aa 100644
--- a/deps/npm/test/lib/commands/cache.js
+++ b/deps/npm/test/lib/commands/cache.js
@@ -1,442 +1,309 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm.js')
-const path = require('path')
-const npa = require('npm-package-arg')
-
-let outputOutput = []
-
-let rimrafPath = ''
-const rimraf = (path, cb) => {
- rimrafPath = path
- return cb()
-}
-
-let logOutput = []
-
-let tarballStreamSpec = ''
-let tarballStreamOpts = {}
-const pacote = {
- tarball: {
- stream: (spec, handler, opts) => {
- tarballStreamSpec = spec
- tarballStreamOpts = opts
- return handler({
- resume: () => {},
- promise: () => Promise.resolve(),
- })
- },
- },
-}
-
-let cacacheEntries = {}
-let cacacheContent = {}
-
-const setupCacacheFixture = () => {
- cacacheEntries = {}
- cacacheContent = {}
- const pkgs = [
- ['webpack@4.44.1', 'https://registry.npmjs.org', true],
- ['npm@1.2.0', 'https://registry.npmjs.org', true],
- ['webpack@4.47.0', 'https://registry.npmjs.org', true],
- ['foo@1.2.3-beta', 'https://registry.npmjs.org', true],
- ['ape-ecs@2.1.7', 'https://registry.npmjs.org', true],
- ['@fritzy/staydown@3.1.1', 'https://registry.npmjs.org', true],
- ['@gar/npm-expansion@2.1.0', 'https://registry.npmjs.org', true],
- ['@gar/npm-expansion@3.0.0-beta', 'https://registry.npmjs.org', true],
- ['extemporaneously@44.2.2', 'https://somerepo.github.org', false],
- ['corrupted@3.1.0', 'https://registry.npmjs.org', true],
- ['missing-dist@23.0.0', 'https://registry.npmjs.org', true],
- ['missing-version@16.2.0', 'https://registry.npmjs.org', true],
- ]
- pkgs.forEach(pkg => addCacachePkg(...pkg))
- // corrupt the packument
- cacacheContent[
- /* eslint-disable-next-line max-len */
- [cacacheEntries['make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted'].integrity]
- ].data = Buffer.from('<>>>}"')
- // nuke the version dist
- cacacheContent[
- /* eslint-disable-next-line max-len */
- [cacacheEntries['make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist'].integrity]
- ].data = Buffer.from(JSON.stringify({ versions: { '23.0.0': {} } }))
- // make the version a non-object
- cacacheContent[
- /* eslint-disable-next-line max-len */
- [cacacheEntries['make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version'].integrity]
- ].data = Buffer.from(JSON.stringify({ versions: 'hello' }))
-}
-
-const packuments = {}
+const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
+const MockRegistry = require('../../fixtures/mock-registry.js')
+const mockGlobals = require('../../fixtures/mock-globals')
-let contentId = 0
-const cacacheVerifyStats = {
- keptSize: 100,
- verifiedContent: 1,
- totalEntries: 1,
- runTime: { total: 2000 },
-}
+const cacache = require('cacache')
+const fs = require('@npmcli/fs')
+const path = require('path')
-const addCacacheKey = (key, content) => {
- contentId++
- cacacheEntries[key] = { integrity: `${contentId}` }
- cacacheContent[`${contentId}`] = {}
-}
-const addCacachePkg = (spec, registry, publicURL) => {
- const parts = npa(spec)
- const ver = parts.rawSpec || '1.0.0'
- let url = `${registry}/${parts.name}/-/${parts.name}-${ver}.tgz`
- if (!publicURL) {
- url = `${registry}/aabbcc/${contentId}`
- }
- const key = `make-fetch-happen:request-cache:${url}`
- const pkey = `make-fetch-happen:request-cache:${registry}/${parts.escapedName}`
- if (!packuments[parts.escapedName]) {
- packuments[parts.escapedName] = {
- versions: {},
- }
- addCacacheKey(pkey)
- }
- packuments[parts.escapedName].versions[ver] = {
- dist: {
- tarball: url,
- },
- }
- addCacacheKey(key)
- cacacheContent[cacacheEntries[pkey].integrity] = {
- data: Buffer.from(JSON.stringify(packuments[parts.escapedName])),
- }
-}
+const pkg = 'test-package'
-const cacache = {
- verify: (path) => {
- return cacacheVerifyStats
- },
- get: (path, key) => {
- if (cacacheEntries[key] === undefined
- || cacacheContent[cacacheEntries[key].integrity] === undefined) {
- throw new Error()
- }
- return cacacheContent[cacacheEntries[key].integrity]
- },
- rm: {
- entry: (path, key) => {
- if (cacacheEntries[key] === undefined) {
- throw new Error()
- }
- delete cacacheEntries[key]
- },
- content: (path, sha) => {
- delete cacacheContent[sha]
- },
- },
- ls: (path) => {
- return cacacheEntries
- },
+t.cleanSnapshot = str => {
+ return str
+ .replace(/Finished in [0-9.s]+/g, 'Finished in xxxs')
+ .replace(/Cache verified and compressed (.*)/, 'Cache verified and compressed ({PATH})')
}
-const Cache = t.mock('../../../lib/commands/cache.js', {
- cacache,
- pacote,
- rimraf,
- 'proc-log': {
- silly: (...args) => {
- logOutput.push(['silly', ...args])
- },
- warn: (...args) => {
- logOutput.push(['warn', ...args])
- },
- },
-})
-
-const npm = mockNpm({
- cache: '/fake/path',
- flatOptions: { force: false },
- config: { force: false },
- output: (msg) => {
- outputOutput.push(msg)
- },
-})
-const cache = new Cache(npm)
-
t.test('cache no args', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
- cache.exec([]),
+ npm.exec('cache', []),
{ code: 'EUSAGE' },
'should throw usage instructions'
)
})
t.test('cache clean', async t => {
+ const { npm } = await loadMockNpm(t)
await t.rejects(
- cache.exec(['clean']),
- 'the npm cache self-heals',
+ npm.exec('cache', ['clean']),
+ /the npm cache self-heals/,
'should throw warning'
)
})
t.test('cache clean (force)', async t => {
- npm.config.set('force', true)
- npm.flatOptions.force = true
- t.teardown(() => {
- rimrafPath = ''
- npm.config.force = false
- npm.flatOptions.force = false
+ const { npm } = await loadMockNpm(t, {
+ cacheDir: { _cacache: {} },
+ config: { force: true },
})
-
- await cache.exec(['clear'])
- t.equal(rimrafPath, path.join(npm.cache, '_cacache'))
+ const cache = path.join(npm.cache, '_cacache')
+ await npm.exec('cache', ['clean'])
+ t.notOk(fs.existsSync(cache), 'cache dir was removed')
})
t.test('cache add no arg', async t => {
- t.teardown(() => {
- logOutput = []
- })
-
+ const { npm } = await loadMockNpm(t)
await t.rejects(
- cache.exec(['add']),
+ npm.exec('cache', ['add']),
{
code: 'EUSAGE',
message: 'First argument to `add` is required',
},
'throws usage error'
)
- t.strictSame(logOutput, [
- ['silly', 'cache add', 'args', []],
- ], 'logs correctly')
})
-t.test('cache add pkg only', async t => {
- t.teardown(() => {
- logOutput = []
- tarballStreamSpec = ''
- tarballStreamOpts = {}
+t.test('cache add single pkg', async t => {
+ const { npm, joinedOutput } = await loadMockNpm(t, {
+ prefixDir: {
+ package: {
+ 'package.json': JSON.stringify({
+ name: pkg,
+ version: '1.0.0',
+ }),
+ },
+ },
})
-
- await cache.exec(['add', 'mypkg'])
- t.strictSame(logOutput, [
- ['silly', 'cache add', 'args', ['mypkg']],
- ['silly', 'cache add', 'spec', 'mypkg'],
- ], 'logs correctly')
- t.equal(tarballStreamSpec, 'mypkg', 'passes the correct spec to pacote')
- t.same(tarballStreamOpts, npm.flatOptions, 'passes the correct options to pacote')
+ const cache = path.join(npm.cache, '_cacache')
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ const manifest = registry.manifest({ name: pkg })
+ await registry.package({ manifest, tarballs: { '1.0.0': path.join(npm.prefix, 'package') } })
+ await npm.exec('cache', ['add', pkg])
+ t.equal(joinedOutput(), '')
+ // eslint-disable-next-line max-len
+ t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'))
+ // eslint-disable-next-line max-len
+ t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package'))
})
t.test('cache add multiple pkgs', async t => {
- t.teardown(() => {
- outputOutput = []
- tarballStreamSpec = ''
- tarballStreamOpts = {}
+ const pkg2 = 'test-package-two'
+ const { npm, joinedOutput } = await loadMockNpm(t, {
+ prefixDir: {
+ package: {
+ 'package.json': JSON.stringify({
+ name: pkg,
+ version: '1.0.0',
+ }),
+ },
+ },
})
-
- await cache.exec(['add', 'mypkg', 'anotherpkg'])
- t.strictSame(logOutput, [
- ['silly', 'cache add', 'args', ['mypkg', 'anotherpkg']],
- ['silly', 'cache add', 'spec', 'mypkg'],
- ['silly', 'cache add', 'spec', 'anotherpkg'],
- ], 'logs correctly')
- t.equal(tarballStreamSpec, 'anotherpkg', 'passes the correct spec to pacote')
- t.same(tarballStreamOpts, npm.flatOptions, 'passes the correct options to pacote')
+ const cache = path.join(npm.cache, '_cacache')
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ const manifest = registry.manifest({ name: pkg })
+ const manifest2 = registry.manifest({ name: pkg2 })
+ await registry.package({ manifest, tarballs: { '1.0.0': path.join(npm.prefix, 'package') } })
+ await registry.package({
+ manifest: manifest2, tarballs: { '1.0.0': path.join(npm.prefix, 'package') },
+ })
+ await npm.exec('cache', ['add', pkg, pkg2])
+ t.equal(joinedOutput(), '')
+ // eslint-disable-next-line max-len
+ t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'))
+ // eslint-disable-next-line max-len
+ t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package'))
+ // eslint-disable-next-line max-len
+ t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package-two/-/test-package-two-1.0.0.tgz'))
+ // eslint-disable-next-line max-len
+ t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package-two'))
})
t.test('cache ls', async t => {
- t.teardown(() => {
- outputOutput = []
- logOutput = []
- })
- setupCacacheFixture()
- await cache.exec(['ls'])
- t.strictSame(outputOutput, [
- /* eslint-disable-next-line max-len */
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy/staydown/-/@fritzy/staydown-3.1.1.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy%2fstaydown',
- /* eslint-disable-next-line max-len */
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar/npm-expansion/-/@gar/npm-expansion-2.1.0.tgz',
- /* eslint-disable-next-line max-len */
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar/npm-expansion/-/@gar/npm-expansion-3.0.0-beta.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar%2fnpm-expansion',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/ape-ecs',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/ape-ecs/-/ape-ecs-2.1.7.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted/-/corrupted-3.1.0.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/foo',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/foo/-/foo-1.2.3-beta.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist',
- /* eslint-disable-next-line max-len */
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist/-/missing-dist-23.0.0.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version',
- /* eslint-disable-next-line max-len */
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version/-/missing-version-16.2.0.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/npm',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/npm/-/npm-1.2.0.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz',
- 'make-fetch-happen:request-cache:https://somerepo.github.org/aabbcc/14',
- 'make-fetch-happen:request-cache:https://somerepo.github.org/extemporaneously',
- ])
+ const keys = [
+ 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package',
+ // eslint-disable-next-line max-len
+ 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz',
+ ]
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ for (const key of keys) {
+ await cacache.put(cache, key, 'test data')
+ }
+ await npm.exec('cache', ['ls'])
+ t.matchSnapshot(joinedOutput(), 'logs cache entries')
})
t.test('cache ls pkgs', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['ls', 'webpack@>4.44.1', 'npm'])
- t.strictSame(outputOutput, [
+ const keys = [
'make-fetch-happen:request-cache:https://registry.npmjs.org/npm',
'make-fetch-happen:request-cache:https://registry.npmjs.org/npm/-/npm-1.2.0.tgz',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack',
'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz',
- ])
+ 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.40.0.tgz',
+ ]
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ for (const key of keys) {
+ await cacache.put(cache, key, 'test data')
+ }
+ await cacache.put(cache,
+ 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack',
+ JSON.stringify({ versions: {
+ '4.40.0': { dist: { tarball: 'https://registry.npmjs.org/webpack/-/webpack-4.40.0.tgz' } },
+ '4.47.0': { dist: { tarball: 'https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz' } },
+ } })
+ )
+ await npm.exec('cache', ['ls', 'webpack@>4.44.1', 'npm'])
+ t.matchSnapshot(joinedOutput(), 'logs cache entries for npm and webpack and one webpack tgz')
})
t.test('cache ls special', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['ls', 'foo@1.2.3-beta'])
- t.strictSame(outputOutput, [
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ await cacache.put(cache,
'make-fetch-happen:request-cache:https://registry.npmjs.org/foo',
+ JSON.stringify({ versions: { '1.2.3-beta': {} } })
+ )
+ await cacache.put(cache,
'make-fetch-happen:request-cache:https://registry.npmjs.org/foo/-/foo-1.2.3-beta.tgz',
- ])
+ 'test-data'
+ )
+ await npm.exec('cache', ['ls', 'foo@1.2.3-beta'])
+ t.matchSnapshot(joinedOutput(), 'logs cache entries for foo')
})
t.test('cache ls nonpublic registry', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['ls', 'extemporaneously'])
- t.strictSame(outputOutput, [
- 'make-fetch-happen:request-cache:https://somerepo.github.org/aabbcc/14',
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ await cacache.put(cache,
'make-fetch-happen:request-cache:https://somerepo.github.org/extemporaneously',
- ])
+ JSON.stringify({
+ versions: { '1.0.0': { dist: { tarball: 'https://somerepo.github.org/aabbcc/' } } },
+ })
+ )
+ await cacache.put(cache,
+ 'make-fetch-happen:request-cache:https://somerepo.github.org/aabbcc/',
+ 'test data'
+ )
+ await npm.exec('cache', ['ls', 'extemporaneously'])
+ t.matchSnapshot(joinedOutput(), 'logs cache entry for extemporaneously and its tarball')
})
t.test('cache ls tagged', async t => {
- t.teardown(() => {
- outputOutput = []
- })
+ const { npm } = await loadMockNpm(t)
await t.rejects(
- cache.exec(['ls', 'webpack@latest']),
- 'tagged package',
- 'should throw warning'
+ npm.exec('cache', ['ls', 'webpack@latest']),
+ { code: 'EUSAGE' },
+ 'should throw usage error'
)
})
t.test('cache ls scoped and scoped slash', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['ls', '@fritzy/staydown', '@gar/npm-expansion'])
- t.strictSame(outputOutput, [
- /* eslint-disable-next-line max-len */
+ const keys = [
+ // eslint-disable-next-line max-len
'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy/staydown/-/@fritzy/staydown-3.1.1.tgz',
'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy%2fstaydown',
- /* eslint-disable-next-line max-len */
+ // eslint-disable-next-line max-len
'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar/npm-expansion/-/@gar/npm-expansion-2.1.0.tgz',
'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar%2fnpm-expansion',
- ])
+ ]
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ for (const key of keys) {
+ await cacache.put(cache, key, 'test data')
+ }
+ await npm.exec('cache', ['ls', '@fritzy/staydown', '@gar/npm-expansion'])
+ t.matchSnapshot(joinedOutput(), 'logs cache entries for @gar and @fritzy')
})
t.test('cache ls corrupted', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['ls', 'corrupted'])
- t.strictSame(outputOutput, [
+ const keys = [
'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted',
'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted/-/corrupted-3.1.0.tgz',
- ])
-})
-
-t.test('cache ls missing packument dist', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['ls', 'missing-dist'])
- t.strictSame(outputOutput, [
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist',
- /* eslint-disable-next-line max-len */
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist/-/missing-dist-23.0.0.tgz',
- ])
+ ]
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ for (const key of keys) {
+ await cacache.put(cache, key, Buffer.from('<>>>}"'))
+ }
+ await npm.exec('cache', ['ls', 'corrupted'])
+ t.matchSnapshot(joinedOutput(), 'logs cache entries with bad data')
})
t.test('cache ls missing packument version not an object', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['ls', 'missing-version'])
- t.strictSame(outputOutput, [
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ await cacache.put(cache,
'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version',
- /* eslint-disable-next-line max-len */
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version/-/missing-version-16.2.0.tgz',
- ])
+ JSON.stringify({ versions: 'not an object' })
+ )
+ await npm.exec('cache', ['ls', 'missing-version'])
+ t.matchSnapshot(joinedOutput(), 'logs cache entry for packument')
})
t.test('cache rm', async t => {
- t.teardown(() => {
- outputOutput = []
- })
- await cache.exec(['rm',
- 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz'])
- t.strictSame(outputOutput, [
- /* eslint-disable-next-line max-len */
- 'Deleted: make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz',
- ])
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ const cache = path.join(npm.cache, '_cacache')
+ // eslint-disable-next-line max-len
+ await cacache.put(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package', '{}')
+ // eslint-disable-next-line max-len
+ await cacache.put(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz', 'test data')
+ // eslint-disable-next-line max-len
+ await npm.exec('cache', ['rm', 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'])
+ t.matchSnapshot(joinedOutput(), 'logs deleting single entry')
+ // eslint-disable-next-line max-len
+ t.resolves(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package'))
+ // eslint-disable-next-line max-len
+ t.rejects(cacache.get(cache, 'make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz'))
})
t.test('cache rm unfound', async t => {
- t.teardown(() => {
- outputOutput = []
- logOutput = []
- })
- await cache.exec(['rm', 'made-up-key'])
- t.strictSame(logOutput, [
- ['warn', 'Not Found: made-up-key'],
- ], 'logs correctly')
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ await npm.exec('cache', ['rm', 'made-up-key'])
+ t.same(joinedOutput(), '', 'no errors, no output')
})
t.test('cache verify', async t => {
- t.teardown(() => {
- outputOutput = []
- })
+ const { npm, joinedOutput } = await loadMockNpm(t)
+ await npm.exec('cache', ['verify'])
+ t.matchSnapshot(joinedOutput(), 'shows verified cache output')
+})
- await cache.exec(['verify'])
- t.match(outputOutput, [
- `Cache verified and compressed (${path.join(npm.cache, '_cacache')})`,
- 'Content verified: 1 (100 bytes)',
- 'Index entries: 1',
- 'Finished in 2s',
- ], 'prints correct output')
+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) })
+ await npm.exec('cache', ['verify'])
+ t.match(joinedOutput(), 'Cache verified and compressed (~', 'contains ~ shorthand')
})
t.test('cache verify w/ extra output', async t => {
- npm.cache = `${process.env.HOME}/fake/path`
- cacacheVerifyStats.badContentCount = 1
- cacacheVerifyStats.reclaimedCount = 2
- cacacheVerifyStats.reclaimedSize = 200
- cacacheVerifyStats.missingContent = 3
- t.teardown(() => {
- npm.cache = '/fake/path'
- outputOutput = []
- delete cacacheVerifyStats.badContentCount
- delete cacacheVerifyStats.reclaimedCount
- delete cacacheVerifyStats.reclaimedSize
- delete cacacheVerifyStats.missingContent
+ const verify = {
+ runTime: {
+ markStartTime: 0,
+ fixPerms: 3,
+ garbageCollect: 54982,
+ rebuildIndex: 62779,
+ cleanTmp: 62781,
+ writeVerifile: 62783,
+ markEndTime: 62783,
+ total: 62783,
+ },
+ verifiedContent: 17057,
+ reclaimedCount: 1144,
+ reclaimedSize: 248164665,
+ badContentCount: 12345,
+ keptSize: 1644485260,
+ missingContent: 92,
+ rejectedEntries: 92,
+ totalEntries: 20175,
+ }
+ const { npm, joinedOutput } = await loadMockNpm(t, {
+ mocks: { cacache: { verify: () => verify } },
})
-
- await cache.exec(['check'])
- t.match(outputOutput, [
- `Cache verified and compressed (~${path.join('/fake/path', '_cacache')})`,
- 'Content verified: 1 (100 bytes)',
- 'Corrupted content removed: 1',
- 'Content garbage-collected: 2 (200 bytes)',
- 'Missing content: 3',
- 'Index entries: 1',
- 'Finished in 2s',
- ], 'prints correct output')
+ await npm.exec('cache', ['verify'])
+ t.matchSnapshot(joinedOutput(), 'shows extra output')
})
t.test('cache completion', async t => {
+ const { npm } = await loadMockNpm(t)
+ const cache = await npm.cmd('cache')
const { completion } = cache
const testComp = (argv, expect) => {
diff --git a/deps/npm/test/lib/commands/ci.js b/deps/npm/test/lib/commands/ci.js
index 978cd03b87..179cee6c9b 100644
--- a/deps/npm/test/lib/commands/ci.js
+++ b/deps/npm/test/lib/commands/ci.js
@@ -1,316 +1,201 @@
-const fs = require('fs')
-const util = require('util')
-const readdir = util.promisify(fs.readdir)
-
const t = require('tap')
-
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-t.test('should ignore scripts with --ignore-scripts', async t => {
- const SCRIPTS = []
- let REIFY_CALLED = false
- const CI = t.mock('../../../lib/commands/ci.js', {
- '../../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/run-script': ({ event }) => {
- SCRIPTS.push(event)
- },
- '@npmcli/arborist': function () {
- this.loadVirtual = async () => {}
- this.reify = () => {
- REIFY_CALLED = true
- }
- this.buildIdealTree = () => {}
- this.virtualTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
- this.idealTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
+const { load: _loadMockNpm } = require('../../fixtures/mock-npm')
+const MockRegistry = require('../../fixtures/mock-registry.js')
+
+const path = require('path')
+const fs = require('@npmcli/fs')
+
+// t.cleanSnapshot = str => str.replace(/ in [0-9ms]+/g, ' in {TIME}')
+
+const loadMockNpm = async (t, opts) => {
+ const mock = await _loadMockNpm(t, opts)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: mock.npm.config.get('registry'),
+ })
+ return { registry, ...mock }
+}
+
+const packageJson = {
+ name: 'test-package',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: '^1.0.0',
+ },
+}
+const packageLock = {
+ name: 'test-package',
+ version: '1.0.0',
+ lockfileVersion: 2,
+ requires: true,
+ packages: {
+ '': {
+ name: 'test-package',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: '^1.0.0',
+ },
},
- })
+ 'node_modules/abbrev': {
+ version: '1.0.0',
+ resolved: 'https://registry.npmjs.org/abbrev/-/abbrev-1.0.0.tgz',
+ // integrity changes w/ each test cause the path is different?
+ },
+ },
+ dependencies: {
+ abbrev: {
+ version: '1.0.0',
+ resolved: 'https://registry.npmjs.org/abbrev/-/abbrev-1.0.0.tgz',
+ // integrity changes w/ each test cause the path is different?
+ },
+ },
+}
+
+const abbrev = {
+ 'package.json': '{"name": "abbrev", "version": "1.0.0"}',
+ test: 'test file',
+}
+
+t.test('reifies, audits, removes node_modules', async t => {
+ const { npm, joinedOutput, registry } = await loadMockNpm(t, {
+ prefixDir: {
+ abbrev: abbrev,
+ 'package.json': JSON.stringify(packageJson),
+ 'package-lock.json': JSON.stringify(packageLock),
+ node_modules: { test: 'test file that will be removed' },
+ },
+ })
+ const manifest = registry.manifest({ name: 'abbrev' })
+ await registry.tarball({
+ manifest: manifest.versions['1.0.0'],
+ tarball: path.join(npm.prefix, 'abbrev'),
+ })
+ registry.nock.post('/-/npm/v1/security/advisories/bulk').reply(200, {})
+ await npm.exec('ci', [])
+ t.match(joinedOutput(), 'added 1 package, and audited 2 packages in')
+ await t.resolveMatch(
+ fs.exists(path.join(npm.prefix, 'node_modules', 'test')),
+ false,
+ 'existing node_modules is removed'
+ )
+ await t.resolveMatch(
+ fs.exists(path.join(npm.prefix, 'node_modules', 'abbrev')),
+ true,
+ 'installs abbrev'
+ )
+})
- const npm = mockNpm({
- globalDir: 'path/to/node_modules/',
- prefix: 'foo',
+t.test('--no-audit and --ignore-scripts', async t => {
+ const { npm, joinedOutput, registry } = await loadMockNpm(t, {
config: {
- global: false,
'ignore-scripts': true,
+ audit: false,
},
- })
- const ci = new CI(npm)
-
- await ci.exec([])
- t.equal(REIFY_CALLED, true, 'called reify')
- t.strictSame(SCRIPTS, [], 'no scripts when running ci')
-})
-
-t.test('should use Arborist and run-script', async t => {
- const scripts = [
- 'preinstall',
- 'install',
- 'postinstall',
- 'prepublish', // XXX should we remove this finally??
- 'preprepare',
- 'prepare',
- 'postprepare',
- ]
-
- // set to true when timer starts, false when it ends
- // when the test is done, we assert that all timers ended
- const timers = {}
- const onTime = msg => {
- if (timers[msg]) {
- throw new Error(`saw duplicate timer: ${msg}`)
- }
- timers[msg] = true
- }
- const onTimeEnd = msg => {
- if (!timers[msg]) {
- throw new Error(`ended timer that was not started: ${msg}`)
- }
- timers[msg] = false
- }
- process.on('time', onTime)
- process.on('timeEnd', onTimeEnd)
- t.teardown(() => {
- process.removeListener('time', onTime)
- process.removeListener('timeEnd', onTimeEnd)
- })
-
- const path = t.testdir({
- node_modules: {
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.2.3',
- }),
+ prefixDir: {
+ abbrev: {
+ 'package.json': '{"name": "abbrev", "version": "1.0.0"}',
+ test: 'test-file',
},
- '.dotdir': {},
- '.dotfile': 'a file with a dot',
+ 'package.json': JSON.stringify({
+ ...packageJson,
+ // Would make install fail
+ scripts: { install: 'echo "SHOULD NOT RUN" && exit 1' },
+ }),
+ 'package-lock.json': JSON.stringify(packageLock),
},
})
- const expectRimrafs = 3
- let actualRimrafs = 0
-
- const CI = t.mock('../../../lib/commands/ci.js', {
- '../../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/run-script': opts => {
- t.match(opts, { event: scripts.shift() })
- },
- '@npmcli/arborist': function (args) {
- t.ok(args, 'gets options object')
- this.loadVirtual = () => {
- t.ok(true, 'loadVirtual is called')
- return Promise.resolve(true)
- }
- this.reify = () => {
- t.ok(true, 'reify is called')
- }
- this.buildIdealTree = () => {}
- this.virtualTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
- this.idealTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
- },
- rimraf: (path, ...args) => {
- actualRimrafs++
- t.ok(path, 'rimraf called with path')
- // callback is always last arg
- args.pop()()
- },
- '../../../lib/utils/reify-output.js': function (arb) {
- t.ok(arb, 'gets arborist tree')
- },
+ require('nock').emitter.on('no match', req => {
+ t.fail('Should not audit')
})
-
- const npm = mockNpm({
- prefix: path,
- config: {
- global: false,
- },
+ const manifest = registry.manifest({ name: 'abbrev' })
+ await registry.tarball({
+ manifest: manifest.versions['1.0.0'],
+ tarball: path.join(npm.prefix, 'abbrev'),
})
- const ci = new CI(npm)
-
- await ci.exec(null)
- for (const [msg, result] of Object.entries(timers)) {
- t.notOk(result, `properly resolved ${msg} timer`)
- }
- t.match(timers, { 'npm-ci:rm': false }, 'saw the rimraf timer')
- t.equal(actualRimrafs, expectRimrafs, 'removed the right number of things')
- t.strictSame(scripts, [], 'called all scripts')
+ await npm.exec('ci', [])
+ t.match(joinedOutput(), 'added 1 package in', 'would fail if install script ran')
})
-t.test('should pass flatOptions to Arborist.reify', async t => {
- t.plan(1)
- const CI = t.mock('../../../lib/commands/ci.js', {
- '../../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/run-script': opts => {},
- '@npmcli/arborist': function () {
- this.loadVirtual = () => Promise.resolve(true)
- this.reify = async (options) => {
- t.equal(options.production, true, 'should pass flatOptions to Arborist.reify')
- }
- this.buildIdealTree = () => {}
- this.virtualTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
- this.idealTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
+t.test('lifecycle scripts', async t => {
+ const scripts = []
+ const { npm, registry } = await loadMockNpm(t, {
+ prefixDir: {
+ abbrev: abbrev,
+ 'package.json': JSON.stringify(packageJson),
+ 'package-lock.json': JSON.stringify(packageLock),
+ },
+ mocks: {
+ '@npmcli/run-script': (opts) => {
+ t.ok(opts.banner)
+ scripts.push(opts.event)
+ },
},
})
- const npm = mockNpm({
- prefix: 'foo',
- flatOptions: {
- production: true,
- },
+ const manifest = registry.manifest({ name: 'abbrev' })
+ await registry.tarball({
+ manifest: manifest.versions['1.0.0'],
+ tarball: path.join(npm.prefix, 'abbrev'),
})
- const ci = new CI(npm)
- await ci.exec(null)
+ registry.nock.post('/-/npm/v1/security/advisories/bulk').reply(200, {})
+ await npm.exec('ci', [])
+ t.same(scripts, [
+ 'preinstall',
+ 'install',
+ 'postinstall',
+ 'prepublish',
+ 'preprepare',
+ 'prepare',
+ 'postprepare',
+ ], 'runs appropriate scripts, in order')
})
t.test('should throw if package-lock.json or npm-shrinkwrap missing', async t => {
- const testDir = t.testdir({
- 'index.js': 'some contents',
- 'package.json': 'some info',
- })
-
- const CI = t.mock('../../../lib/commands/ci.js', {
- '@npmcli/run-script': opts => {},
- '../../../lib/utils/reify-finish.js': async () => {},
- 'proc-log': {
- verbose: () => {
- t.ok(true, 'log fn called')
+ const { npm } = await loadMockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(packageJson),
+ node_modules: {
+ 'test-file': 'should not be removed',
},
},
})
- const npm = mockNpm({
- prefix: testDir,
- config: {
- global: false,
- },
- })
- const ci = new CI(npm)
- await t.rejects(
- ci.exec(null),
- /package-lock.json/,
- 'throws error when there is no package-lock'
+ await t.rejects(npm.exec('ci', []), { code: 'EUSAGE', message: /package-lock.json/ })
+ await t.resolveMatch(
+ fs.exists(path.join(npm.prefix, 'node_modules', 'test-file')),
+ true,
+ 'does not remove node_modules'
)
})
t.test('should throw ECIGLOBAL', async t => {
- const CI = t.mock('../../../lib/commands/ci.js', {
- '@npmcli/run-script': opts => {},
- '../../../lib/utils/reify-finish.js': async () => {},
- })
- const npm = mockNpm({
- prefix: 'foo',
- config: {
- global: true,
- },
- })
- const ci = new CI(npm)
- await t.rejects(
- ci.exec(null),
- { code: 'ECIGLOBAL' },
- 'throws error with global packages'
- )
-})
-
-t.test('should remove existing node_modules before installing', async t => {
- t.plan(3)
- const testDir = t.testdir({
- node_modules: {
- 'some-file': 'some contents',
- },
+ const { npm } = await loadMockNpm(t, {
+ config: { global: true },
})
-
- const CI = t.mock('../../../lib/commands/ci.js', {
- '@npmcli/run-script': opts => {},
- '../../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/arborist': function () {
- this.loadVirtual = () => Promise.resolve(true)
- this.reify = async (options) => {
- t.equal(options.packageLock, true, 'npm ci should never ignore lock')
- t.equal(options.save, false, 'npm ci should never save')
- // check if node_modules was removed before reifying
- const contents = await readdir(testDir)
- const nodeModules = contents.filter((path) => path.startsWith('node_modules'))
- t.same(nodeModules, ['node_modules'], 'should only have the node_modules directory')
- }
- this.buildIdealTree = () => {}
- this.virtualTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
- this.idealTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
- },
- })
-
- const npm = mockNpm({
- prefix: testDir,
- config: {
- global: false,
- },
- })
- const ci = new CI(npm)
-
- await ci.exec(null)
+ await t.rejects(npm.exec('ci', []), { code: 'ECIGLOBAL' })
})
t.test('should throw error when ideal inventory mismatches virtual', async t => {
- const CI = t.mock('../../../lib/commands/ci.js', {
- '../../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/run-script': ({ event }) => {},
- '@npmcli/arborist': function () {
- this.loadVirtual = async () => {}
- this.reify = () => {}
- this.buildIdealTree = () => {}
- this.virtualTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '1.0.0' }],
- ]),
- }
- this.idealTree = {
- inventory: new Map([
- ['foo', { name: 'foo', version: '2.0.0' }],
- ]),
- }
- },
- })
-
- const npm = mockNpm({
- globalDir: 'path/to/node_modules/',
- prefix: 'foo',
- config: {
- global: false,
- 'ignore-scripts': true,
+ const { npm, registry } = await loadMockNpm(t, {
+ prefixDir: {
+ abbrev: abbrev,
+ 'package.json': JSON.stringify({
+ ...packageJson,
+ dependencies: { notabbrev: '^1.0.0' },
+ }),
+ 'package-lock.json': JSON.stringify(packageLock),
+ node_modules: {
+ 'test-file': 'should not be removed',
+ },
},
})
- const ci = new CI(npm)
-
- try {
- await ci.exec([])
- } catch (err) {
- t.matchSnapshot(err.message)
- }
+ const manifest = registry.manifest({ name: 'notabbrev' })
+ await registry.package({ manifest })
+ await t.rejects(
+ npm.exec('ci', []),
+ { code: 'EUSAGE', message: /in sync/ }
+ )
+ await t.resolveMatch(
+ fs.exists(path.join(npm.prefix, 'node_modules', 'test-file')),
+ true,
+ 'does not remove node_modules'
+ )
})
diff --git a/deps/npm/test/lib/commands/deprecate.js b/deps/npm/test/lib/commands/deprecate.js
index 8a925fc2a6..3a610a703a 100644
--- a/deps/npm/test/lib/commands/deprecate.js
+++ b/deps/npm/test/lib/commands/deprecate.js
@@ -44,7 +44,7 @@ t.test('completion', async t => {
registry.whoami({ statusCode: 404, body: {} })
- t.rejects(testComp([], []), { code: 'ENEEDAUTH' })
+ t.rejects(testComp([], []), { code: 'EINVALIDTYPE' })
})
t.test('no args', async t => {
diff --git a/deps/npm/test/lib/commands/exec.js b/deps/npm/test/lib/commands/exec.js
index 1117885b91..049ed327c8 100644
--- a/deps/npm/test/lib/commands/exec.js
+++ b/deps/npm/test/lib/commands/exec.js
@@ -473,7 +473,7 @@ t.test('npm exec foo, not present locally but in central loc', async t => {
await exec.exec(['foo', 'one arg', 'two arg'])
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
t.match(ARB_CTOR, [{ path }])
- t.match(ARB_REIFY, [], 'no need to install again, already there')
+ t.strictSame(ARB_REIFY, [], 'no need to install again, already there')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}`
t.match(RUN_SCRIPTS, [
diff --git a/deps/npm/test/lib/commands/outdated.js b/deps/npm/test/lib/commands/outdated.js
index 14647ce6ce..4803c7e171 100644
--- a/deps/npm/test/lib/commands/outdated.js
+++ b/deps/npm/test/lib/commands/outdated.js
@@ -343,7 +343,9 @@ t.test('should return if no outdated deps', async t => {
})
await outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ },
}).exec([])
t.equal(logs.length, 0, 'no logs')
})
@@ -369,7 +371,9 @@ t.test('throws if error with a dep', async t => {
await t.rejects(
outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ },
}).exec([]),
'There is an error with this package.'
)
@@ -388,7 +392,9 @@ t.test('should skip missing non-prod deps', async t => {
})
await outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ },
}).exec([])
t.equal(logs.length, 0, 'no logs')
})
diff --git a/deps/npm/test/lib/commands/ping.js b/deps/npm/test/lib/commands/ping.js
index f808e0ac3b..dd2f83de08 100644
--- a/deps/npm/test/lib/commands/ping.js
+++ b/deps/npm/test/lib/commands/ping.js
@@ -1,113 +1,67 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
+const MockRegistry = require('../../fixtures/mock-registry.js')
-t.test('pings', async t => {
- t.plan(6)
-
- const registry = 'https://registry.npmjs.org'
- let noticeCalls = 0
- const Ping = t.mock('../../../lib/commands/ping.js', {
- '../../../lib/utils/ping.js': function (spec) {
- t.equal(spec.registry, registry, 'passes flatOptions')
- return {}
- },
- 'proc-log': {
- notice: (type, spec) => {
- ++noticeCalls
- if (noticeCalls === 1) {
- t.equal(type, 'PING', 'should log a PING')
- t.equal(spec, registry, 'should log the registry url')
- } else {
- t.equal(type, 'PONG', 'should log a PONG')
- t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
- }
- },
- },
- })
- const npm = mockNpm({
- config: { registry },
- flatOptions: { registry },
+t.test('no details', async t => {
+ const { npm, logs, joinedOutput } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
})
- const ping = new Ping(npm)
-
- await ping.exec([])
- t.equal(noticeCalls, 2, 'should have logged 2 lines')
+ registry.ping()
+ await npm.exec('ping', [])
+ t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]])
+ t.equal(joinedOutput(), '')
})
-t.test('pings and logs details', async t => {
- t.plan(8)
+t.test('with details', async t => {
+ const { npm, logs, joinedOutput } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.ping({ body: { test: true } })
+ await npm.exec('ping', [])
+ t.match(logs.notice, [
+ ['PING', 'https://registry.npmjs.org/'],
+ ['PONG', /[0-9]+ms/],
+ ['PONG', '{\n "test": true\n}'],
+ ])
+ t.match(joinedOutput(), '')
+})
- const registry = 'https://registry.npmjs.org'
- const details = { extra: 'data' }
- let noticeCalls = 0
- const Ping = t.mock('../../../lib/commands/ping.js', {
- '../../../lib/utils/ping.js': function (spec) {
- t.equal(spec.registry, registry, 'passes flatOptions')
- return details
- },
- 'proc-log': {
- notice: (type, spec) => {
- ++noticeCalls
- if (noticeCalls === 1) {
- t.equal(type, 'PING', 'should log a PING')
- t.equal(spec, registry, 'should log the registry url')
- } else if (noticeCalls === 2) {
- t.equal(type, 'PONG', 'should log a PONG')
- t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
- } else {
- t.equal(type, 'PONG', 'should log a PONG')
- const parsed = JSON.parse(spec)
- t.match(parsed, details, 'should log JSON stringified details')
- }
- },
- },
+t.test('valid json', async t => {
+ const { npm, logs, joinedOutput } = await loadMockNpm(t, {
+ config: { json: true },
})
- const npm = mockNpm({
- config: { registry },
- flatOptions: { registry },
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.ping()
+ await npm.exec('ping', [])
+ t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]])
+ t.match(JSON.parse(joinedOutput()), {
+ registry: npm.config.get('registry'),
+ time: /[0-9]+/,
+ details: {},
})
- const ping = new Ping(npm)
-
- await ping.exec([])
- t.equal(noticeCalls, 3, 'should have logged 3 lines')
})
-t.test('pings and returns json', async t => {
- t.plan(9)
-
- const registry = 'https://registry.npmjs.org'
- const details = { extra: 'data' }
- let noticeCalls = 0
- const Ping = t.mock('../../../lib/commands/ping.js', {
- '../../../lib/utils/ping.js': function (spec) {
- t.equal(spec.registry, registry, 'passes flatOptions')
- return details
- },
- 'proc-log': {
- notice: (type, spec) => {
- ++noticeCalls
- if (noticeCalls === 1) {
- t.equal(type, 'PING', 'should log a PING')
- t.equal(spec, registry, 'should log the registry url')
- } else {
- t.equal(type, 'PONG', 'should log a PONG')
- t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
- }
- },
- },
+t.test('invalid json', async t => {
+ const { npm, logs, joinedOutput } = await loadMockNpm(t, {
+ config: { json: true },
})
- const npm = mockNpm({
- config: { registry, json: true },
- flatOptions: { registry },
- output: function (spec) {
- const parsed = JSON.parse(spec)
- t.equal(parsed.registry, registry, 'returns the correct registry url')
- t.match(parsed.details, details, 'prints returned details')
- t.type(parsed.time, 'number', 'returns time as a number')
- },
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.ping({ body: '{not: real"json]' })
+ await npm.exec('ping', [])
+ t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]])
+ t.match(JSON.parse(joinedOutput()), {
+ registry: npm.config.get('registry'),
+ time: /[0-9]+/,
+ details: {},
})
- const ping = new Ping(npm)
-
- await ping.exec([])
- t.equal(noticeCalls, 2, 'should have logged 2 lines')
})
diff --git a/deps/npm/test/lib/commands/set-script.js b/deps/npm/test/lib/commands/set-script.js
index 2c4fe57d68..cf0df53af1 100644
--- a/deps/npm/test/lib/commands/set-script.js
+++ b/deps/npm/test/lib/commands/set-script.js
@@ -130,7 +130,7 @@ t.test('warns when overwriting', async t => {
})
await setScript.exec(['arg1', 'arg2'])
- t.hasStrict(WARN_OUTPUT[0], ['set-script', 'Script "arg1" was overwritten'], 'warning was logged')
+ t.hasStrict(WARN_OUTPUT[1], ['set-script', 'Script "arg1" was overwritten'], 'warning was logged')
})
t.test('workspaces', async t => {
diff --git a/deps/npm/test/lib/commands/whoami.js b/deps/npm/test/lib/commands/whoami.js
index f483bd46d5..ad7c223888 100644
--- a/deps/npm/test/lib/commands/whoami.js
+++ b/deps/npm/test/lib/commands/whoami.js
@@ -5,7 +5,7 @@ const MockRegistry = require('../../fixtures/mock-registry.js')
const username = 'foo'
const auth = { '//registry.npmjs.org/:_authToken': 'test-auth-token' }
-t.test('npm whoami', async (t) => {
+t.test('npm whoami', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, { config: auth })
const registry = new MockRegistry({
tap: t,
@@ -17,7 +17,7 @@ t.test('npm whoami', async (t) => {
t.equal(joinedOutput(), username, 'should print username')
})
-t.test('npm whoami --json', async (t) => {
+t.test('npm whoami --json', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
json: true,
@@ -33,3 +33,23 @@ t.test('npm whoami --json', async (t) => {
await npm.exec('whoami', [])
t.equal(JSON.parse(joinedOutput()), username, 'should print username')
})
+
+t.test('credentials from token', async t => {
+ const { npm, joinedOutput } = await loadMockNpm(t, {
+ config: {
+ '//registry.npmjs.org/:username': username,
+ '//registry.npmjs.org/:_password': 'hunter2',
+ },
+ })
+ await npm.exec('whoami', [])
+ t.equal(joinedOutput(), username, 'should print username')
+})
+
+t.test('not logged in', async t => {
+ const { npm } = await loadMockNpm(t, {
+ config: {
+ json: true,
+ },
+ })
+ await t.rejects(npm.exec('whoami', []), { code: 'ENEEDAUTH' })
+})
diff --git a/deps/npm/test/lib/npm.js b/deps/npm/test/lib/npm.js
index 566cbca20f..cd692a93f5 100644
--- a/deps/npm/test/lib/npm.js
+++ b/deps/npm/test/lib/npm.js
@@ -654,3 +654,61 @@ t.test('implicit workspace accept', async t => {
})
await t.rejects(mock.npm.exec('org', []), /.*Usage/)
})
+
+t.test('usage', async t => {
+ const { npm } = await loadMockNpm(t)
+ t.afterEach(() => {
+ npm.config.set('viewer', null)
+ npm.config.set('long', false)
+ npm.config.set('userconfig', '/some/config/file/.npmrc')
+ })
+ const { dirname } = require('path')
+ const basedir = dirname(dirname(__dirname))
+ t.cleanSnapshot = str => str.split(basedir).join('{BASEDIR}')
+ .split(require('../../package.json').version).join('{VERSION}')
+
+ npm.config.set('viewer', null)
+ npm.config.set('long', false)
+ npm.config.set('userconfig', '/some/config/file/.npmrc')
+
+ t.test('basic usage', async t => {
+ t.matchSnapshot(await npm.usage)
+ t.end()
+ })
+
+ t.test('with browser', async t => {
+ npm.config.set('viewer', 'browser')
+ t.matchSnapshot(await npm.usage)
+ t.end()
+ })
+
+ t.test('with long', async t => {
+ npm.config.set('long', true)
+ t.matchSnapshot(await npm.usage)
+ t.end()
+ })
+
+ t.test('set process.stdout.columns', async t => {
+ const { columns } = process.stdout
+ t.teardown(() => {
+ Object.defineProperty(process.stdout, 'columns', {
+ value: columns,
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ })
+ })
+ const cases = [0, 90]
+ for (const cols of cases) {
+ t.test(`columns=${cols}`, async t => {
+ Object.defineProperty(process.stdout, 'columns', {
+ value: cols,
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ })
+ t.matchSnapshot(await npm.usage)
+ })
+ }
+ })
+})
diff --git a/deps/npm/test/lib/utils/get-identity.js b/deps/npm/test/lib/utils/get-identity.js
deleted file mode 100644
index 5e6de9ca9c..0000000000
--- a/deps/npm/test/lib/utils/get-identity.js
+++ /dev/null
@@ -1,103 +0,0 @@
-const t = require('tap')
-
-t.test('throws ENOREGISTRY when no registry option is provided', async (t) => {
- t.plan(2)
- const getIdentity = t.mock('../../../lib/utils/get-identity.js')
-
- try {
- await getIdentity({})
- } catch (err) {
- t.equal(err.code, 'ENOREGISTRY', 'assigns the appropriate error code')
- t.equal(err.message, 'No registry specified.', 'returns the correct error message')
- }
-})
-
-t.test('returns username from uri when provided', async (t) => {
- t.plan(1)
-
- const getIdentity = t.mock('../../../lib/utils/get-identity.js')
- const npm = {
- config: {
- getCredentialsByURI: () => {
- return { username: 'foo' }
- },
- },
- }
-
- const identity = await getIdentity(npm, { registry: 'https://registry.npmjs.org' })
- t.equal(identity, 'foo', 'returns username from uri')
-})
-
-t.test('calls registry whoami when token is provided', async (t) => {
- t.plan(3)
-
- const options = {
- registry: 'https://registry.npmjs.org',
- token: 'thisisnotreallyatoken',
- }
-
- const getIdentity = t.mock('../../../lib/utils/get-identity.js', {
- 'npm-registry-fetch': {
- json: (path, opts) => {
- t.equal(path, '/-/whoami', 'calls whoami')
- t.same(opts, options, 'passes through provided options')
- return { username: 'foo' }
- },
- },
- })
- const npm = {
- config: {
- getCredentialsByURI: () => options,
- },
- }
-
- const identity = await getIdentity(npm, options)
- t.equal(identity, 'foo', 'fetched username from registry')
-})
-
-t.test('throws ENEEDAUTH when response does not include a username', async (t) => {
- t.plan(3)
-
- const options = {
- registry: 'https://registry.npmjs.org',
- token: 'thisisnotreallyatoken',
- }
-
- const getIdentity = t.mock('../../../lib/utils/get-identity.js', {
- 'npm-registry-fetch': {
- json: (path, opts) => {
- t.equal(path, '/-/whoami', 'calls whoami')
- t.same(opts, options, 'passes through provided options')
- return {}
- },
- },
- })
- const npm = {
- config: {
- getCredentialsByURI: () => options,
- },
- }
-
- try {
- await getIdentity(npm, options)
- } catch (err) {
- t.equal(err.code, 'ENEEDAUTH', 'throws correct error code')
- }
-})
-
-t.test('throws ENEEDAUTH when neither username nor token is configured', async (t) => {
- t.plan(1)
- const getIdentity = t.mock('../../../lib/utils/get-identity.js', {
- })
- const npm = {
- config: {
- getCredentialsByURI: () => ({}),
- },
- }
-
- try {
- await getIdentity(npm, { registry: 'https://registry.npmjs.org' })
- } catch (err) {
- t.equal(err.code, 'ENEEDAUTH', 'throws correct error code')
- }
-})
diff --git a/deps/npm/test/lib/utils/is-windows.js b/deps/npm/test/lib/utils/is-windows.js
deleted file mode 100644
index a1d520f062..0000000000
--- a/deps/npm/test/lib/utils/is-windows.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const t = require('tap')
-
-const mockGlobals = require('../../fixtures/mock-globals')
-
-t.test('is not windows', async t => {
- mockGlobals(t, { 'process.platform': 'posix' })
- t.match({
- isWindows: false,
- isWindowsShell: false,
- }, t.mock('../../../lib/utils/is-windows.js'))
-})
-
-t.test('is windows, shell', async t => {
- mockGlobals(t, {
- 'process.platform': 'win32',
- 'process.env': {
- MSYSTEM: 'notmingw',
- TERM: 'notcygwin',
- },
- })
- t.match({
- isWindows: true,
- isWindowsShell: true,
- }, t.mock('../../../lib/utils/is-windows.js'))
-})
-
-t.test('is windows, not shell', async t => {
- mockGlobals(t, {
- 'process.platform': 'win32',
- 'process.env': {
- MSYSTEM: 'MINGW32',
- TERM: 'cygwin',
- },
- })
- t.match({
- isWindows: true,
- isWindowsShell: false,
- }, t.mock('../../../lib/utils/is-windows.js'))
-})
diff --git a/deps/npm/test/lib/utils/npm-usage.js b/deps/npm/test/lib/utils/npm-usage.js
deleted file mode 100644
index 035d4bbb21..0000000000
--- a/deps/npm/test/lib/utils/npm-usage.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const t = require('tap')
-const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
-
-t.test('usage', async t => {
- const { npm } = await loadMockNpm(t)
- t.afterEach(() => {
- npm.config.set('viewer', null)
- npm.config.set('long', false)
- npm.config.set('userconfig', '/some/config/file/.npmrc')
- })
- const { dirname } = require('path')
- const basedir = dirname(dirname(dirname(__dirname)))
- t.cleanSnapshot = str => str.split(basedir).join('{BASEDIR}')
- .split(require('../../../package.json').version).join('{VERSION}')
-
- npm.config.set('viewer', null)
- npm.config.set('long', false)
- npm.config.set('userconfig', '/some/config/file/.npmrc')
-
- t.test('basic usage', async t => {
- t.matchSnapshot(await npm.usage)
- t.end()
- })
-
- t.test('with browser', async t => {
- npm.config.set('viewer', 'browser')
- t.matchSnapshot(await npm.usage)
- t.end()
- })
-
- t.test('with long', async t => {
- npm.config.set('long', true)
- t.matchSnapshot(await npm.usage)
- t.end()
- })
-
- t.test('set process.stdout.columns', async t => {
- const { columns } = process.stdout
- t.teardown(() => {
- Object.defineProperty(process.stdout, 'columns', {
- value: columns,
- enumerable: true,
- configurable: true,
- writable: true,
- })
- })
- const cases = [0, 90]
- for (const cols of cases) {
- t.test(`columns=${cols}`, async t => {
- Object.defineProperty(process.stdout, 'columns', {
- value: cols,
- enumerable: true,
- configurable: true,
- writable: true,
- })
- t.matchSnapshot(await npm.usage)
- })
- }
- })
-})
diff --git a/deps/npm/test/lib/utils/ping.js b/deps/npm/test/lib/utils/ping.js
deleted file mode 100644
index 1bebfa69d2..0000000000
--- a/deps/npm/test/lib/utils/ping.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const t = require('tap')
-
-t.test('pings', async (t) => {
- t.plan(3)
-
- const options = { fake: 'options' }
- const response = { some: 'details' }
- const ping = t.mock('../../../lib/utils/ping.js', {
- 'npm-registry-fetch': (url, opts) => {
- t.equal(url, '/-/ping?write=true', 'calls the correct url')
- t.equal(opts, options, 'passes through options')
- return { json: () => Promise.resolve(response) }
- },
- })
-
- const res = await ping(options)
- t.match(res, response, 'returns json response')
-})
-
-t.test('catches errors and returns empty json', async (t) => {
- t.plan(3)
-
- const options = { fake: 'options' }
- const response = { some: 'details' }
- const ping = t.mock('../../../lib/utils/ping.js', {
- 'npm-registry-fetch': (url, opts) => {
- t.equal(url, '/-/ping?write=true', 'calls the correct url')
- t.equal(opts, options, 'passes through options')
- return { json: () => Promise.reject(response) }
- },
- })
-
- const res = await ping(options)
- t.match(res, {}, 'returns empty json response')
-})