From d282270502cc2ecafdee1416952fc34361347c6f Mon Sep 17 00:00:00 2001 From: Behnam Mohammadi Date: Tue, 31 Aug 2021 09:53:16 +0430 Subject: [PATCH 01/35] fix(docs): add missing notice --- docs/content/using-npm/workspaces.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/content/using-npm/workspaces.md b/docs/content/using-npm/workspaces.md index 7cc125b3c7a7c..baa1eedeed41f 100644 --- a/docs/content/using-npm/workspaces.md +++ b/docs/content/using-npm/workspaces.md @@ -176,6 +176,22 @@ npm run test --workspaces Will run the `test` script in both `./packages/a` and `./packages/b`. +Order of run depend on your definition in `workspaces` at `package.json` + +``` +{ + "workspaces": [ "packages/a", "packages/b" ] +} +``` + +Order of run is different with: + +``` +{ + "workspaces": [ "packages/b", "packages/a" ] +} +``` + ### See also * [npm install](/commands/npm-install) From 1fa549db0955b55fd680a658809a6d97be306b06 Mon Sep 17 00:00:00 2001 From: nlf Date: Tue, 31 Aug 2021 09:13:35 -0700 Subject: [PATCH 02/35] deps: @npmcli/config@2.3.0 * feat: export npm_config_local_prefix and npm_config_global_prefix to the environment --- node_modules/@npmcli/config/lib/set-envs.js | 2 ++ node_modules/@npmcli/config/package.json | 2 +- package-lock.json | 14 +++++++------- package.json | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/node_modules/@npmcli/config/lib/set-envs.js b/node_modules/@npmcli/config/lib/set-envs.js index 370a2f3ffd34b..8eed0221ba80e 100644 --- a/node_modules/@npmcli/config/lib/set-envs.js +++ b/node_modules/@npmcli/config/lib/set-envs.js @@ -86,6 +86,8 @@ const setEnvs = (config) => { // also set some other common nice envs that we want to rely on env.HOME = config.home + env.npm_config_global_prefix = config.globalPrefix + env.npm_config_local_prefix = config.localPrefix if (cliConf.editor) env.EDITOR = cliConf.editor diff --git a/node_modules/@npmcli/config/package.json b/node_modules/@npmcli/config/package.json index f80669640ebd4..b31eecbe35979 100644 --- a/node_modules/@npmcli/config/package.json +++ b/node_modules/@npmcli/config/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/config", - "version": "2.2.0", + "version": "2.3.0", "files": [ "lib" ], diff --git a/package-lock.json b/package-lock.json index 76b333cc8902d..4f17b2dfef834 100644 --- a/package-lock.json +++ b/package-lock.json @@ -85,7 +85,7 @@ "dependencies": { "@npmcli/arborist": "^2.8.2", "@npmcli/ci-detect": "^1.2.0", - "@npmcli/config": "^2.2.0", + "@npmcli/config": "^2.3.0", "@npmcli/map-workspaces": "^1.0.4", "@npmcli/package-json": "^1.0.1", "@npmcli/run-script": "^1.8.6", @@ -813,9 +813,9 @@ "inBundle": true }, "node_modules/@npmcli/config": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-2.2.0.tgz", - "integrity": "sha512-y0V3F7RCWXy8kBOvKvKSRUNKRobLB6vL/UNchy/6+IUNIqu+UyrY3Z7jvj1ZA/AkYc/0WkCUtppCo+bPhMU8Aw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-2.3.0.tgz", + "integrity": "sha512-yjiC1xv7KTmUTqfRwN2ZL7BHV160ctGF0fLXmKkkMXj40UOvBe45Apwvt5JsFRtXSoHkUYy1ouzscziuWNzklg==", "inBundle": true, "dependencies": { "ini": "^2.0.0", @@ -11057,9 +11057,9 @@ "integrity": "sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==" }, "@npmcli/config": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-2.2.0.tgz", - "integrity": "sha512-y0V3F7RCWXy8kBOvKvKSRUNKRobLB6vL/UNchy/6+IUNIqu+UyrY3Z7jvj1ZA/AkYc/0WkCUtppCo+bPhMU8Aw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-2.3.0.tgz", + "integrity": "sha512-yjiC1xv7KTmUTqfRwN2ZL7BHV160ctGF0fLXmKkkMXj40UOvBe45Apwvt5JsFRtXSoHkUYy1ouzscziuWNzklg==", "requires": { "ini": "^2.0.0", "mkdirp-infer-owner": "^2.0.0", diff --git a/package.json b/package.json index d5f3cf54cf89c..30877f8de75c5 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "dependencies": { "@npmcli/arborist": "^2.8.2", "@npmcli/ci-detect": "^1.2.0", - "@npmcli/config": "^2.2.0", + "@npmcli/config": "^2.3.0", "@npmcli/map-workspaces": "^1.0.4", "@npmcli/package-json": "^1.0.1", "@npmcli/run-script": "^1.8.6", From 6f431fe2325f77b4370f95848359a36fe7a011d1 Mon Sep 17 00:00:00 2001 From: tripu <1016538+tripu@users.noreply.github.com> Date: Fri, 27 Aug 2021 12:49:18 +0200 Subject: [PATCH 03/35] =?UTF-8?q?docs:=20Fix=20one=20=E2=80=9Csee=20also?= =?UTF-8?q?=E2=80=9D=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/npm/cli/pull/3690 Credit: @tripu Close: #3690 Reviewed-by: @wraithgar --- docs/content/commands/npm-deprecate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/commands/npm-deprecate.md b/docs/content/commands/npm-deprecate.md index 4888e42e8ba86..438a54ec6e4f3 100644 --- a/docs/content/commands/npm-deprecate.md +++ b/docs/content/commands/npm-deprecate.md @@ -76,4 +76,4 @@ password, npm will prompt on the command line for one. * [npm publish](/commands/npm-publish) * [npm registry](/using-npm/registry) * [npm owner](/commands/npm-owner) -* [npm owner](/commands/npm-adduser) +* [npm adduser](/commands/npm-adduser) From e91578d10b1d5d930fec32e7070d975af4892140 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 31 Aug 2021 09:18:14 -0700 Subject: [PATCH 04/35] deps: minpass-fetch@1.4.1 * Made rejectUnauthorized depend on NODE_TLS_REJECT_UNAUTHORIZED --- node_modules/minipass-fetch/lib/request.js | 2 +- node_modules/minipass-fetch/package.json | 5 ++--- package-lock.json | 12 ++++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/node_modules/minipass-fetch/lib/request.js b/node_modules/minipass-fetch/lib/request.js index 173f415d18e7b..278b27874eaac 100644 --- a/node_modules/minipass-fetch/lib/request.js +++ b/node_modules/minipass-fetch/lib/request.js @@ -82,7 +82,7 @@ class Request extends Body { key, passphrase, pfx, - rejectUnauthorized = true, + rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0', secureOptions, secureProtocol, servername, diff --git a/node_modules/minipass-fetch/package.json b/node_modules/minipass-fetch/package.json index 64dab7816bd12..1d7d9e4756623 100644 --- a/node_modules/minipass-fetch/package.json +++ b/node_modules/minipass-fetch/package.json @@ -1,6 +1,6 @@ { "name": "minipass-fetch", - "version": "1.3.4", + "version": "1.4.1", "description": "An implementation of window.fetch in Node.js using Minipass streams", "license": "MIT", "main": "lib/index.js", @@ -22,11 +22,10 @@ "form-data": "^2.5.1", "parted": "^0.1.1", "string-to-arraybuffer": "^1.0.2", - "tap": "^14.6.9", + "tap": "^15.0.9", "whatwg-url": "^7.0.0" }, "dependencies": { - "encoding": "^0.1.12", "minipass": "^3.1.0", "minipass-sized": "^1.0.3", "minizlib": "^2.0.0" diff --git a/package-lock.json b/package-lock.json index 4f17b2dfef834..c5cac9352e398 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5148,9 +5148,9 @@ } }, "node_modules/minipass-fetch": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.4.tgz", - "integrity": "sha512-TielGogIzbUEtd1LsjZFs47RWuHHfhl6TiCx1InVxApBAmQ8bL0dL5ilkLGcRvuyW/A9nE+Lvn855Ewz8S0PnQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", "inBundle": true, "dependencies": { "minipass": "^3.1.0", @@ -14263,9 +14263,9 @@ } }, "minipass-fetch": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.4.tgz", - "integrity": "sha512-TielGogIzbUEtd1LsjZFs47RWuHHfhl6TiCx1InVxApBAmQ8bL0dL5ilkLGcRvuyW/A9nE+Lvn855Ewz8S0PnQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", "requires": { "encoding": "^0.1.12", "minipass": "^3.1.0", From 6125db545315da0217fe7b05062fd0a504c9a45b Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 1 Sep 2021 10:39:33 -0700 Subject: [PATCH 05/35] deps: are-we-there-yet@1.1.6 --- node_modules/are-we-there-yet/CHANGES.md | 37 - node_modules/are-we-there-yet/LICENSE | 5 - node_modules/are-we-there-yet/LICENSE.md | 18 + .../are-we-there-yet/{ => lib}/index.js | 0 .../{ => lib}/tracker-base.js | 0 .../{ => lib}/tracker-group.js | 19 +- .../{ => lib}/tracker-stream.js | 0 .../are-we-there-yet/{ => lib}/tracker.js | 4 +- node_modules/are-we-there-yet/package.json | 52 +- node_modules/isarray/Makefile | 6 - node_modules/isarray/component.json | 19 - node_modules/isarray/index.js | 5 - node_modules/isarray/package.json | 45 - node_modules/isarray/test.js | 20 - node_modules/process-nextick-args/index.js | 45 - node_modules/process-nextick-args/license.md | 19 - .../process-nextick-args/package.json | 25 - node_modules/process-nextick-args/readme.md | 18 - .../doc/wg-meetings/2015-01-30.md | 60 -- .../readable-stream/duplex-browser.js | 1 - node_modules/readable-stream/duplex.js | 1 - .../readable-stream/errors-browser.js | 127 +++ node_modules/readable-stream/errors.js | 116 +++ .../readable-stream/experimentalWarning.js | 17 + .../readable-stream/lib/_stream_duplex.js | 96 ++- .../lib/_stream_passthrough.js | 10 +- .../readable-stream/lib/_stream_readable.js | 787 ++++++++++-------- .../readable-stream/lib/_stream_transform.js | 71 +- .../readable-stream/lib/_stream_writable.js | 390 ++++----- .../lib/internal/streams/BufferList.js | 79 -- .../lib/internal/streams/async_iterator.js | 207 +++++ .../lib/internal/streams/buffer_list.js | 210 +++++ .../lib/internal/streams/destroy.js | 65 +- .../lib/internal/streams/end-of-stream.js | 104 +++ .../lib/internal/streams/from-browser.js | 3 + .../lib/internal/streams/from.js | 64 ++ .../lib/internal/streams/pipeline.js | 97 +++ .../lib/internal/streams/state.js | 27 + node_modules/readable-stream/package.json | 54 +- node_modules/readable-stream/passthrough.js | 1 - .../readable-stream/readable-browser.js | 2 + node_modules/readable-stream/readable.js | 13 +- node_modules/readable-stream/transform.js | 1 - .../readable-stream/writable-browser.js | 1 - node_modules/readable-stream/writable.js | 8 - package-lock.json | 130 +-- 46 files changed, 1886 insertions(+), 1193 deletions(-) delete mode 100644 node_modules/are-we-there-yet/CHANGES.md delete mode 100644 node_modules/are-we-there-yet/LICENSE create mode 100644 node_modules/are-we-there-yet/LICENSE.md rename node_modules/are-we-there-yet/{ => lib}/index.js (100%) rename node_modules/are-we-there-yet/{ => lib}/tracker-base.js (100%) rename node_modules/are-we-there-yet/{ => lib}/tracker-group.js (88%) rename node_modules/are-we-there-yet/{ => lib}/tracker-stream.js (100%) rename node_modules/are-we-there-yet/{ => lib}/tracker.js (90%) delete mode 100644 node_modules/isarray/Makefile delete mode 100644 node_modules/isarray/component.json delete mode 100644 node_modules/isarray/index.js delete mode 100644 node_modules/isarray/package.json delete mode 100644 node_modules/isarray/test.js delete mode 100644 node_modules/process-nextick-args/index.js delete mode 100644 node_modules/process-nextick-args/license.md delete mode 100644 node_modules/process-nextick-args/package.json delete mode 100644 node_modules/process-nextick-args/readme.md delete mode 100644 node_modules/readable-stream/doc/wg-meetings/2015-01-30.md delete mode 100644 node_modules/readable-stream/duplex-browser.js delete mode 100644 node_modules/readable-stream/duplex.js create mode 100644 node_modules/readable-stream/errors-browser.js create mode 100644 node_modules/readable-stream/errors.js create mode 100644 node_modules/readable-stream/experimentalWarning.js delete mode 100644 node_modules/readable-stream/lib/internal/streams/BufferList.js create mode 100644 node_modules/readable-stream/lib/internal/streams/async_iterator.js create mode 100644 node_modules/readable-stream/lib/internal/streams/buffer_list.js create mode 100644 node_modules/readable-stream/lib/internal/streams/end-of-stream.js create mode 100644 node_modules/readable-stream/lib/internal/streams/from-browser.js create mode 100644 node_modules/readable-stream/lib/internal/streams/from.js create mode 100644 node_modules/readable-stream/lib/internal/streams/pipeline.js create mode 100644 node_modules/readable-stream/lib/internal/streams/state.js delete mode 100644 node_modules/readable-stream/passthrough.js delete mode 100644 node_modules/readable-stream/transform.js delete mode 100644 node_modules/readable-stream/writable-browser.js delete mode 100644 node_modules/readable-stream/writable.js diff --git a/node_modules/are-we-there-yet/CHANGES.md b/node_modules/are-we-there-yet/CHANGES.md deleted file mode 100644 index 21f3b1c128452..0000000000000 --- a/node_modules/are-we-there-yet/CHANGES.md +++ /dev/null @@ -1,37 +0,0 @@ -Hi, figured we could actually use a changelog now: - -## 1.1.5 2018-05-24 - -* [#92](https://github.com/iarna/are-we-there-yet/pull/92) Fix bug where - `finish` would throw errors when including `TrackerStream` objects in - `TrackerGroup` collections. (@brianloveswords) - -## 1.1.4 2017-04-21 - -* Fix typo in package.json - -## 1.1.3 2017-04-21 - -* Improve documentation and limit files included in the distribution. - -## 1.1.2 2016-03-15 - -* Add tracker group cycle detection and tests for it - -## 1.1.1 2016-01-29 - -* Fix a typo in stream completion tracker - -## 1.1.0 2016-01-29 - -* Rewrote completion percent computation to be low impact– no more walking a - tree of completion groups every time we need this info. Previously, with - medium sized tree of completion groups, even a relatively modest number of - calls to the top level `completed()` method would result in absurd numbers - of calls overall as it walked down the tree. We now, instead, keep track as - we bubble up changes, so the computation is limited to when data changes and - to the depth of that one branch, instead of _every_ node. (Plus, we were already - incurring _this_ cost, since we already bubbled out changes.) -* Moved different tracker types out to their own files. -* Made tests test for TOO MANY events too. -* Standarized the source code formatting diff --git a/node_modules/are-we-there-yet/LICENSE b/node_modules/are-we-there-yet/LICENSE deleted file mode 100644 index af4588069db82..0000000000000 --- a/node_modules/are-we-there-yet/LICENSE +++ /dev/null @@ -1,5 +0,0 @@ -Copyright (c) 2015, Rebecca Turner - -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/are-we-there-yet/LICENSE.md b/node_modules/are-we-there-yet/LICENSE.md new file mode 100644 index 0000000000000..845be76f64e78 --- /dev/null +++ b/node_modules/are-we-there-yet/LICENSE.md @@ -0,0 +1,18 @@ +ISC License + +Copyright npm, Inc. + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/are-we-there-yet/index.js b/node_modules/are-we-there-yet/lib/index.js similarity index 100% rename from node_modules/are-we-there-yet/index.js rename to node_modules/are-we-there-yet/lib/index.js diff --git a/node_modules/are-we-there-yet/tracker-base.js b/node_modules/are-we-there-yet/lib/tracker-base.js similarity index 100% rename from node_modules/are-we-there-yet/tracker-base.js rename to node_modules/are-we-there-yet/lib/tracker-base.js diff --git a/node_modules/are-we-there-yet/tracker-group.js b/node_modules/are-we-there-yet/lib/tracker-group.js similarity index 88% rename from node_modules/are-we-there-yet/tracker-group.js rename to node_modules/are-we-there-yet/lib/tracker-group.js index 9759e1226db04..9da13f8a7e116 100644 --- a/node_modules/are-we-there-yet/tracker-group.js +++ b/node_modules/are-we-there-yet/lib/tracker-group.js @@ -19,7 +19,9 @@ util.inherits(TrackerGroup, TrackerBase) function bubbleChange (trackerGroup) { return function (name, completed, tracker) { trackerGroup.completion[tracker.id] = completed - if (trackerGroup.finished) return + if (trackerGroup.finished) { + return + } trackerGroup.emit('change', name || trackerGroup.name, trackerGroup.completed(), trackerGroup) } } @@ -53,17 +55,22 @@ TrackerGroup.prototype.addUnit = function (unit, weight) { this.trackers.push(unit) this.completion[unit.id] = unit.completed() unit.on('change', this.bubbleChange) - if (!this.finished) this.emit('change', unit.name, this.completion[unit.id], unit) + if (!this.finished) { + this.emit('change', unit.name, this.completion[unit.id], unit) + } return unit } TrackerGroup.prototype.completed = function () { - if (this.trackers.length === 0) return 0 + if (this.trackers.length === 0) { + return 0 + } var valPerWeight = 1 / this.totalWeight var completed = 0 for (var ii = 0; ii < this.trackers.length; ii++) { var trackerId = this.trackers[ii].id - completed += valPerWeight * this.weight[trackerId] * this.completion[trackerId] + completed += + valPerWeight * this.weight[trackerId] * this.completion[trackerId] } return completed } @@ -82,7 +89,9 @@ TrackerGroup.prototype.newStream = function (name, todo, weight) { TrackerGroup.prototype.finish = function () { this.finished = true - if (!this.trackers.length) this.addUnit(new Tracker(), 1, true) + if (!this.trackers.length) { + this.addUnit(new Tracker(), 1, true) + } for (var ii = 0; ii < this.trackers.length; ii++) { var tracker = this.trackers[ii] tracker.finish() diff --git a/node_modules/are-we-there-yet/tracker-stream.js b/node_modules/are-we-there-yet/lib/tracker-stream.js similarity index 100% rename from node_modules/are-we-there-yet/tracker-stream.js rename to node_modules/are-we-there-yet/lib/tracker-stream.js diff --git a/node_modules/are-we-there-yet/tracker.js b/node_modules/are-we-there-yet/lib/tracker.js similarity index 90% rename from node_modules/are-we-there-yet/tracker.js rename to node_modules/are-we-there-yet/lib/tracker.js index 68c2339b45409..a8f8b3ba01391 100644 --- a/node_modules/are-we-there-yet/tracker.js +++ b/node_modules/are-we-there-yet/lib/tracker.js @@ -20,7 +20,9 @@ Tracker.prototype.addWork = function (work) { Tracker.prototype.completeWork = function (work) { this.workDone += work - if (this.workDone > this.workTodo) this.workDone = this.workTodo + if (this.workDone > this.workTodo) { + this.workDone = this.workTodo + } this.emit('change', this.name, this.completed(), this) } diff --git a/node_modules/are-we-there-yet/package.json b/node_modules/are-we-there-yet/package.json index c5990c9bdc5b2..d3901a86d67c6 100644 --- a/node_modules/are-we-there-yet/package.json +++ b/node_modules/are-we-there-yet/package.json @@ -1,35 +1,53 @@ { "name": "are-we-there-yet", - "version": "1.1.5", + "version": "1.1.6", "description": "Keep track of the overall completion of many disparate processes", - "main": "index.js", + "main": "lib/index.js", "scripts": { - "test": "standard && tap test/*.js" + "test": "tap", + "npmclilint": "npmcli-lint", + "lint": "eslint '**/*.js'", + "lintfix": "npm run lint -- --fix", + "posttest": "npm run lint", + "postsnap": "npm run lintfix --", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "snap": "tap" }, "repository": { "type": "git", - "url": "https://github.com/iarna/are-we-there-yet.git" + "url": "https://github.com/npm/are-we-there-yet.git" }, - "author": "Rebecca Turner (http://re-becca.org)", + "author": "GitHub Inc.", "license": "ISC", "bugs": { - "url": "https://github.com/iarna/are-we-there-yet/issues" + "url": "https://github.com/npm/are-we-there-yet/issues" }, - "homepage": "https://github.com/iarna/are-we-there-yet", + "homepage": "https://github.com/npm/are-we-there-yet", "devDependencies": { - "standard": "^11.0.1", - "tap": "^12.0.1" + "@npmcli/eslint-config": "^1.0.0", + "@npmcli/template-oss": "^1.0.2", + "eslint": "^7.32.0", + "eslint-plugin-node": "^11.1.0", + "tap": "^15.0.9" }, "dependencies": { "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "readable-stream": "^3.6.0" }, "files": [ - "index.js", - "tracker-base.js", - "tracker-group.js", - "tracker-stream.js", - "tracker.js", - "CHANGES.md" - ] + "bin", + "lib" + ], + "engines": { + "node": ">=10" + }, + "tap": { + "branches": 68, + "statements": 92, + "functions": 86, + "lines": 92 + }, + "templateVersion": "1.0.2" } diff --git a/node_modules/isarray/Makefile b/node_modules/isarray/Makefile deleted file mode 100644 index 787d56e1e982e..0000000000000 --- a/node_modules/isarray/Makefile +++ /dev/null @@ -1,6 +0,0 @@ - -test: - @node_modules/.bin/tape test.js - -.PHONY: test - diff --git a/node_modules/isarray/component.json b/node_modules/isarray/component.json deleted file mode 100644 index 9e31b68388901..0000000000000 --- a/node_modules/isarray/component.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name" : "isarray", - "description" : "Array#isArray for older browsers", - "version" : "0.0.1", - "repository" : "juliangruber/isarray", - "homepage": "https://github.com/juliangruber/isarray", - "main" : "index.js", - "scripts" : [ - "index.js" - ], - "dependencies" : {}, - "keywords": ["browser","isarray","array"], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT" -} diff --git a/node_modules/isarray/index.js b/node_modules/isarray/index.js deleted file mode 100644 index a57f63495943a..0000000000000 --- a/node_modules/isarray/index.js +++ /dev/null @@ -1,5 +0,0 @@ -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; diff --git a/node_modules/isarray/package.json b/node_modules/isarray/package.json deleted file mode 100644 index 1a4317a9c41c7..0000000000000 --- a/node_modules/isarray/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "isarray", - "description": "Array#isArray for older browsers", - "version": "1.0.0", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/isarray.git" - }, - "homepage": "https://github.com/juliangruber/isarray", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "tape": "~2.13.4" - }, - "keywords": [ - "browser", - "isarray", - "array" - ], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test.js", - "browsers": [ - "ie/8..latest", - "firefox/17..latest", - "firefox/nightly", - "chrome/22..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - }, - "scripts": { - "test": "tape test.js" - } -} diff --git a/node_modules/isarray/test.js b/node_modules/isarray/test.js deleted file mode 100644 index e0c3444d85d5c..0000000000000 --- a/node_modules/isarray/test.js +++ /dev/null @@ -1,20 +0,0 @@ -var isArray = require('./'); -var test = require('tape'); - -test('is array', function(t){ - t.ok(isArray([])); - t.notOk(isArray({})); - t.notOk(isArray(null)); - t.notOk(isArray(false)); - - var obj = {}; - obj[0] = true; - t.notOk(isArray(obj)); - - var arr = []; - arr.foo = 'bar'; - t.ok(isArray(arr)); - - t.end(); -}); - diff --git a/node_modules/process-nextick-args/index.js b/node_modules/process-nextick-args/index.js deleted file mode 100644 index 3eecf11488531..0000000000000 --- a/node_modules/process-nextick-args/index.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -if (typeof process === 'undefined' || - !process.version || - process.version.indexOf('v0.') === 0 || - process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { - module.exports = { nextTick: nextTick }; -} else { - module.exports = process -} - -function nextTick(fn, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); - } -} - diff --git a/node_modules/process-nextick-args/license.md b/node_modules/process-nextick-args/license.md deleted file mode 100644 index c67e3532b5424..0000000000000 --- a/node_modules/process-nextick-args/license.md +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2015 Calvin Metcalf - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.** diff --git a/node_modules/process-nextick-args/package.json b/node_modules/process-nextick-args/package.json deleted file mode 100644 index 6070b723fcd34..0000000000000 --- a/node_modules/process-nextick-args/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "process-nextick-args", - "version": "2.0.1", - "description": "process.nextTick but always with args", - "main": "index.js", - "files": [ - "index.js" - ], - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "https://github.com/calvinmetcalf/process-nextick-args.git" - }, - "author": "", - "license": "MIT", - "bugs": { - "url": "https://github.com/calvinmetcalf/process-nextick-args/issues" - }, - "homepage": "https://github.com/calvinmetcalf/process-nextick-args", - "devDependencies": { - "tap": "~0.2.6" - } -} diff --git a/node_modules/process-nextick-args/readme.md b/node_modules/process-nextick-args/readme.md deleted file mode 100644 index ecb432c9b21ff..0000000000000 --- a/node_modules/process-nextick-args/readme.md +++ /dev/null @@ -1,18 +0,0 @@ -process-nextick-args -===== - -[![Build Status](https://travis-ci.org/calvinmetcalf/process-nextick-args.svg?branch=master)](https://travis-ci.org/calvinmetcalf/process-nextick-args) - -```bash -npm install --save process-nextick-args -``` - -Always be able to pass arguments to process.nextTick, no matter the platform - -```js -var pna = require('process-nextick-args'); - -pna.nextTick(function (a, b, c) { - console.log(a, b, c); -}, 'step', 3, 'profit'); -``` diff --git a/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md deleted file mode 100644 index 83275f192e407..0000000000000 --- a/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ /dev/null @@ -1,60 +0,0 @@ -# streams WG Meeting 2015-01-30 - -## Links - -* **Google Hangouts Video**: http://www.youtube.com/watch?v=I9nDOSGfwZg -* **GitHub Issue**: https://github.com/iojs/readable-stream/issues/106 -* **Original Minutes Google Doc**: https://docs.google.com/document/d/17aTgLnjMXIrfjgNaTUnHQO7m3xgzHR2VXBTmi03Qii4/ - -## Agenda - -Extracted from https://github.com/iojs/readable-stream/labels/wg-agenda prior to meeting. - -* adopt a charter [#105](https://github.com/iojs/readable-stream/issues/105) -* release and versioning strategy [#101](https://github.com/iojs/readable-stream/issues/101) -* simpler stream creation [#102](https://github.com/iojs/readable-stream/issues/102) -* proposal: deprecate implicit flowing of streams [#99](https://github.com/iojs/readable-stream/issues/99) - -## Minutes - -### adopt a charter - -* group: +1's all around - -### What versioning scheme should be adopted? -* group: +1’s 3.0.0 -* domenic+group: pulling in patches from other sources where appropriate -* mikeal: version independently, suggesting versions for io.js -* mikeal+domenic: work with TC to notify in advance of changes -simpler stream creation - -### streamline creation of streams -* sam: streamline creation of streams -* domenic: nice simple solution posted - but, we lose the opportunity to change the model - may not be backwards incompatible (double check keys) - - **action item:** domenic will check - -### remove implicit flowing of streams on(‘data’) -* add isFlowing / isPaused -* mikeal: worrying that we’re documenting polyfill methods – confuses users -* domenic: more reflective API is probably good, with warning labels for users -* new section for mad scientists (reflective stream access) -* calvin: name the “third state” -* mikeal: maybe borrow the name from whatwg? -* domenic: we’re missing the “third state” -* consensus: kind of difficult to name the third state -* mikeal: figure out differences in states / compat -* mathias: always flow on data – eliminates third state - * explore what it breaks - -**action items:** -* ask isaac for ability to list packages by what public io.js APIs they use (esp. Stream) -* ask rod/build for infrastructure -* **chris**: explore the “flow on data” approach -* add isPaused/isFlowing -* add new docs section -* move isPaused to that section - - diff --git a/node_modules/readable-stream/duplex-browser.js b/node_modules/readable-stream/duplex-browser.js deleted file mode 100644 index f8b2db83dbe73..0000000000000 --- a/node_modules/readable-stream/duplex-browser.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/_stream_duplex.js'); diff --git a/node_modules/readable-stream/duplex.js b/node_modules/readable-stream/duplex.js deleted file mode 100644 index 46924cbfdf538..0000000000000 --- a/node_modules/readable-stream/duplex.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./readable').Duplex diff --git a/node_modules/readable-stream/errors-browser.js b/node_modules/readable-stream/errors-browser.js new file mode 100644 index 0000000000000..fb8e73e1893b1 --- /dev/null +++ b/node_modules/readable-stream/errors-browser.js @@ -0,0 +1,127 @@ +'use strict'; + +function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } + +var codes = {}; + +function createErrorType(code, message, Base) { + if (!Base) { + Base = Error; + } + + function getMessage(arg1, arg2, arg3) { + if (typeof message === 'string') { + return message; + } else { + return message(arg1, arg2, arg3); + } + } + + var NodeError = + /*#__PURE__*/ + function (_Base) { + _inheritsLoose(NodeError, _Base); + + function NodeError(arg1, arg2, arg3) { + return _Base.call(this, getMessage(arg1, arg2, arg3)) || this; + } + + return NodeError; + }(Base); + + NodeError.prototype.name = Base.name; + NodeError.prototype.code = code; + codes[code] = NodeError; +} // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js + + +function oneOf(expected, thing) { + if (Array.isArray(expected)) { + var len = expected.length; + expected = expected.map(function (i) { + return String(i); + }); + + if (len > 2) { + return "one of ".concat(thing, " ").concat(expected.slice(0, len - 1).join(', '), ", or ") + expected[len - 1]; + } else if (len === 2) { + return "one of ".concat(thing, " ").concat(expected[0], " or ").concat(expected[1]); + } else { + return "of ".concat(thing, " ").concat(expected[0]); + } + } else { + return "of ".concat(thing, " ").concat(String(expected)); + } +} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith + + +function startsWith(str, search, pos) { + return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; +} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith + + +function endsWith(str, search, this_len) { + if (this_len === undefined || this_len > str.length) { + this_len = str.length; + } + + return str.substring(this_len - search.length, this_len) === search; +} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes + + +function includes(str, search, start) { + if (typeof start !== 'number') { + start = 0; + } + + if (start + search.length > str.length) { + return false; + } else { + return str.indexOf(search, start) !== -1; + } +} + +createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) { + return 'The value "' + value + '" is invalid for option "' + name + '"'; +}, TypeError); +createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) { + // determiner: 'must be' or 'must not be' + var determiner; + + if (typeof expected === 'string' && startsWith(expected, 'not ')) { + determiner = 'must not be'; + expected = expected.replace(/^not /, ''); + } else { + determiner = 'must be'; + } + + var msg; + + if (endsWith(name, ' argument')) { + // For cases like 'first argument' + msg = "The ".concat(name, " ").concat(determiner, " ").concat(oneOf(expected, 'type')); + } else { + var type = includes(name, '.') ? 'property' : 'argument'; + msg = "The \"".concat(name, "\" ").concat(type, " ").concat(determiner, " ").concat(oneOf(expected, 'type')); + } + + msg += ". Received type ".concat(typeof actual); + return msg; +}, TypeError); +createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'); +createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) { + return 'The ' + name + ' method is not implemented'; +}); +createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'); +createErrorType('ERR_STREAM_DESTROYED', function (name) { + return 'Cannot call ' + name + ' after a stream was destroyed'; +}); +createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); +createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'); +createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'); +createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); +createErrorType('ERR_UNKNOWN_ENCODING', function (arg) { + return 'Unknown encoding: ' + arg; +}, TypeError); +createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event'); +module.exports.codes = codes; diff --git a/node_modules/readable-stream/errors.js b/node_modules/readable-stream/errors.js new file mode 100644 index 0000000000000..8471526d6e7f7 --- /dev/null +++ b/node_modules/readable-stream/errors.js @@ -0,0 +1,116 @@ +'use strict'; + +const codes = {}; + +function createErrorType(code, message, Base) { + if (!Base) { + Base = Error + } + + function getMessage (arg1, arg2, arg3) { + if (typeof message === 'string') { + return message + } else { + return message(arg1, arg2, arg3) + } + } + + class NodeError extends Base { + constructor (arg1, arg2, arg3) { + super(getMessage(arg1, arg2, arg3)); + } + } + + NodeError.prototype.name = Base.name; + NodeError.prototype.code = code; + + codes[code] = NodeError; +} + +// https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js +function oneOf(expected, thing) { + if (Array.isArray(expected)) { + const len = expected.length; + expected = expected.map((i) => String(i)); + if (len > 2) { + return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` + + expected[len - 1]; + } else if (len === 2) { + return `one of ${thing} ${expected[0]} or ${expected[1]}`; + } else { + return `of ${thing} ${expected[0]}`; + } + } else { + return `of ${thing} ${String(expected)}`; + } +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith +function startsWith(str, search, pos) { + return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith +function endsWith(str, search, this_len) { + if (this_len === undefined || this_len > str.length) { + this_len = str.length; + } + return str.substring(this_len - search.length, this_len) === search; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes +function includes(str, search, start) { + if (typeof start !== 'number') { + start = 0; + } + + if (start + search.length > str.length) { + return false; + } else { + return str.indexOf(search, start) !== -1; + } +} + +createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) { + return 'The value "' + value + '" is invalid for option "' + name + '"' +}, TypeError); +createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) { + // determiner: 'must be' or 'must not be' + let determiner; + if (typeof expected === 'string' && startsWith(expected, 'not ')) { + determiner = 'must not be'; + expected = expected.replace(/^not /, ''); + } else { + determiner = 'must be'; + } + + let msg; + if (endsWith(name, ' argument')) { + // For cases like 'first argument' + msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`; + } else { + const type = includes(name, '.') ? 'property' : 'argument'; + msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`; + } + + msg += `. Received type ${typeof actual}`; + return msg; +}, TypeError); +createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'); +createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) { + return 'The ' + name + ' method is not implemented' +}); +createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'); +createErrorType('ERR_STREAM_DESTROYED', function (name) { + return 'Cannot call ' + name + ' after a stream was destroyed'; +}); +createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); +createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'); +createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'); +createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); +createErrorType('ERR_UNKNOWN_ENCODING', function (arg) { + return 'Unknown encoding: ' + arg +}, TypeError); +createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event'); + +module.exports.codes = codes; diff --git a/node_modules/readable-stream/experimentalWarning.js b/node_modules/readable-stream/experimentalWarning.js new file mode 100644 index 0000000000000..78e841495bf24 --- /dev/null +++ b/node_modules/readable-stream/experimentalWarning.js @@ -0,0 +1,17 @@ +'use strict' + +var experimentalWarnings = new Set(); + +function emitExperimentalWarning(feature) { + if (experimentalWarnings.has(feature)) return; + var msg = feature + ' is an experimental feature. This feature could ' + + 'change at any time'; + experimentalWarnings.add(feature); + process.emitWarning(msg, 'ExperimentalWarning'); +} + +function noop() {} + +module.exports.emitExperimentalWarning = process.emitWarning + ? emitExperimentalWarning + : noop; diff --git a/node_modules/readable-stream/lib/_stream_duplex.js b/node_modules/readable-stream/lib/_stream_duplex.js index 57003c32d256c..67525192250f6 100644 --- a/node_modules/readable-stream/lib/_stream_duplex.js +++ b/node_modules/readable-stream/lib/_stream_duplex.js @@ -18,43 +18,37 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. - // a duplex stream is just a stream that is both readable and writable. // Since JS doesn't have multiple prototypal inheritance, this class // prototypally inherits from Readable, and then parasitically from // Writable. - 'use strict'; - /**/ -var pna = require('process-nextick-args'); -/**/ - -/**/ var objectKeys = Object.keys || function (obj) { var keys = []; + for (var key in obj) { keys.push(key); - }return keys; + } + + return keys; }; /**/ -module.exports = Duplex; -/**/ -var util = Object.create(require('core-util-is')); -util.inherits = require('inherits'); -/**/ +module.exports = Duplex; var Readable = require('./_stream_readable'); + var Writable = require('./_stream_writable'); -util.inherits(Duplex, Readable); +require('inherits')(Duplex, Readable); { - // avoid scope creep, the keys array can then be collected + // Allow the keys array to be GC'ed. var keys = objectKeys(Writable.prototype); + for (var v = 0; v < keys.length; v++) { var method = keys[v]; if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; @@ -63,18 +57,19 @@ util.inherits(Duplex, Readable); function Duplex(options) { if (!(this instanceof Duplex)) return new Duplex(options); - Readable.call(this, options); Writable.call(this, options); - - if (options && options.readable === false) this.readable = false; - - if (options && options.writable === false) this.writable = false; - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; - this.once('end', onend); + if (options) { + if (options.readable === false) this.readable = false; + if (options.writable === false) this.writable = false; + + if (options.allowHalfOpen === false) { + this.allowHalfOpen = false; + this.once('end', onend); + } + } } Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { @@ -82,20 +77,35 @@ Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { // because otherwise some prototype manipulation in // userland will fail enumerable: false, - get: function () { + get: function get() { return this._writableState.highWaterMark; } }); +Object.defineProperty(Duplex.prototype, 'writableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } +}); +Object.defineProperty(Duplex.prototype, 'writableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.length; + } +}); // the no-half-open enforcer -// the no-half-open enforcer function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) return; - - // no more data can be written. + // If the writable side ended, then we're ok. + if (this._writableState.ended) return; // no more data can be written. // But allow more writes to happen in this tick. - pna.nextTick(onEndNT, this); + + process.nextTick(onEndNT, this); } function onEndNT(self) { @@ -103,29 +113,27 @@ function onEndNT(self) { } Object.defineProperty(Duplex.prototype, 'destroyed', { - get: function () { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { if (this._readableState === undefined || this._writableState === undefined) { return false; } + return this._readableState.destroyed && this._writableState.destroyed; }, - set: function (value) { + set: function set(value) { // we ignore the value if the stream // has not been initialized yet if (this._readableState === undefined || this._writableState === undefined) { return; - } - - // backward compatibility, the user is explicitly + } // backward compatibility, the user is explicitly // managing destroyed + + this._readableState.destroyed = value; this._writableState.destroyed = value; } -}); - -Duplex.prototype._destroy = function (err, cb) { - this.push(null); - this.end(); - - pna.nextTick(cb, err); -}; \ No newline at end of file +}); \ No newline at end of file diff --git a/node_modules/readable-stream/lib/_stream_passthrough.js b/node_modules/readable-stream/lib/_stream_passthrough.js index 612edb4d8b443..32e7414c5a827 100644 --- a/node_modules/readable-stream/lib/_stream_passthrough.js +++ b/node_modules/readable-stream/lib/_stream_passthrough.js @@ -18,27 +18,19 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. - // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. - 'use strict'; module.exports = PassThrough; var Transform = require('./_stream_transform'); -/**/ -var util = Object.create(require('core-util-is')); -util.inherits = require('inherits'); -/**/ - -util.inherits(PassThrough, Transform); +require('inherits')(PassThrough, Transform); function PassThrough(options) { if (!(this instanceof PassThrough)) return new PassThrough(options); - Transform.call(this, options); } diff --git a/node_modules/readable-stream/lib/_stream_readable.js b/node_modules/readable-stream/lib/_stream_readable.js index 0f807646b0f67..192d451488f20 100644 --- a/node_modules/readable-stream/lib/_stream_readable.js +++ b/node_modules/readable-stream/lib/_stream_readable.js @@ -18,118 +18,110 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. - 'use strict'; -/**/ - -var pna = require('process-nextick-args'); -/**/ - module.exports = Readable; - /**/ -var isArray = require('isarray'); -/**/ -/**/ var Duplex; /**/ Readable.ReadableState = ReadableState; - /**/ + var EE = require('events').EventEmitter; -var EElistenerCount = function (emitter, type) { +var EElistenerCount = function EElistenerCount(emitter, type) { return emitter.listeners(type).length; }; /**/ /**/ + + var Stream = require('./internal/streams/stream'); /**/ -/**/ -var Buffer = require('safe-buffer').Buffer; +var Buffer = require('buffer').Buffer; + var OurUint8Array = global.Uint8Array || function () {}; + function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } + function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } - -/**/ - /**/ -var util = Object.create(require('core-util-is')); -util.inherits = require('inherits'); -/**/ -/**/ + var debugUtil = require('util'); -var debug = void 0; + +var debug; + if (debugUtil && debugUtil.debuglog) { debug = debugUtil.debuglog('stream'); } else { - debug = function () {}; + debug = function debug() {}; } /**/ -var BufferList = require('./internal/streams/BufferList'); + +var BufferList = require('./internal/streams/buffer_list'); + var destroyImpl = require('./internal/streams/destroy'); + +var _require = require('./internal/streams/state'), + getHighWaterMark = _require.getHighWaterMark; + +var _require$codes = require('../errors').codes, + ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, + ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; // Lazy loaded to improve the startup performance. + + var StringDecoder; +var createReadableStreamAsyncIterator; +var from; -util.inherits(Readable, Stream); +require('inherits')(Readable, Stream); +var errorOrDestroy = destroyImpl.errorOrDestroy; var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; function prependListener(emitter, event, fn) { // Sadly this is not cacheable as some libraries bundle their own // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); - - // This is a hack to make sure that our error handler is attached before any + if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); // This is a hack to make sure that our error handler is attached before any // userland ones. NEVER DO THIS. This is here only because this code needs // to continue to work with older versions of Node.js that do not include // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; } -function ReadableState(options, stream) { +function ReadableState(options, stream, isDuplex) { Duplex = Duplex || require('./_stream_duplex'); - - options = options || {}; - - // Duplex streams are both readable and writable, but share + options = options || {}; // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different // values for the readable and the writable sides of the duplex stream. // These options can be provided separately as readableXXX and writableXXX. - var isDuplex = stream instanceof Duplex; - // object stream flag. Used to make read(n) ignore n and to + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag. Used to make read(n) ignore n and to // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - - // the point at which it stops calling _read() to fill the buffer + this.objectMode = !!options.objectMode; + if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var readableHwm = options.readableHighWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - - if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm; - - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); - // A linked list is used to store data chunks instead of an array because the + this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than // array.shift() + this.buffer = new BufferList(); this.length = 0; this.pipes = null; @@ -137,37 +129,36 @@ function ReadableState(options, stream) { this.flowing = null; this.ended = false; this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the event 'readable'/'data' is emitted + this.reading = false; // a flag to be able to tell if the event 'readable'/'data' is emitted // immediately, or on a later tick. We set this to true at first, because // any actions that shouldn't happen until "later" should generally also // not happen before the first read call. - this.sync = true; - // whenever we return null, then we set a flag to say + this.sync = true; // whenever we return null, then we set a flag to say // that we're awaiting a 'readable' event emission. + this.needReadable = false; this.emittedReadable = false; this.readableListening = false; this.resumeScheduled = false; + this.paused = true; // Should close be emitted on destroy. Defaults to true. - // has it been destroyed - this.destroyed = false; + this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'end' (and potentially 'finish') - // Crypto is kind of old and crusty. Historically, its default string + this.autoDestroy = !!options.autoDestroy; // has it been destroyed + + this.destroyed = false; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; + this.defaultEncoding = options.defaultEncoding || 'utf8'; // the number of writers that are awaiting a drain event in .pipe()s - // if true, a maybeReadMore has been scheduled - this.readingMore = false; + this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled + this.readingMore = false; this.decoder = null; this.encoding = null; + if (options.encoding) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this.decoder = new StringDecoder(options.encoding); @@ -177,17 +168,16 @@ function ReadableState(options, stream) { function Readable(options) { Duplex = Duplex || require('./_stream_duplex'); + if (!(this instanceof Readable)) return new Readable(options); // Checking for a Stream.Duplex instance is faster here instead of inside + // the ReadableState constructor, at least with V8 6.5 - if (!(this instanceof Readable)) return new Readable(options); - - this._readableState = new ReadableState(options, this); + var isDuplex = this instanceof Duplex; + this._readableState = new ReadableState(options, this, isDuplex); // legacy - // legacy this.readable = true; if (options) { if (typeof options.read === 'function') this._read = options.read; - if (typeof options.destroy === 'function') this._destroy = options.destroy; } @@ -195,36 +185,40 @@ function Readable(options) { } Object.defineProperty(Readable.prototype, 'destroyed', { - get: function () { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { if (this._readableState === undefined) { return false; } + return this._readableState.destroyed; }, - set: function (value) { + set: function set(value) { // we ignore the value if the stream // has not been initialized yet if (!this._readableState) { return; - } - - // backward compatibility, the user is explicitly + } // backward compatibility, the user is explicitly // managing destroyed + + this._readableState.destroyed = value; } }); - Readable.prototype.destroy = destroyImpl.destroy; Readable.prototype._undestroy = destroyImpl.undestroy; + Readable.prototype._destroy = function (err, cb) { - this.push(null); cb(err); -}; - -// Manually shove something into the read() buffer. +}; // Manually shove something into the read() buffer. // This returns true if the highWaterMark has not been hit yet, // similar to how Writable.write() returns true if you should // write() some more. + + Readable.prototype.push = function (chunk, encoding) { var state = this._readableState; var skipChunkCheck; @@ -232,10 +226,12 @@ Readable.prototype.push = function (chunk, encoding) { if (!state.objectMode) { if (typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { chunk = Buffer.from(chunk, encoding); encoding = ''; } + skipChunkCheck = true; } } else { @@ -243,34 +239,40 @@ Readable.prototype.push = function (chunk, encoding) { } return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); -}; +}; // Unshift should *always* be something directly out of read() + -// Unshift should *always* be something directly out of read() Readable.prototype.unshift = function (chunk) { return readableAddChunk(this, chunk, null, true, false); }; function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { + debug('readableAddChunk', chunk); var state = stream._readableState; + if (chunk === null) { state.reading = false; onEofChunk(stream, state); } else { var er; if (!skipChunkCheck) er = chunkInvalid(state, chunk); + if (er) { - stream.emit('error', er); + errorOrDestroy(stream, er); } else if (state.objectMode || chunk && chunk.length > 0) { if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { chunk = _uint8ArrayToBuffer(chunk); } if (addToFront) { - if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); + if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true); } else if (state.ended) { - stream.emit('error', new Error('stream.push() after EOF')); + errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF()); + } else if (state.destroyed) { + return false; } else { state.reading = false; + if (state.decoder && !encoding) { chunk = state.decoder.write(chunk); if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); @@ -280,61 +282,73 @@ function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { } } else if (!addToFront) { state.reading = false; + maybeReadMore(stream, state); } - } + } // We can push more data if we are below the highWaterMark. + // Also, if we have no data yet, we can stand some more bytes. + // This is to work around cases where hwm=0, such as the repl. - return needMoreData(state); + + return !state.ended && (state.length < state.highWaterMark || state.length === 0); } function addChunk(stream, state, chunk, addToFront) { if (state.flowing && state.length === 0 && !state.sync) { + state.awaitDrain = 0; stream.emit('data', chunk); - stream.read(0); } else { // update the buffer info. state.length += state.objectMode ? 1 : chunk.length; if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - if (state.needReadable) emitReadable(stream); } + maybeReadMore(stream, state); } function chunkInvalid(state, chunk) { var er; + if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); + er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk); } - return er; -} -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); + return er; } Readable.prototype.isPaused = function () { return this._readableState.flowing === false; -}; +}; // backwards compatibility. + -// backwards compatibility. Readable.prototype.setEncoding = function (enc) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; + var decoder = new StringDecoder(enc); + this._readableState.decoder = decoder; // If setEncoding(null), decoder.encoding equals utf8 + + this._readableState.encoding = this._readableState.decoder.encoding; // Iterate over current buffer to convert already stored Buffers: + + var p = this._readableState.buffer.head; + var content = ''; + + while (p !== null) { + content += decoder.write(p.data); + p = p.next; + } + + this._readableState.buffer.clear(); + + if (content !== '') this._readableState.buffer.push(content); + this._readableState.length = content.length; return this; -}; +}; // Don't raise the hwm > 1GB + + +var MAX_HWM = 0x40000000; -// Don't raise the hwm > 8MB -var MAX_HWM = 0x800000; function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { + // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. n = MAX_HWM; } else { // Get the next highest power of 2 to prevent increasing hwm excessively in @@ -347,56 +361,55 @@ function computeNewHighWaterMark(n) { n |= n >>> 16; n++; } - return n; -} -// This function is designed to be inlinable, so please take care when making + return n; +} // This function is designed to be inlinable, so please take care when making // changes to the function body. + + function howMuchToRead(n, state) { if (n <= 0 || state.length === 0 && state.ended) return 0; if (state.objectMode) return 1; + if (n !== n) { // Only flow one buffer at a time if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } - // If we're asking for more than the current hwm, then raise the hwm. + } // If we're asking for more than the current hwm, then raise the hwm. + + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; - // Don't have enough + if (n <= state.length) return n; // Don't have enough + if (!state.ended) { state.needReadable = true; return 0; } + return state.length; -} +} // you can override either this method, or the async _read(n) below. + -// you can override either this method, or the async _read(n) below. Readable.prototype.read = function (n) { debug('read', n); n = parseInt(n, 10); var state = this._readableState; var nOrig = n; - - if (n !== 0) state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we + if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we // already have a bunch of data in the buffer, then just trigger // the 'readable' event and move on. - if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + + if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) { debug('read: emitReadable', state.length, state.ended); if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); return null; } - n = howMuchToRead(n, state); + n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up. - // if we've ended, and we're now clear, then finish it up. if (n === 0 && state.ended) { if (state.length === 0) endReadable(this); return null; - } - - // All the actual chunk generation logic needs to be + } // All the actual chunk generation logic needs to be // *below* the call to _read. The reason is that in certain // synthetic stream cases, such as passthrough streams, _read // may be a completely synchronous operation which may change @@ -417,33 +430,34 @@ Readable.prototype.read = function (n) { // 'readable' etc. // // 3. Actually pull the requested chunks out of the buffer and return. - // if we need a readable event, then we need to do some reading. + + var doRead = state.needReadable; - debug('need readable', doRead); + debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some - // if we currently have less than the highWaterMark, then also read some if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true; debug('length less than watermark', doRead); - } - - // however, if we've ended, then there's no point, and if we're already + } // however, if we've ended, then there's no point, and if we're already // reading, then it's unnecessary. + + if (state.ended || state.reading) { doRead = false; debug('reading or ended', doRead); } else if (doRead) { debug('do read'); state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - // call internal read method + state.sync = true; // if the length is currently zero, then we *need* a readable event. + + if (state.length === 0) state.needReadable = true; // call internal read method + this._read(state.highWaterMark); - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, + + state.sync = false; // If _read pushed data synchronously, then `reading` will be false, // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); } @@ -451,91 +465,144 @@ Readable.prototype.read = function (n) { if (n > 0) ret = fromList(n, state);else ret = null; if (ret === null) { - state.needReadable = true; + state.needReadable = state.length <= state.highWaterMark; n = 0; } else { state.length -= n; + state.awaitDrain = 0; } if (state.length === 0) { // If we have nothing in the buffer, then we want to know // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; + if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick. - // If we tried to read() past the EOF, then emit end on the next tick. if (nOrig !== n && state.ended) endReadable(this); } if (ret !== null) this.emit('data', ret); - return ret; }; function onEofChunk(stream, state) { + debug('onEofChunk'); if (state.ended) return; + if (state.decoder) { var chunk = state.decoder.end(); + if (chunk && chunk.length) { state.buffer.push(chunk); state.length += state.objectMode ? 1 : chunk.length; } } + state.ended = true; - // emit 'readable' now to make sure it gets picked up. - emitReadable(stream); -} + if (state.sync) { + // if we are sync, wait until next tick to emit the data. + // Otherwise we risk emitting data in the flow() + // the readable code triggers during a read() call + emitReadable(stream); + } else { + // emit 'readable' now to make sure it gets picked up. + state.needReadable = false; -// Don't emit readable right away in sync mode, because this can trigger + if (!state.emittedReadable) { + state.emittedReadable = true; + emitReadable_(stream); + } + } +} // Don't emit readable right away in sync mode, because this can trigger // another read() call => stack overflow. This way, it might trigger // a nextTick recursion warning, but that's not so bad. + + function emitReadable(stream) { var state = stream._readableState; + debug('emitReadable', state.needReadable, state.emittedReadable); state.needReadable = false; + if (!state.emittedReadable) { debug('emitReadable', state.flowing); state.emittedReadable = true; - if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream); + process.nextTick(emitReadable_, stream); } } function emitReadable_(stream) { - debug('emit readable'); - stream.emit('readable'); - flow(stream); -} + var state = stream._readableState; + debug('emitReadable_', state.destroyed, state.length, state.ended); -// at this point, the user has presumably seen the 'readable' event, + if (!state.destroyed && (state.length || state.ended)) { + stream.emit('readable'); + state.emittedReadable = false; + } // The stream needs another readable event if + // 1. It is not flowing, as the flow mechanism will take + // care of it. + // 2. It is not ended. + // 3. It is below the highWaterMark, so we can schedule + // another readable later. + + + state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark; + flow(stream); +} // at this point, the user has presumably seen the 'readable' event, // and called read() to consume some data. that may have triggered // in turn another _read(n) call, in which case reading = true if // it's in progress. // However, if we're not ended, or reading, and the length < hwm, // then go ahead and try to read some more preemptively. + + function maybeReadMore(stream, state) { if (!state.readingMore) { state.readingMore = true; - pna.nextTick(maybeReadMore_, stream, state); + process.nextTick(maybeReadMore_, stream, state); } } function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + // Attempt to read more data if we should. + // + // The conditions for reading more data are (one of): + // - Not enough data buffered (state.length < state.highWaterMark). The loop + // is responsible for filling the buffer with enough data if such data + // is available. If highWaterMark is 0 and we are not in the flowing mode + // we should _not_ attempt to buffer any extra data. We'll get more data + // when the stream consumer calls read() instead. + // - No data in the buffer, and the stream is in flowing mode. In this mode + // the loop below is responsible for ensuring read() is called. Failing to + // call read here would abort the flow and there's no other mechanism for + // continuing the flow if the stream consumer has just subscribed to the + // 'data' event. + // + // In addition to the above conditions to keep reading data, the following + // conditions prevent the data from being read: + // - The stream has ended (state.ended). + // - There is already a pending 'read' operation (state.reading). This is a + // case where the the stream has called the implementation defined _read() + // method, but they are processing the call asynchronously and have _not_ + // called push() with new data. In this case we skip performing more + // read()s. The execution ends in this method again after the _read() ends + // up calling push() with more data. + while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) { + var len = state.length; debug('maybeReadMore read 0'); stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break;else len = state.length; + if (len === state.length) // didn't get any data, stop spinning. + break; } - state.readingMore = false; -} -// abstract method. to be overridden in specific implementation classes. + state.readingMore = false; +} // abstract method. to be overridden in specific implementation classes. // call cb(er, data) where data is <= n in length. // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. + + Readable.prototype._read = function (n) { - this.emit('error', new Error('_read() is not implemented')); + errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()')); }; Readable.prototype.pipe = function (dest, pipeOpts) { @@ -546,24 +613,26 @@ Readable.prototype.pipe = function (dest, pipeOpts) { case 0: state.pipes = dest; break; + case 1: state.pipes = [state.pipes, dest]; break; + default: state.pipes.push(dest); break; } + state.pipesCount += 1; debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - var endFn = doEnd ? onend : unpipe; - if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn); - + if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); + function onunpipe(readable, unpipeInfo) { debug('onunpipe'); + if (readable === src) { if (unpipeInfo && unpipeInfo.hasUnpiped === false) { unpipeInfo.hasUnpiped = true; @@ -575,19 +644,19 @@ Readable.prototype.pipe = function (dest, pipeOpts) { function onend() { debug('onend'); dest.end(); - } - - // when the dest drains, it reduces the awaitDrain counter + } // when the dest drains, it reduces the awaitDrain counter // on the source. This would be more elegant with a .once() // handler in flow(), but adding and removing repeatedly is // too slow. + + var ondrain = pipeOnDrain(src); dest.on('drain', ondrain); - var cleanedUp = false; + function cleanup() { - debug('cleanup'); - // cleanup event handlers once the pipe is broken + debug('cleanup'); // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); dest.removeListener('finish', onfinish); dest.removeListener('drain', ondrain); @@ -596,75 +665,71 @@ Readable.prototype.pipe = function (dest, pipeOpts) { src.removeListener('end', onend); src.removeListener('end', unpipe); src.removeListener('data', ondata); - - cleanedUp = true; - - // if the reader is waiting for a drain event from this + cleanedUp = true; // if the reader is waiting for a drain event from this // specific writer, then it would cause it to never start // flowing again. // So, if this is awaiting a drain, then we just call it now. // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); } - // If the user pushes more data while we're writing to dest then we'll end up - // in ondata again. However, we only want to increase awaitDrain once because - // dest will only emit one 'drain' event for the multiple writes. - // => Introduce a guard on increasing awaitDrain. - var increasedAwaitDrain = false; src.on('data', ondata); + function ondata(chunk) { debug('ondata'); - increasedAwaitDrain = false; var ret = dest.write(chunk); - if (false === ret && !increasedAwaitDrain) { + debug('dest.write', ret); + + if (ret === false) { // If the user unpiped during `dest.write()`, it is possible // to get stuck in a permanently paused state if that write // also returned false. // => Check whether `dest` is still a piping destination. if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); - src._readableState.awaitDrain++; - increasedAwaitDrain = true; + debug('false write response, pause', state.awaitDrain); + state.awaitDrain++; } + src.pause(); } - } - - // if the dest has an error, then stop piping into it. + } // if the dest has an error, then stop piping into it. // however, don't suppress the throwing behavior for this. + + function onerror(er) { debug('onerror', er); unpipe(); dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); - } + if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er); + } // Make sure our error handler is attached before userland ones. - // Make sure our error handler is attached before userland ones. - prependListener(dest, 'error', onerror); - // Both close and finish should trigger unpipe, but only once. + prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once. + function onclose() { dest.removeListener('finish', onfinish); unpipe(); } + dest.once('close', onclose); + function onfinish() { debug('onfinish'); dest.removeListener('close', onclose); unpipe(); } + dest.once('finish', onfinish); function unpipe() { debug('unpipe'); src.unpipe(dest); - } + } // tell the dest that it's being piped to - // tell the dest that it's being piped to - dest.emit('pipe', src); - // start the flow if it hasn't been started already. + dest.emit('pipe', src); // start the flow if it hasn't been started already. + if (!state.flowing) { debug('pipe resume'); src.resume(); @@ -674,10 +739,11 @@ Readable.prototype.pipe = function (dest, pipeOpts) { }; function pipeOnDrain(src) { - return function () { + return function pipeOnDrainFunctionResult() { var state = src._readableState; debug('pipeOnDrain', state.awaitDrain); if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { state.flowing = true; flow(src); @@ -687,27 +753,24 @@ function pipeOnDrain(src) { Readable.prototype.unpipe = function (dest) { var state = this._readableState; - var unpipeInfo = { hasUnpiped: false }; + var unpipeInfo = { + hasUnpiped: false + }; // if we're not piping anywhere, then do nothing. - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) return this; + if (state.pipesCount === 0) return this; // just one destination. most common case. - // just one destination. most common case. if (state.pipesCount === 1) { // passed in one, but it's not the right one. if (dest && dest !== state.pipes) return this; + if (!dest) dest = state.pipes; // got a match. - if (!dest) dest = state.pipes; - - // got a match. state.pipes = null; state.pipesCount = 0; state.flowing = false; if (dest) dest.emit('unpipe', this, unpipeInfo); return this; - } + } // slow case. multiple pipe destinations. - // slow case. multiple pipe destinations. if (!dest) { // remove all. @@ -718,80 +781,139 @@ Readable.prototype.unpipe = function (dest) { state.flowing = false; for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this, unpipeInfo); - }return this; - } + dests[i].emit('unpipe', this, { + hasUnpiped: false + }); + } + + return this; + } // try to find the right one. + - // try to find the right one. var index = indexOf(state.pipes, dest); if (index === -1) return this; - state.pipes.splice(index, 1); state.pipesCount -= 1; if (state.pipesCount === 1) state.pipes = state.pipes[0]; - dest.emit('unpipe', this, unpipeInfo); - return this; -}; - -// set up data events if they are asked for +}; // set up data events if they are asked for // Ensure readable listeners eventually get something + + Readable.prototype.on = function (ev, fn) { var res = Stream.prototype.on.call(this, ev, fn); + var state = this._readableState; if (ev === 'data') { - // Start flowing on next tick if stream isn't explicitly paused - if (this._readableState.flowing !== false) this.resume(); + // update readableListening so that resume() may be a no-op + // a few lines down. This is needed to support once('readable'). + state.readableListening = this.listenerCount('readable') > 0; // Try start flowing on next tick if stream isn't explicitly paused + + if (state.flowing !== false) this.resume(); } else if (ev === 'readable') { - var state = this._readableState; if (!state.endEmitted && !state.readableListening) { state.readableListening = state.needReadable = true; + state.flowing = false; state.emittedReadable = false; - if (!state.reading) { - pna.nextTick(nReadingNextTick, this); - } else if (state.length) { + debug('on readable', state.length, state.reading); + + if (state.length) { emitReadable(this); + } else if (!state.reading) { + process.nextTick(nReadingNextTick, this); } } } return res; }; + Readable.prototype.addListener = Readable.prototype.on; +Readable.prototype.removeListener = function (ev, fn) { + var res = Stream.prototype.removeListener.call(this, ev, fn); + + if (ev === 'readable') { + // We need to check if there is someone still listening to + // readable and reset the state. However this needs to happen + // after readable has been emitted but before I/O (nextTick) to + // support once('readable', fn) cycles. This means that calling + // resume within the same tick will have no + // effect. + process.nextTick(updateReadableListening, this); + } + + return res; +}; + +Readable.prototype.removeAllListeners = function (ev) { + var res = Stream.prototype.removeAllListeners.apply(this, arguments); + + if (ev === 'readable' || ev === undefined) { + // We need to check if there is someone still listening to + // readable and reset the state. However this needs to happen + // after readable has been emitted but before I/O (nextTick) to + // support once('readable', fn) cycles. This means that calling + // resume within the same tick will have no + // effect. + process.nextTick(updateReadableListening, this); + } + + return res; +}; + +function updateReadableListening(self) { + var state = self._readableState; + state.readableListening = self.listenerCount('readable') > 0; + + if (state.resumeScheduled && !state.paused) { + // flowing needs to be set to true now, otherwise + // the upcoming resume will not flow. + state.flowing = true; // crude way to check if we should resume + } else if (self.listenerCount('data') > 0) { + self.resume(); + } +} + function nReadingNextTick(self) { debug('readable nexttick read 0'); self.read(0); -} - -// pause() and resume() are remnants of the legacy readable stream API +} // pause() and resume() are remnants of the legacy readable stream API // If the user uses them, then switch into old mode. + + Readable.prototype.resume = function () { var state = this._readableState; + if (!state.flowing) { - debug('resume'); - state.flowing = true; + debug('resume'); // we flow only if there is no one listening + // for readable, but we still have to call + // resume() + + state.flowing = !state.readableListening; resume(this, state); } + + state.paused = false; return this; }; function resume(stream, state) { if (!state.resumeScheduled) { state.resumeScheduled = true; - pna.nextTick(resume_, stream, state); + process.nextTick(resume_, stream, state); } } function resume_(stream, state) { + debug('resume', state.reading); + if (!state.reading) { - debug('resume read 0'); stream.read(0); } state.resumeScheduled = false; - state.awaitDrain = 0; stream.emit('resume'); flow(stream); if (state.flowing && !state.reading) stream.read(0); @@ -799,31 +921,37 @@ function resume_(stream, state) { Readable.prototype.pause = function () { debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { + + if (this._readableState.flowing !== false) { debug('pause'); this._readableState.flowing = false; this.emit('pause'); } + + this._readableState.paused = true; return this; }; function flow(stream) { var state = stream._readableState; debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) {} -} -// wrap an old-style stream as the async data source. + while (state.flowing && stream.read() !== null) { + ; + } +} // wrap an old-style stream as the async data source. // This is *not* part of the readable stream interface. // It is an ugly unfortunate mess of history. + + Readable.prototype.wrap = function (stream) { var _this = this; var state = this._readableState; var paused = false; - stream.on('end', function () { debug('wrapped end'); + if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) _this.push(chunk); @@ -831,42 +959,41 @@ Readable.prototype.wrap = function (stream) { _this.push(null); }); - stream.on('data', function (chunk) { debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); + if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode - // don't skip over falsy values in objectMode if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; var ret = _this.push(chunk); + if (!ret) { paused = true; stream.pause(); } - }); - - // proxy all the other methods. + }); // proxy all the other methods. // important when wrapping filters and duplexes. + for (var i in stream) { if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function (method) { - return function () { + this[i] = function methodWrap(method) { + return function methodWrapReturnFunction() { return stream[method].apply(stream, arguments); }; }(i); } - } + } // proxy certain important events. + - // proxy certain important events. for (var n = 0; n < kProxyEvents.length; n++) { stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); - } - - // when we try to consume some more bytes, simply unpause the + } // when we try to consume some more bytes, simply unpause the // underlying stream. + + this._read = function (n) { debug('wrapped _read', n); + if (paused) { paused = false; stream.resume(); @@ -876,144 +1003,122 @@ Readable.prototype.wrap = function (stream) { return this; }; +if (typeof Symbol === 'function') { + Readable.prototype[Symbol.asyncIterator] = function () { + if (createReadableStreamAsyncIterator === undefined) { + createReadableStreamAsyncIterator = require('./internal/streams/async_iterator'); + } + + return createReadableStreamAsyncIterator(this); + }; +} + Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { // making it explicit this property is not enumerable // because otherwise some prototype manipulation in // userland will fail enumerable: false, - get: function () { + get: function get() { return this._readableState.highWaterMark; } }); +Object.defineProperty(Readable.prototype, 'readableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState && this._readableState.buffer; + } +}); +Object.defineProperty(Readable.prototype, 'readableFlowing', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.flowing; + }, + set: function set(state) { + if (this._readableState) { + this._readableState.flowing = state; + } + } +}); // exposed for testing purposes only. -// exposed for testing purposes only. Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. +Object.defineProperty(Readable.prototype, 'readableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.length; + } +}); // Pluck off n bytes from an array of buffers. // Length is the combined lengths of all the buffers in the list. // This function is designed to be inlinable, so please take care when making // changes to the function body. + function fromList(n, state) { // nothing buffered if (state.length === 0) return null; - var ret; if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length); state.buffer.clear(); } else { // read part of list - ret = fromListPartial(n, state.buffer, state.decoder); + ret = state.buffer.consume(n, state.decoder); } - - return ret; -} - -// Extracts only enough buffered data to satisfy the amount requested. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromListPartial(n, list, hasStrings) { - var ret; - if (n < list.head.data.length) { - // slice is the same for buffers and strings - ret = list.head.data.slice(0, n); - list.head.data = list.head.data.slice(n); - } else if (n === list.head.data.length) { - // first chunk is a perfect match - ret = list.shift(); - } else { - // result spans more than one buffer - ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); - } - return ret; -} - -// Copies a specified amount of characters from the list of buffered data -// chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBufferString(n, list) { - var p = list.head; - var c = 1; - var ret = p.data; - n -= ret.length; - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = str.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -// Copies a specified amount of bytes from the list of buffered data chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBuffer(n, list) { - var ret = Buffer.allocUnsafe(n); - var p = list.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = buf.slice(nb); - } - break; - } - ++c; - } - list.length -= c; return ret; } function endReadable(stream) { var state = stream._readableState; - - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); + debug('endReadable', state.endEmitted); if (!state.endEmitted) { state.ended = true; - pna.nextTick(endReadableNT, state, stream); + process.nextTick(endReadableNT, state, stream); } } function endReadableNT(state, stream) { - // Check that we didn't get one last unshift. + debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { state.endEmitted = true; stream.readable = false; stream.emit('end'); + + if (state.autoDestroy) { + // In case of duplex streams we need a way to detect + // if the writable side is ready for autoDestroy as well + var wState = stream._writableState; + + if (!wState || wState.autoDestroy && wState.finished) { + stream.destroy(); + } + } } } +if (typeof Symbol === 'function') { + Readable.from = function (iterable, opts) { + if (from === undefined) { + from = require('./internal/streams/from'); + } + + return from(Readable, iterable, opts); + }; +} + function indexOf(xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } + return -1; } \ No newline at end of file diff --git a/node_modules/readable-stream/lib/_stream_transform.js b/node_modules/readable-stream/lib/_stream_transform.js index fcfc105af8e9a..41a738c4e9359 100644 --- a/node_modules/readable-stream/lib/_stream_transform.js +++ b/node_modules/readable-stream/lib/_stream_transform.js @@ -18,7 +18,6 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. - // a transform stream is a readable/writable stream where you do // something with the data. Sometimes it's called a "filter", // but that's not a great name for it, since that implies a thing where @@ -60,40 +59,37 @@ // However, even in such a pathological case, only a single written chunk // would be consumed, and then the rest would wait (un-transformed) until // the results of the previous transformed chunk were consumed. - 'use strict'; module.exports = Transform; -var Duplex = require('./_stream_duplex'); +var _require$codes = require('../errors').codes, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, + ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING, + ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0; -/**/ -var util = Object.create(require('core-util-is')); -util.inherits = require('inherits'); -/**/ +var Duplex = require('./_stream_duplex'); -util.inherits(Transform, Duplex); +require('inherits')(Transform, Duplex); function afterTransform(er, data) { var ts = this._transformState; ts.transforming = false; - var cb = ts.writecb; - if (!cb) { - return this.emit('error', new Error('write callback called multiple times')); + if (cb === null) { + return this.emit('error', new ERR_MULTIPLE_CALLBACK()); } ts.writechunk = null; ts.writecb = null; - if (data != null) // single equals check for both `null` and `undefined` this.push(data); - cb(er); - var rs = this._readableState; rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { this._read(rs.highWaterMark); } @@ -101,9 +97,7 @@ function afterTransform(er, data) { function Transform(options) { if (!(this instanceof Transform)) return new Transform(options); - Duplex.call(this, options); - this._transformState = { afterTransform: afterTransform.bind(this), needTransform: false, @@ -111,30 +105,27 @@ function Transform(options) { writecb: null, writechunk: null, writeencoding: null - }; - - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; + }; // start out asking for a readable event once data is transformed. - // we have implemented the _read method, and done the other things + this._readableState.needReadable = true; // we have implemented the _read method, and done the other things // that Readable wants before the first _read call, so unset the // sync guard flag. + this._readableState.sync = false; if (options) { if (typeof options.transform === 'function') this._transform = options.transform; - if (typeof options.flush === 'function') this._flush = options.flush; - } + } // When the writable side finishes, then flush out anything remaining. + - // When the writable side finishes, then flush out anything remaining. this.on('prefinish', prefinish); } function prefinish() { var _this = this; - if (typeof this._flush === 'function') { + if (typeof this._flush === 'function' && !this._readableState.destroyed) { this._flush(function (er, data) { done(_this, er, data); }); @@ -146,9 +137,7 @@ function prefinish() { Transform.prototype.push = function (chunk, encoding) { this._transformState.needTransform = false; return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! +}; // This is the part where you do stuff! // override this function in implementation classes. // 'chunk' is an input chunk. // @@ -158,8 +147,10 @@ Transform.prototype.push = function (chunk, encoding) { // Call `cb(err)` when you are done with this chunk. If you pass // an error, then that'll put the hurt on the whole operation. If you // never call cb(), then you'll never get another chunk. + + Transform.prototype._transform = function (chunk, encoding, cb) { - throw new Error('_transform() is not implemented'); + cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()')); }; Transform.prototype._write = function (chunk, encoding, cb) { @@ -167,20 +158,22 @@ Transform.prototype._write = function (chunk, encoding, cb) { ts.writecb = cb; ts.writechunk = chunk; ts.writeencoding = encoding; + if (!ts.transforming) { var rs = this._readableState; if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); } -}; - -// Doesn't matter what the args are here. +}; // Doesn't matter what the args are here. // _transform does all the work. // That we got here means that the readable side wants more data. + + Transform.prototype._read = function (n) { var ts = this._transformState; - if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + if (ts.writechunk !== null && !ts.transforming) { ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); } else { // mark that we need a transform, so that any data that comes in @@ -190,25 +183,19 @@ Transform.prototype._read = function (n) { }; Transform.prototype._destroy = function (err, cb) { - var _this2 = this; - Duplex.prototype._destroy.call(this, err, function (err2) { cb(err2); - _this2.emit('close'); }); }; function done(stream, er, data) { if (er) return stream.emit('error', er); - if (data != null) // single equals check for both `null` and `undefined` - stream.push(data); - + stream.push(data); // TODO(BridgeAR): Write a test for these two error cases // if there's nothing in the write buffer, then that means // that nothing more will ever be provided - if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0'); - - if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming'); + if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0(); + if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING(); return stream.push(null); } \ No newline at end of file diff --git a/node_modules/readable-stream/lib/_stream_writable.js b/node_modules/readable-stream/lib/_stream_writable.js index b0b02200cd723..a2634d7c24fd5 100644 --- a/node_modules/readable-stream/lib/_stream_writable.js +++ b/node_modules/readable-stream/lib/_stream_writable.js @@ -18,35 +18,29 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. - // A bit simpler than readable streams. // Implement an async ._write(chunk, encoding, cb), and it'll handle all // the drain event emission and buffering. - 'use strict'; -/**/ - -var pna = require('process-nextick-args'); -/**/ - module.exports = Writable; - /* */ + function WriteReq(chunk, encoding, cb) { this.chunk = chunk; this.encoding = encoding; this.callback = cb; this.next = null; -} - -// It seems a linked list but it is not +} // It seems a linked list but it is not // there will be only 2 of these for each stream + + function CorkedRequest(state) { var _this = this; this.next = null; this.entry = null; + this.finish = function () { onCorkedFinish(_this, state); }; @@ -54,266 +48,247 @@ function CorkedRequest(state) { /* */ /**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick; -/**/ -/**/ + var Duplex; /**/ Writable.WritableState = WritableState; - /**/ -var util = Object.create(require('core-util-is')); -util.inherits = require('inherits'); -/**/ -/**/ var internalUtil = { deprecate: require('util-deprecate') }; /**/ /**/ + var Stream = require('./internal/streams/stream'); /**/ -/**/ -var Buffer = require('safe-buffer').Buffer; +var Buffer = require('buffer').Buffer; + var OurUint8Array = global.Uint8Array || function () {}; + function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } + function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } -/**/ - var destroyImpl = require('./internal/streams/destroy'); -util.inherits(Writable, Stream); +var _require = require('./internal/streams/state'), + getHighWaterMark = _require.getHighWaterMark; -function nop() {} +var _require$codes = require('../errors').codes, + ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, + ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE, + ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED, + ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES, + ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END, + ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING; -function WritableState(options, stream) { - Duplex = Duplex || require('./_stream_duplex'); +var errorOrDestroy = destroyImpl.errorOrDestroy; - options = options || {}; +require('inherits')(Writable, Stream); - // Duplex streams are both readable and writable, but share +function nop() {} + +function WritableState(options, stream, isDuplex) { + Duplex = Duplex || require('./_stream_duplex'); + options = options || {}; // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - var isDuplex = stream instanceof Duplex; + // values for the readable and the writable sides of the duplex stream, + // e.g. options.readableObjectMode vs. options.writableObjectMode, etc. - // object stream flag to indicate whether or not this stream + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag to indicate whether or not this stream // contains buffers or objects. - this.objectMode = !!options.objectMode; - - if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; - // the point at which write() starts returning false + this.objectMode = !!options.objectMode; + if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - var writableHwm = options.writableHighWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm; + this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex); // if _final has been called + + this.finalCalled = false; // drain event flag. - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); + this.needDrain = false; // at the start of calling end() - // if _final has been called - this.finalCalled = false; + this.ending = false; // when end() has been called, and returned - // drain event flag. - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned - this.ended = false; - // when 'finish' is emitted - this.finished = false; + this.ended = false; // when 'finish' is emitted - // has it been destroyed - this.destroyed = false; + this.finished = false; // has it been destroyed - // should we decode strings into buffers before passing to _write? + this.destroyed = false; // should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; - // Crypto is kind of old and crusty. Historically, its default string + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - // not an actual buffer we keep track of, but a measurement + this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement // of how much we're waiting to get pushed to some underlying // socket or file. - this.length = 0; - // a flag to see when we're in the middle of a write. - this.writing = false; + this.length = 0; // a flag to see when we're in the middle of a write. - // when true all writes will be buffered until .uncork() call - this.corked = 0; + this.writing = false; // when true all writes will be buffered until .uncork() call - // a flag to be able to tell if the onwrite cb is called immediately, + this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. - this.sync = true; - // a flag to know if we're processing previously buffered items, which + this.sync = true; // a flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - // the callback that's passed to _write(chunk,cb) + this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { onwrite(stream, er); - }; + }; // the callback that the user supplies to write(chunk,encoding,cb) - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; - // the amount that is being written when _write is called. - this.writelen = 0; + this.writecb = null; // the amount that is being written when _write is called. + this.writelen = 0; this.bufferedRequest = null; - this.lastBufferedRequest = null; - - // number of pending user-supplied write callbacks + this.lastBufferedRequest = null; // number of pending user-supplied write callbacks // this must be 0 before 'finish' can be emitted - this.pendingcb = 0; - // emit prefinish if the only thing we're waiting for is _write cbs + this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams - this.prefinished = false; - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; + this.prefinished = false; // True if the error was already emitted and should not be thrown again - // count buffered requests - this.bufferedRequestCount = 0; + this.errorEmitted = false; // Should close be emitted on destroy. Defaults to true. - // allocate the first CorkedRequest, there is always + this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'finish' (and potentially 'end') + + this.autoDestroy = !!options.autoDestroy; // count buffered requests + + this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = new CorkedRequest(this); } WritableState.prototype.getBuffer = function getBuffer() { var current = this.bufferedRequest; var out = []; + while (current) { out.push(current); current = current.next; } + return out; }; (function () { try { Object.defineProperty(WritableState.prototype, 'buffer', { - get: internalUtil.deprecate(function () { + get: internalUtil.deprecate(function writableStateBufferGetter() { return this.getBuffer(); }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') }); } catch (_) {} -})(); - -// Test _writableState for inheritance to account for Duplex streams, +})(); // Test _writableState for inheritance to account for Duplex streams, // whose prototype chain only points to Readable. + + var realHasInstance; + if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { realHasInstance = Function.prototype[Symbol.hasInstance]; Object.defineProperty(Writable, Symbol.hasInstance, { - value: function (object) { + value: function value(object) { if (realHasInstance.call(this, object)) return true; if (this !== Writable) return false; - return object && object._writableState instanceof WritableState; } }); } else { - realHasInstance = function (object) { + realHasInstance = function realHasInstance(object) { return object instanceof this; }; } function Writable(options) { - Duplex = Duplex || require('./_stream_duplex'); - - // Writable ctor is applied to Duplexes, too. + Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` // would return false, as no `_writableState` property is attached. - // Trying to use the custom `instanceof` for Writable here will also break the // Node.js LazyTransform implementation, which has a non-trivial getter for // `_writableState` that would lead to infinite recursion. - if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { - return new Writable(options); - } + // Checking for a Stream.Duplex instance is faster here instead of inside + // the WritableState constructor, at least with V8 6.5 - this._writableState = new WritableState(options, this); + var isDuplex = this instanceof Duplex; + if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options); + this._writableState = new WritableState(options, this, isDuplex); // legacy. - // legacy. this.writable = true; if (options) { if (typeof options.write === 'function') this._write = options.write; - if (typeof options.writev === 'function') this._writev = options.writev; - if (typeof options.destroy === 'function') this._destroy = options.destroy; - if (typeof options.final === 'function') this._final = options.final; } Stream.call(this); -} +} // Otherwise people can pipe Writable streams, which is just wrong. + -// Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function () { - this.emit('error', new Error('Cannot pipe, not readable')); + errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()); }; function writeAfterEnd(stream, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - pna.nextTick(cb, er); -} + var er = new ERR_STREAM_WRITE_AFTER_END(); // TODO: defer error events consistently everywhere, not just the cb -// Checks that a user-supplied chunk is valid, especially for the particular + errorOrDestroy(stream, er); + process.nextTick(cb, er); +} // Checks that a user-supplied chunk is valid, especially for the particular // mode the stream is in. Currently this means that `null` is never accepted // and undefined/non-string values are only allowed in object mode. + + function validChunk(stream, state, chunk, cb) { - var valid = true; - var er = false; + var er; if (chunk === null) { - er = new TypeError('May not write null values to stream'); - } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); + er = new ERR_STREAM_NULL_VALUES(); + } else if (typeof chunk !== 'string' && !state.objectMode) { + er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk); } + if (er) { - stream.emit('error', er); - pna.nextTick(cb, er); - valid = false; + errorOrDestroy(stream, er); + process.nextTick(cb, er); + return false; } - return valid; + + return true; } Writable.prototype.write = function (chunk, encoding, cb) { var state = this._writableState; var ret = false; + var isBuf = !state.objectMode && _isUint8Array(chunk); if (isBuf && !Buffer.isBuffer(chunk)) { @@ -326,21 +301,16 @@ Writable.prototype.write = function (chunk, encoding, cb) { } if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; - if (typeof cb !== 'function') cb = nop; - - if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { + if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { state.pendingcb++; ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); } - return ret; }; Writable.prototype.cork = function () { - var state = this._writableState; - - state.corked++; + this._writableState.corked++; }; Writable.prototype.uncork = function () { @@ -348,23 +318,33 @@ Writable.prototype.uncork = function () { if (state.corked) { state.corked--; - - if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); } }; Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { // node::ParseEncoding() requires lower case. if (typeof encoding === 'string') encoding = encoding.toLowerCase(); - if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding); this._writableState.defaultEncoding = encoding; return this; }; +Object.defineProperty(Writable.prototype, 'writableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } +}); + function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { chunk = Buffer.from(chunk, encoding); } + return chunk; } @@ -373,29 +353,28 @@ Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { // because otherwise some prototype manipulation in // userland will fail enumerable: false, - get: function () { + get: function get() { return this._writableState.highWaterMark; } -}); - -// if we're already writing something, then just put this +}); // if we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. + function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { if (!isBuf) { var newChunk = decodeChunk(state, chunk, encoding); + if (chunk !== newChunk) { isBuf = true; encoding = 'buffer'; chunk = newChunk; } } - var len = state.objectMode ? 1 : chunk.length; + var len = state.objectMode ? 1 : chunk.length; state.length += len; + var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false. - var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. if (!ret) state.needDrain = true; if (state.writing || state.corked) { @@ -407,11 +386,13 @@ function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { callback: cb, next: null }; + if (last) { last.next = state.lastBufferedRequest; } else { state.bufferedRequest = state.lastBufferedRequest; } + state.bufferedRequestCount += 1; } else { doWrite(stream, state, false, len, chunk, encoding, cb); @@ -425,7 +406,7 @@ function doWrite(stream, state, writev, len, chunk, encoding, cb) { state.writecb = cb; state.writing = true; state.sync = true; - if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); state.sync = false; } @@ -435,20 +416,20 @@ function onwriteError(stream, state, sync, er, cb) { if (sync) { // defer the callback if we are being called synchronously // to avoid piling up things on the stack - pna.nextTick(cb, er); - // this can emit finish, and it will always happen + process.nextTick(cb, er); // this can emit finish, and it will always happen // after error - pna.nextTick(finishMaybe, stream, state); + + process.nextTick(finishMaybe, stream, state); stream._writableState.errorEmitted = true; - stream.emit('error', er); + errorOrDestroy(stream, er); } else { // the caller expect this to happen before if // it is async cb(er); stream._writableState.errorEmitted = true; - stream.emit('error', er); - // this can emit finish, but finish must + errorOrDestroy(stream, er); // this can emit finish, but finish must // always follow error + finishMaybe(stream, state); } } @@ -464,21 +445,18 @@ function onwrite(stream, er) { var state = stream._writableState; var sync = state.sync; var cb = state.writecb; - + if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK(); onwriteStateUpdate(state); - if (er) onwriteError(stream, state, sync, er, cb);else { // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(state); + var finished = needFinish(state) || stream.destroyed; if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { clearBuffer(stream, state); } if (sync) { - /**/ - asyncWrite(afterWrite, stream, state, finished, cb); - /**/ + process.nextTick(afterWrite, stream, state, finished, cb); } else { afterWrite(stream, state, finished, cb); } @@ -490,19 +468,19 @@ function afterWrite(stream, state, finished, cb) { state.pendingcb--; cb(); finishMaybe(stream, state); -} - -// Must force callback to be called on nextTick, so that we don't +} // Must force callback to be called on nextTick, so that we don't // emit 'drain' before the write() consumer gets the 'false' return // value, and has a chance to attach a 'drain' listener. + + function onwriteDrain(stream, state) { if (state.length === 0 && state.needDrain) { state.needDrain = false; stream.emit('drain'); } -} +} // if there's something in the buffer waiting, then process it + -// if there's something in the buffer waiting, then process it function clearBuffer(stream, state) { state.bufferProcessing = true; var entry = state.bufferedRequest; @@ -513,29 +491,30 @@ function clearBuffer(stream, state) { var buffer = new Array(l); var holder = state.corkedRequestsFree; holder.entry = entry; - var count = 0; var allBuffers = true; + while (entry) { buffer[count] = entry; if (!entry.isBuf) allBuffers = false; entry = entry.next; count += 1; } - buffer.allBuffers = allBuffers; - doWrite(stream, state, true, state.length, buffer, '', holder.finish); - - // doWrite is almost always async, defer these to save a bit of time + buffer.allBuffers = allBuffers; + doWrite(stream, state, true, state.length, buffer, '', holder.finish); // doWrite is almost always async, defer these to save a bit of time // as the hot path ends with doWrite + state.pendingcb++; state.lastBufferedRequest = null; + if (holder.next) { state.corkedRequestsFree = holder.next; holder.next = null; } else { state.corkedRequestsFree = new CorkedRequest(state); } + state.bufferedRequestCount = 0; } else { // Slow case, write chunks one-by-one @@ -544,14 +523,13 @@ function clearBuffer(stream, state) { var encoding = entry.encoding; var cb = entry.callback; var len = state.objectMode ? 1 : chunk.length; - doWrite(stream, state, false, len, chunk, encoding, cb); entry = entry.next; - state.bufferedRequestCount--; - // if we didn't call the onwrite immediately, then + state.bufferedRequestCount--; // if we didn't call the onwrite immediately, then // it means that we need to wait until it does. // also, that means that the chunk and cb are currently // being processed, so move the buffer counter past them. + if (state.writing) { break; } @@ -565,7 +543,7 @@ function clearBuffer(stream, state) { } Writable.prototype._write = function (chunk, encoding, cb) { - cb(new Error('_write() is not implemented')); + cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()')); }; Writable.prototype._writev = null; @@ -582,38 +560,52 @@ Writable.prototype.end = function (chunk, encoding, cb) { encoding = null; } - if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks - // .end() fully uncorks if (state.corked) { state.corked = 1; this.uncork(); - } + } // ignore unnecessary end() calls. + - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) endWritable(this, state, cb); + if (!state.ending) endWritable(this, state, cb); + return this; }; +Object.defineProperty(Writable.prototype, 'writableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.length; + } +}); + function needFinish(state) { return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; } + function callFinal(stream, state) { stream._final(function (err) { state.pendingcb--; + if (err) { - stream.emit('error', err); + errorOrDestroy(stream, err); } + state.prefinished = true; stream.emit('prefinish'); finishMaybe(stream, state); }); } + function prefinish(stream, state) { if (!state.prefinished && !state.finalCalled) { - if (typeof stream._final === 'function') { + if (typeof stream._final === 'function' && !state.destroyed) { state.pendingcb++; state.finalCalled = true; - pna.nextTick(callFinal, stream, state); + process.nextTick(callFinal, stream, state); } else { state.prefinished = true; stream.emit('prefinish'); @@ -623,22 +615,37 @@ function prefinish(stream, state) { function finishMaybe(stream, state) { var need = needFinish(state); + if (need) { prefinish(stream, state); + if (state.pendingcb === 0) { state.finished = true; stream.emit('finish'); + + if (state.autoDestroy) { + // In case of duplex streams we need a way to detect + // if the readable side is ready for autoDestroy as well + var rState = stream._readableState; + + if (!rState || rState.autoDestroy && rState.endEmitted) { + stream.destroy(); + } + } } } + return need; } function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); + if (cb) { - if (state.finished) pna.nextTick(cb);else stream.once('finish', cb); + if (state.finished) process.nextTick(cb);else stream.once('finish', cb); } + state.ended = true; stream.writable = false; } @@ -646,42 +653,45 @@ function endWritable(stream, state, cb) { function onCorkedFinish(corkReq, state, err) { var entry = corkReq.entry; corkReq.entry = null; + while (entry) { var cb = entry.callback; state.pendingcb--; cb(err); entry = entry.next; - } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = corkReq; - } else { - state.corkedRequestsFree = corkReq; - } + } // reuse the free corkReq. + + + state.corkedRequestsFree.next = corkReq; } Object.defineProperty(Writable.prototype, 'destroyed', { - get: function () { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { if (this._writableState === undefined) { return false; } + return this._writableState.destroyed; }, - set: function (value) { + set: function set(value) { // we ignore the value if the stream // has not been initialized yet if (!this._writableState) { return; - } - - // backward compatibility, the user is explicitly + } // backward compatibility, the user is explicitly // managing destroyed + + this._writableState.destroyed = value; } }); - Writable.prototype.destroy = destroyImpl.destroy; Writable.prototype._undestroy = destroyImpl.undestroy; + Writable.prototype._destroy = function (err, cb) { - this.end(); cb(err); }; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/BufferList.js b/node_modules/readable-stream/lib/internal/streams/BufferList.js deleted file mode 100644 index aefc68bd90b9c..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/BufferList.js +++ /dev/null @@ -1,79 +0,0 @@ -'use strict'; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Buffer = require('safe-buffer').Buffer; -var util = require('util'); - -function copyBuffer(src, target, offset) { - src.copy(target, offset); -} - -module.exports = function () { - function BufferList() { - _classCallCheck(this, BufferList); - - this.head = null; - this.tail = null; - this.length = 0; - } - - BufferList.prototype.push = function push(v) { - var entry = { data: v, next: null }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; - }; - - BufferList.prototype.unshift = function unshift(v) { - var entry = { data: v, next: this.head }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; - }; - - BufferList.prototype.shift = function shift() { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; - }; - - BufferList.prototype.clear = function clear() { - this.head = this.tail = null; - this.length = 0; - }; - - BufferList.prototype.join = function join(s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - while (p = p.next) { - ret += s + p.data; - }return ret; - }; - - BufferList.prototype.concat = function concat(n) { - if (this.length === 0) return Buffer.alloc(0); - if (this.length === 1) return this.head.data; - var ret = Buffer.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - while (p) { - copyBuffer(p.data, ret, i); - i += p.data.length; - p = p.next; - } - return ret; - }; - - return BufferList; -}(); - -if (util && util.inspect && util.inspect.custom) { - module.exports.prototype[util.inspect.custom] = function () { - var obj = util.inspect({ length: this.length }); - return this.constructor.name + ' ' + obj; - }; -} \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/async_iterator.js b/node_modules/readable-stream/lib/internal/streams/async_iterator.js new file mode 100644 index 0000000000000..9fb615a2f3bc4 --- /dev/null +++ b/node_modules/readable-stream/lib/internal/streams/async_iterator.js @@ -0,0 +1,207 @@ +'use strict'; + +var _Object$setPrototypeO; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var finished = require('./end-of-stream'); + +var kLastResolve = Symbol('lastResolve'); +var kLastReject = Symbol('lastReject'); +var kError = Symbol('error'); +var kEnded = Symbol('ended'); +var kLastPromise = Symbol('lastPromise'); +var kHandlePromise = Symbol('handlePromise'); +var kStream = Symbol('stream'); + +function createIterResult(value, done) { + return { + value: value, + done: done + }; +} + +function readAndResolve(iter) { + var resolve = iter[kLastResolve]; + + if (resolve !== null) { + var data = iter[kStream].read(); // we defer if data is null + // we can be expecting either 'end' or + // 'error' + + if (data !== null) { + iter[kLastPromise] = null; + iter[kLastResolve] = null; + iter[kLastReject] = null; + resolve(createIterResult(data, false)); + } + } +} + +function onReadable(iter) { + // we wait for the next tick, because it might + // emit an error with process.nextTick + process.nextTick(readAndResolve, iter); +} + +function wrapForNext(lastPromise, iter) { + return function (resolve, reject) { + lastPromise.then(function () { + if (iter[kEnded]) { + resolve(createIterResult(undefined, true)); + return; + } + + iter[kHandlePromise](resolve, reject); + }, reject); + }; +} + +var AsyncIteratorPrototype = Object.getPrototypeOf(function () {}); +var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = { + get stream() { + return this[kStream]; + }, + + next: function next() { + var _this = this; + + // if we have detected an error in the meanwhile + // reject straight away + var error = this[kError]; + + if (error !== null) { + return Promise.reject(error); + } + + if (this[kEnded]) { + return Promise.resolve(createIterResult(undefined, true)); + } + + if (this[kStream].destroyed) { + // We need to defer via nextTick because if .destroy(err) is + // called, the error will be emitted via nextTick, and + // we cannot guarantee that there is no error lingering around + // waiting to be emitted. + return new Promise(function (resolve, reject) { + process.nextTick(function () { + if (_this[kError]) { + reject(_this[kError]); + } else { + resolve(createIterResult(undefined, true)); + } + }); + }); + } // if we have multiple next() calls + // we will wait for the previous Promise to finish + // this logic is optimized to support for await loops, + // where next() is only called once at a time + + + var lastPromise = this[kLastPromise]; + var promise; + + if (lastPromise) { + promise = new Promise(wrapForNext(lastPromise, this)); + } else { + // fast path needed to support multiple this.push() + // without triggering the next() queue + var data = this[kStream].read(); + + if (data !== null) { + return Promise.resolve(createIterResult(data, false)); + } + + promise = new Promise(this[kHandlePromise]); + } + + this[kLastPromise] = promise; + return promise; + } +}, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () { + return this; +}), _defineProperty(_Object$setPrototypeO, "return", function _return() { + var _this2 = this; + + // destroy(err, cb) is a private API + // we can guarantee we have that here, because we control the + // Readable class this is attached to + return new Promise(function (resolve, reject) { + _this2[kStream].destroy(null, function (err) { + if (err) { + reject(err); + return; + } + + resolve(createIterResult(undefined, true)); + }); + }); +}), _Object$setPrototypeO), AsyncIteratorPrototype); + +var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) { + var _Object$create; + + var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, { + value: stream, + writable: true + }), _defineProperty(_Object$create, kLastResolve, { + value: null, + writable: true + }), _defineProperty(_Object$create, kLastReject, { + value: null, + writable: true + }), _defineProperty(_Object$create, kError, { + value: null, + writable: true + }), _defineProperty(_Object$create, kEnded, { + value: stream._readableState.endEmitted, + writable: true + }), _defineProperty(_Object$create, kHandlePromise, { + value: function value(resolve, reject) { + var data = iterator[kStream].read(); + + if (data) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + resolve(createIterResult(data, false)); + } else { + iterator[kLastResolve] = resolve; + iterator[kLastReject] = reject; + } + }, + writable: true + }), _Object$create)); + iterator[kLastPromise] = null; + finished(stream, function (err) { + if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') { + var reject = iterator[kLastReject]; // reject if we are waiting for data in the Promise + // returned by next() and store the error + + if (reject !== null) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + reject(err); + } + + iterator[kError] = err; + return; + } + + var resolve = iterator[kLastResolve]; + + if (resolve !== null) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + resolve(createIterResult(undefined, true)); + } + + iterator[kEnded] = true; + }); + stream.on('readable', onReadable.bind(null, iterator)); + return iterator; +}; + +module.exports = createReadableStreamAsyncIterator; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/buffer_list.js b/node_modules/readable-stream/lib/internal/streams/buffer_list.js new file mode 100644 index 0000000000000..cdea425f19dd9 --- /dev/null +++ b/node_modules/readable-stream/lib/internal/streams/buffer_list.js @@ -0,0 +1,210 @@ +'use strict'; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +var _require = require('buffer'), + Buffer = _require.Buffer; + +var _require2 = require('util'), + inspect = _require2.inspect; + +var custom = inspect && inspect.custom || 'inspect'; + +function copyBuffer(src, target, offset) { + Buffer.prototype.copy.call(src, target, offset); +} + +module.exports = +/*#__PURE__*/ +function () { + function BufferList() { + _classCallCheck(this, BufferList); + + this.head = null; + this.tail = null; + this.length = 0; + } + + _createClass(BufferList, [{ + key: "push", + value: function push(v) { + var entry = { + data: v, + next: null + }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; + } + }, { + key: "unshift", + value: function unshift(v) { + var entry = { + data: v, + next: this.head + }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; + } + }, { + key: "shift", + value: function shift() { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; + } + }, { + key: "clear", + value: function clear() { + this.head = this.tail = null; + this.length = 0; + } + }, { + key: "join", + value: function join(s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + + while (p = p.next) { + ret += s + p.data; + } + + return ret; + } + }, { + key: "concat", + value: function concat(n) { + if (this.length === 0) return Buffer.alloc(0); + var ret = Buffer.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + + while (p) { + copyBuffer(p.data, ret, i); + i += p.data.length; + p = p.next; + } + + return ret; + } // Consumes a specified amount of bytes or characters from the buffered data. + + }, { + key: "consume", + value: function consume(n, hasStrings) { + var ret; + + if (n < this.head.data.length) { + // `slice` is the same for buffers and strings. + ret = this.head.data.slice(0, n); + this.head.data = this.head.data.slice(n); + } else if (n === this.head.data.length) { + // First chunk is a perfect match. + ret = this.shift(); + } else { + // Result spans more than one buffer. + ret = hasStrings ? this._getString(n) : this._getBuffer(n); + } + + return ret; + } + }, { + key: "first", + value: function first() { + return this.head.data; + } // Consumes a specified amount of characters from the buffered data. + + }, { + key: "_getString", + value: function _getString(n) { + var p = this.head; + var c = 1; + var ret = p.data; + n -= ret.length; + + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) this.head = p.next;else this.head = this.tail = null; + } else { + this.head = p; + p.data = str.slice(nb); + } + + break; + } + + ++c; + } + + this.length -= c; + return ret; + } // Consumes a specified amount of bytes from the buffered data. + + }, { + key: "_getBuffer", + value: function _getBuffer(n) { + var ret = Buffer.allocUnsafe(n); + var p = this.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) this.head = p.next;else this.head = this.tail = null; + } else { + this.head = p; + p.data = buf.slice(nb); + } + + break; + } + + ++c; + } + + this.length -= c; + return ret; + } // Make sure the linked list only shows the minimal necessary information. + + }, { + key: custom, + value: function value(_, options) { + return inspect(this, _objectSpread({}, options, { + // Only inspect one level. + depth: 0, + // It should not recurse. + customInspect: false + })); + } + }]); + + return BufferList; +}(); \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/destroy.js b/node_modules/readable-stream/lib/internal/streams/destroy.js index 5a0a0d88cec6f..3268a16f3b6f2 100644 --- a/node_modules/readable-stream/lib/internal/streams/destroy.js +++ b/node_modules/readable-stream/lib/internal/streams/destroy.js @@ -1,11 +1,5 @@ -'use strict'; +'use strict'; // undocumented cb() API, needed for core, not for public API -/**/ - -var pna = require('process-nextick-args'); -/**/ - -// undocumented cb() API, needed for core, not for public API function destroy(err, cb) { var _this = this; @@ -15,38 +9,61 @@ function destroy(err, cb) { if (readableDestroyed || writableDestroyed) { if (cb) { cb(err); - } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { - pna.nextTick(emitErrorNT, this, err); + } else if (err) { + if (!this._writableState) { + process.nextTick(emitErrorNT, this, err); + } else if (!this._writableState.errorEmitted) { + this._writableState.errorEmitted = true; + process.nextTick(emitErrorNT, this, err); + } } - return this; - } - // we set destroyed to true before firing error callbacks in order + return this; + } // we set destroyed to true before firing error callbacks in order // to make it re-entrance safe in case destroy() is called within callbacks + if (this._readableState) { this._readableState.destroyed = true; - } + } // if this is a duplex stream mark the writable part as destroyed as well + - // if this is a duplex stream mark the writable part as destroyed as well if (this._writableState) { this._writableState.destroyed = true; } this._destroy(err || null, function (err) { if (!cb && err) { - pna.nextTick(emitErrorNT, _this, err); - if (_this._writableState) { + if (!_this._writableState) { + process.nextTick(emitErrorAndCloseNT, _this, err); + } else if (!_this._writableState.errorEmitted) { _this._writableState.errorEmitted = true; + process.nextTick(emitErrorAndCloseNT, _this, err); + } else { + process.nextTick(emitCloseNT, _this); } } else if (cb) { + process.nextTick(emitCloseNT, _this); cb(err); + } else { + process.nextTick(emitCloseNT, _this); } }); return this; } +function emitErrorAndCloseNT(self, err) { + emitErrorNT(self, err); + emitCloseNT(self); +} + +function emitCloseNT(self) { + if (self._writableState && !self._writableState.emitClose) return; + if (self._readableState && !self._readableState.emitClose) return; + self.emit('close'); +} + function undestroy() { if (this._readableState) { this._readableState.destroyed = false; @@ -59,6 +76,8 @@ function undestroy() { this._writableState.destroyed = false; this._writableState.ended = false; this._writableState.ending = false; + this._writableState.finalCalled = false; + this._writableState.prefinished = false; this._writableState.finished = false; this._writableState.errorEmitted = false; } @@ -68,7 +87,19 @@ function emitErrorNT(self, err) { self.emit('error', err); } +function errorOrDestroy(stream, err) { + // We have tests that rely on errors being emitted + // in the same tick, so changing this is semver major. + // For now when you opt-in to autoDestroy we allow + // the error to be emitted nextTick. In a future + // semver major update we should change the default to this. + var rState = stream._readableState; + var wState = stream._writableState; + if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err); +} + module.exports = { destroy: destroy, - undestroy: undestroy + undestroy: undestroy, + errorOrDestroy: errorOrDestroy }; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/end-of-stream.js b/node_modules/readable-stream/lib/internal/streams/end-of-stream.js new file mode 100644 index 0000000000000..831f286d98fa9 --- /dev/null +++ b/node_modules/readable-stream/lib/internal/streams/end-of-stream.js @@ -0,0 +1,104 @@ +// Ported from https://github.com/mafintosh/end-of-stream with +// permission from the author, Mathias Buus (@mafintosh). +'use strict'; + +var ERR_STREAM_PREMATURE_CLOSE = require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE; + +function once(callback) { + var called = false; + return function () { + if (called) return; + called = true; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + callback.apply(this, args); + }; +} + +function noop() {} + +function isRequest(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +} + +function eos(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + callback = once(callback || noop); + var readable = opts.readable || opts.readable !== false && stream.readable; + var writable = opts.writable || opts.writable !== false && stream.writable; + + var onlegacyfinish = function onlegacyfinish() { + if (!stream.writable) onfinish(); + }; + + var writableEnded = stream._writableState && stream._writableState.finished; + + var onfinish = function onfinish() { + writable = false; + writableEnded = true; + if (!readable) callback.call(stream); + }; + + var readableEnded = stream._readableState && stream._readableState.endEmitted; + + var onend = function onend() { + readable = false; + readableEnded = true; + if (!writable) callback.call(stream); + }; + + var onerror = function onerror(err) { + callback.call(stream, err); + }; + + var onclose = function onclose() { + var err; + + if (readable && !readableEnded) { + if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); + } + + if (writable && !writableEnded) { + if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); + } + }; + + var onrequest = function onrequest() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest();else stream.on('request', onrequest); + } else if (writable && !stream._writableState) { + // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); + return function () { + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; +} + +module.exports = eos; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/from-browser.js b/node_modules/readable-stream/lib/internal/streams/from-browser.js new file mode 100644 index 0000000000000..a4ce56f3c90f6 --- /dev/null +++ b/node_modules/readable-stream/lib/internal/streams/from-browser.js @@ -0,0 +1,3 @@ +module.exports = function () { + throw new Error('Readable.from is not available in the browser') +}; diff --git a/node_modules/readable-stream/lib/internal/streams/from.js b/node_modules/readable-stream/lib/internal/streams/from.js new file mode 100644 index 0000000000000..6c41284416799 --- /dev/null +++ b/node_modules/readable-stream/lib/internal/streams/from.js @@ -0,0 +1,64 @@ +'use strict'; + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var ERR_INVALID_ARG_TYPE = require('../../../errors').codes.ERR_INVALID_ARG_TYPE; + +function from(Readable, iterable, opts) { + var iterator; + + if (iterable && typeof iterable.next === 'function') { + iterator = iterable; + } else if (iterable && iterable[Symbol.asyncIterator]) iterator = iterable[Symbol.asyncIterator]();else if (iterable && iterable[Symbol.iterator]) iterator = iterable[Symbol.iterator]();else throw new ERR_INVALID_ARG_TYPE('iterable', ['Iterable'], iterable); + + var readable = new Readable(_objectSpread({ + objectMode: true + }, opts)); // Reading boolean to protect against _read + // being called before last iteration completion. + + var reading = false; + + readable._read = function () { + if (!reading) { + reading = true; + next(); + } + }; + + function next() { + return _next2.apply(this, arguments); + } + + function _next2() { + _next2 = _asyncToGenerator(function* () { + try { + var _ref = yield iterator.next(), + value = _ref.value, + done = _ref.done; + + if (done) { + readable.push(null); + } else if (readable.push((yield value))) { + next(); + } else { + reading = false; + } + } catch (err) { + readable.destroy(err); + } + }); + return _next2.apply(this, arguments); + } + + return readable; +} + +module.exports = from; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/pipeline.js b/node_modules/readable-stream/lib/internal/streams/pipeline.js new file mode 100644 index 0000000000000..6589909889c58 --- /dev/null +++ b/node_modules/readable-stream/lib/internal/streams/pipeline.js @@ -0,0 +1,97 @@ +// Ported from https://github.com/mafintosh/pump with +// permission from the author, Mathias Buus (@mafintosh). +'use strict'; + +var eos; + +function once(callback) { + var called = false; + return function () { + if (called) return; + called = true; + callback.apply(void 0, arguments); + }; +} + +var _require$codes = require('../../../errors').codes, + ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS, + ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED; + +function noop(err) { + // Rethrow the error if it exists to avoid swallowing it + if (err) throw err; +} + +function isRequest(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +} + +function destroyer(stream, reading, writing, callback) { + callback = once(callback); + var closed = false; + stream.on('close', function () { + closed = true; + }); + if (eos === undefined) eos = require('./end-of-stream'); + eos(stream, { + readable: reading, + writable: writing + }, function (err) { + if (err) return callback(err); + closed = true; + callback(); + }); + var destroyed = false; + return function (err) { + if (closed) return; + if (destroyed) return; + destroyed = true; // request.destroy just do .end - .abort is what we want + + if (isRequest(stream)) return stream.abort(); + if (typeof stream.destroy === 'function') return stream.destroy(); + callback(err || new ERR_STREAM_DESTROYED('pipe')); + }; +} + +function call(fn) { + fn(); +} + +function pipe(from, to) { + return from.pipe(to); +} + +function popCallback(streams) { + if (!streams.length) return noop; + if (typeof streams[streams.length - 1] !== 'function') return noop; + return streams.pop(); +} + +function pipeline() { + for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { + streams[_key] = arguments[_key]; + } + + var callback = popCallback(streams); + if (Array.isArray(streams[0])) streams = streams[0]; + + if (streams.length < 2) { + throw new ERR_MISSING_ARGS('streams'); + } + + var error; + var destroys = streams.map(function (stream, i) { + var reading = i < streams.length - 1; + var writing = i > 0; + return destroyer(stream, reading, writing, function (err) { + if (!error) error = err; + if (err) destroys.forEach(call); + if (reading) return; + destroys.forEach(call); + callback(error); + }); + }); + return streams.reduce(pipe); +} + +module.exports = pipeline; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/state.js b/node_modules/readable-stream/lib/internal/streams/state.js new file mode 100644 index 0000000000000..19887eb8a9070 --- /dev/null +++ b/node_modules/readable-stream/lib/internal/streams/state.js @@ -0,0 +1,27 @@ +'use strict'; + +var ERR_INVALID_OPT_VALUE = require('../../../errors').codes.ERR_INVALID_OPT_VALUE; + +function highWaterMarkFrom(options, isDuplex, duplexKey) { + return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null; +} + +function getHighWaterMark(state, options, duplexKey, isDuplex) { + var hwm = highWaterMarkFrom(options, isDuplex, duplexKey); + + if (hwm != null) { + if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) { + var name = isDuplex ? duplexKey : 'highWaterMark'; + throw new ERR_INVALID_OPT_VALUE(name, hwm); + } + + return Math.floor(hwm); + } // Default value + + + return state.objectMode ? 16 : 16 * 1024; +} + +module.exports = { + getHighWaterMark: getHighWaterMark +}; \ No newline at end of file diff --git a/node_modules/readable-stream/package.json b/node_modules/readable-stream/package.json index 2afa6fbd81e22..0b0c4bd207ace 100644 --- a/node_modules/readable-stream/package.json +++ b/node_modules/readable-stream/package.json @@ -1,31 +1,46 @@ { "name": "readable-stream", - "version": "2.3.7", + "version": "3.6.0", "description": "Streams3, a user-land copy of the stream library from Node.js", "main": "readable.js", + "engines": { + "node": ">= 6" + }, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "devDependencies": { + "@babel/cli": "^7.2.0", + "@babel/core": "^7.2.0", + "@babel/polyfill": "^7.0.0", + "@babel/preset-env": "^7.2.0", + "airtap": "0.0.9", "assert": "^1.4.0", - "babel-polyfill": "^6.9.1", - "buffer": "^4.9.0", - "lolex": "^2.3.2", - "nyc": "^6.4.0", - "tap": "^0.7.0", - "tape": "^4.8.0" + "bl": "^2.0.0", + "deep-strict-equal": "^0.2.0", + "events.once": "^2.0.2", + "glob": "^7.1.2", + "gunzip-maybe": "^1.4.1", + "hyperquest": "^2.1.3", + "lolex": "^2.6.0", + "nyc": "^11.0.0", + "pump": "^3.0.0", + "rimraf": "^2.6.2", + "tap": "^12.0.0", + "tape": "^4.9.0", + "tar-fs": "^1.16.2", + "util-promisify": "^2.1.0" }, "scripts": { - "test": "tap test/parallel/*.js test/ours/*.js && node test/verify-dependencies.js", - "ci": "tap test/parallel/*.js test/ours/*.js --tap | tee test.tap && node test/verify-dependencies.js", + "test": "tap -J --no-esm test/parallel/*.js test/ours/*.js", + "ci": "TAP=1 tap --no-esm test/parallel/*.js test/ours/*.js | tee test.tap", + "test-browsers": "airtap --sauce-connect --loopback airtap.local -- test/browser.js", + "test-browser-local": "airtap --open --local -- test/browser.js", "cover": "nyc npm test", - "report": "nyc report --reporter=lcov" + "report": "nyc report --reporter=lcov", + "update-browser-errors": "babel -o errors-browser.js errors.js" }, "repository": { "type": "git", @@ -38,9 +53,10 @@ ], "browser": { "util": false, + "worker_threads": false, + "./errors": "./errors-browser.js", "./readable.js": "./readable-browser.js", - "./writable.js": "./writable-browser.js", - "./duplex.js": "./duplex-browser.js", + "./lib/internal/streams/from.js": "./lib/internal/streams/from-browser.js", "./lib/internal/streams/stream.js": "./lib/internal/streams/stream-browser.js" }, "nyc": { diff --git a/node_modules/readable-stream/passthrough.js b/node_modules/readable-stream/passthrough.js deleted file mode 100644 index ffd791d7ff275..0000000000000 --- a/node_modules/readable-stream/passthrough.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./readable').PassThrough diff --git a/node_modules/readable-stream/readable-browser.js b/node_modules/readable-stream/readable-browser.js index e50372592ee6c..adbf60de832f9 100644 --- a/node_modules/readable-stream/readable-browser.js +++ b/node_modules/readable-stream/readable-browser.js @@ -5,3 +5,5 @@ exports.Writable = require('./lib/_stream_writable.js'); exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); +exports.finished = require('./lib/internal/streams/end-of-stream.js'); +exports.pipeline = require('./lib/internal/streams/pipeline.js'); diff --git a/node_modules/readable-stream/readable.js b/node_modules/readable-stream/readable.js index ec89ec5330649..9e0ca120ded82 100644 --- a/node_modules/readable-stream/readable.js +++ b/node_modules/readable-stream/readable.js @@ -1,13 +1,8 @@ var Stream = require('stream'); if (process.env.READABLE_STREAM === 'disable' && Stream) { - module.exports = Stream; - exports = module.exports = Stream.Readable; - exports.Readable = Stream.Readable; - exports.Writable = Stream.Writable; - exports.Duplex = Stream.Duplex; - exports.Transform = Stream.Transform; - exports.PassThrough = Stream.PassThrough; - exports.Stream = Stream; + module.exports = Stream.Readable; + Object.assign(module.exports, Stream); + module.exports.Stream = Stream; } else { exports = module.exports = require('./lib/_stream_readable.js'); exports.Stream = Stream || exports; @@ -16,4 +11,6 @@ if (process.env.READABLE_STREAM === 'disable' && Stream) { exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); + exports.finished = require('./lib/internal/streams/end-of-stream.js'); + exports.pipeline = require('./lib/internal/streams/pipeline.js'); } diff --git a/node_modules/readable-stream/transform.js b/node_modules/readable-stream/transform.js deleted file mode 100644 index b1baba26da03d..0000000000000 --- a/node_modules/readable-stream/transform.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./readable').Transform diff --git a/node_modules/readable-stream/writable-browser.js b/node_modules/readable-stream/writable-browser.js deleted file mode 100644 index ebdde6a85dcb1..0000000000000 --- a/node_modules/readable-stream/writable-browser.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/_stream_writable.js'); diff --git a/node_modules/readable-stream/writable.js b/node_modules/readable-stream/writable.js deleted file mode 100644 index 3211a6f80d1ab..0000000000000 --- a/node_modules/readable-stream/writable.js +++ /dev/null @@ -1,8 +0,0 @@ -var Stream = require("stream") -var Writable = require("./lib/_stream_writable.js") - -if (process.env.READABLE_STREAM === 'disable') { - module.exports = Stream && Stream.Writable || Writable -} else { - module.exports = Writable -} diff --git a/package-lock.json b/package-lock.json index c5cac9352e398..ef2bf71959f6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1197,13 +1197,16 @@ "inBundle": true }, "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.6.tgz", + "integrity": "sha512-+1byPnimWdGcKFRS48zG73nxM08kamPFReUYvEmRXI3E8E4YhF4voMRDaGlfGD1UeRHEgs4NhQCE28KI8JVj1A==", "inBundle": true, "dependencies": { "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/argparse": { @@ -1464,20 +1467,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4247,12 +4236,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "inBundle": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6238,12 +6221,6 @@ "integrity": "sha512-aCk8AO51s+4JyuYGg3Q/a6gnrlDO09NpVWePtjp7xwphcoQ04x5WAfCyugcsbLooWcMJ87CLkD4+604IckEdhg==", "inBundle": true }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "inBundle": true - }, "node_modules/process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -6599,18 +6576,17 @@ } }, "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "inBundle": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/readdir-scoped-modules": { @@ -9513,20 +9489,6 @@ "node": ">=6" } }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/tcompare": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.6.tgz", @@ -11354,12 +11316,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.6.tgz", + "integrity": "sha512-+1byPnimWdGcKFRS48zG73nxM08kamPFReUYvEmRXI3E8E4YhF4voMRDaGlfGD1UeRHEgs4NhQCE28KI8JVj1A==", "requires": { "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "readable-stream": "^3.6.0" } }, "argparse": { @@ -11548,19 +11510,6 @@ "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } } }, "brace-expansion": { @@ -13557,11 +13506,6 @@ "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", "dev": true }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -15089,11 +15033,6 @@ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-1.0.0.tgz", "integrity": "sha512-aCk8AO51s+4JyuYGg3Q/a6gnrlDO09NpVWePtjp7xwphcoQ04x5WAfCyugcsbLooWcMJ87CLkD4+604IckEdhg==" }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -15370,17 +15309,13 @@ } }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "readdir-scoped-modules": { @@ -17456,19 +17391,6 @@ "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } } }, "tcompare": { From 033e948c95b3455812e03a860ad1bd96a635e7eb Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 1 Sep 2021 14:32:47 -0700 Subject: [PATCH 06/35] deps: read-package-json@4.1.1 * feat: add types lookup * fix(man): don't lose relative man path --- node_modules/read-package-json/package.json | 10 +++- node_modules/read-package-json/read-json.js | 51 +++++++++++++++++++-- package-lock.json | 14 +++--- package.json | 2 +- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/node_modules/read-package-json/package.json b/node_modules/read-package-json/package.json index 5ca535cfd14ad..fb263fd711ee7 100644 --- a/node_modules/read-package-json/package.json +++ b/node_modules/read-package-json/package.json @@ -1,6 +1,6 @@ { "name": "read-package-json", - "version": "4.0.1", + "version": "4.1.1", "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "description": "The thing npm uses to read package.json files with semantics and defaults and validation", "repository": { @@ -12,7 +12,7 @@ "prerelease": "npm t", "postrelease": "npm publish && git push --follow-tags", "release": "standard-version -s", - "test": "tap --nyc-arg=--all --coverage test/*.js --branches 68 --functions 83 --lines 76 --statements 77", + "test": "tap --nyc-arg=--all --coverage test/*.js", "npmclilint": "npmcli-lint", "lint": "npm run npmclilint -- --ignore-pattern test/fixtures \"*.*js\" \"test/**/*.*js\"", "lintfix": "npm run lint -- --fix", @@ -36,5 +36,11 @@ ], "engines": { "node": ">=10" + }, + "tap": { + "branches": 68, + "functions": 83, + "lines": 76, + "statements": 77 } } diff --git a/node_modules/read-package-json/read-json.js b/node_modules/read-package-json/read-json.js index 04d22e3af7e21..468a33e397774 100644 --- a/node_modules/read-package-json/read-json.js +++ b/node_modules/read-package-json/read-json.js @@ -21,6 +21,7 @@ readJson.extraSet = [ mans, bins, githead, + fillTypes, ] var typoWarned = {} @@ -339,16 +340,17 @@ function readme_ (file, data, rm, cb) { } function mans (file, data, cb) { - var m = data.directories && data.directories.man - if (data.man || !m) { + let cwd = data.directories && data.directories.man + if (data.man || !cwd) { return cb(null, data) } - m = path.resolve(path.dirname(file), m) - glob('**/*.[0-9]', { cwd: m }, function (er, mans) { + const dirname = path.dirname(file) + cwd = path.resolve(path.dirname(file), cwd) + glob('**/*.[0-9]', { cwd }, function (er, mans) { if (er) { return cb(er) } - data.man = mans + data.man = mans.map(man => path.relative(dirname, path.join(cwd, man))) return cb(null, data) }) } @@ -517,6 +519,45 @@ function final (file, data, log, strict, cb) { }) } +function fillTypes (file, data, cb) { + var index = data.main ? data.main : 'index.js' + + // TODO exports is much more complicated than this in verbose format + // We need to support for instance + + // "exports": { + // ".": [ + // { + // "default": "./lib/npm.js" + // }, + // "./lib/npm.js" + // ], + // "./package.json": "./package.json" + // }, + // as well as conditional exports + + // if (data.exports && typeof data.exports === 'string') { + // index = data.exports + // } + + // if (data.exports && data.exports['.']) { + // index = data.exports['.'] + // if (typeof index !== 'string') { + // } + // } + + var extless = + path.join(path.dirname(index), path.basename(index, path.extname(index))) + var dts = `./${extless}.d.ts` + var dtsPath = path.join(path.dirname(file), dts) + var hasDTSFields = 'types' in data || 'typings' in data + if (!hasDTSFields && fs.existsSync(dtsPath)) { + data.types = dts + } + + cb(null, data) +} + function makePackageId (data) { var name = cleanString(data.name) var ver = cleanString(data.version) diff --git a/package-lock.json b/package-lock.json index ef2bf71959f6b..1d4f7b360a6e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -138,7 +138,7 @@ "parse-conflict-json": "^1.1.1", "qrcode-terminal": "^0.12.0", "read": "~1.0.7", - "read-package-json": "^4.0.1", + "read-package-json": "^4.1.1", "read-package-json-fast": "^2.0.3", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", @@ -6444,9 +6444,9 @@ "inBundle": true }, "node_modules/read-package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-4.0.1.tgz", - "integrity": "sha512-czqCcYfkEl6sIFJVOND/5/Goseu7cVw1rcDUATq6ED0jLGjMm9/HOPmFmEZMvRu9yl272YERaMUcOlvcNU9InQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-4.1.1.tgz", + "integrity": "sha512-P82sbZJ3ldDrWCOSKxJT0r/CXMWR0OR3KRh55SgKo3p91GSIEEC32v3lSHAvO/UcH3/IoL7uqhOFBduAnwdldw==", "inBundle": true, "dependencies": { "glob": "^7.1.1", @@ -15193,9 +15193,9 @@ "integrity": "sha512-HJpV9bQpkl6KwjxlJcBoqu9Ba0PQg8TqSNIOrulGt54a0uup0HtevreFHzYzkm0lpnleRdNBzXznKrgxglEHQw==" }, "read-package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-4.0.1.tgz", - "integrity": "sha512-czqCcYfkEl6sIFJVOND/5/Goseu7cVw1rcDUATq6ED0jLGjMm9/HOPmFmEZMvRu9yl272YERaMUcOlvcNU9InQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-4.1.1.tgz", + "integrity": "sha512-P82sbZJ3ldDrWCOSKxJT0r/CXMWR0OR3KRh55SgKo3p91GSIEEC32v3lSHAvO/UcH3/IoL7uqhOFBduAnwdldw==", "requires": { "glob": "^7.1.1", "json-parse-even-better-errors": "^2.3.0", diff --git a/package.json b/package.json index 30877f8de75c5..f769d346ea47e 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "parse-conflict-json": "^1.1.1", "qrcode-terminal": "^0.12.0", "read": "~1.0.7", - "read-package-json": "^4.0.1", + "read-package-json": "^4.1.1", "read-package-json-fast": "^2.0.3", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", From 0dcda73b022083338c4cb755390a275757b9627b Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 1 Sep 2021 14:50:42 -0700 Subject: [PATCH 07/35] deps: string_decoder@1.3.0 --- node_modules/safe-buffer/index.js | 3 ++ node_modules/safe-buffer/package.json | 22 ++++++++-- node_modules/string_decoder/package.json | 7 ++- package-lock.json | 56 ++++++++++++++++++------ 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/node_modules/safe-buffer/index.js b/node_modules/safe-buffer/index.js index 22438dabbbcee..f8d3ec98852f4 100644 --- a/node_modules/safe-buffer/index.js +++ b/node_modules/safe-buffer/index.js @@ -1,3 +1,4 @@ +/*! safe-buffer. MIT License. Feross Aboukhadijeh */ /* eslint-disable node/no-deprecated-api */ var buffer = require('buffer') var Buffer = buffer.Buffer @@ -20,6 +21,8 @@ function SafeBuffer (arg, encodingOrOffset, length) { return Buffer(arg, encodingOrOffset, length) } +SafeBuffer.prototype = Object.create(Buffer.prototype) + // Copy static methods from Buffer copyProps(Buffer, SafeBuffer) diff --git a/node_modules/safe-buffer/package.json b/node_modules/safe-buffer/package.json index 623fbc3f6b0c4..f2869e256477a 100644 --- a/node_modules/safe-buffer/package.json +++ b/node_modules/safe-buffer/package.json @@ -1,18 +1,18 @@ { "name": "safe-buffer", "description": "Safer Node.js Buffer API", - "version": "5.1.2", + "version": "5.2.1", "author": { "name": "Feross Aboukhadijeh", "email": "feross@feross.org", - "url": "http://feross.org" + "url": "https://feross.org" }, "bugs": { "url": "https://github.com/feross/safe-buffer/issues" }, "devDependencies": { "standard": "*", - "tape": "^4.0.0" + "tape": "^5.0.0" }, "homepage": "https://github.com/feross/safe-buffer", "keywords": [ @@ -33,5 +33,19 @@ }, "scripts": { "test": "standard && tape test/*.js" - } + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] } diff --git a/node_modules/string_decoder/package.json b/node_modules/string_decoder/package.json index 518c3eb9fb1ff..b2bb141160cad 100644 --- a/node_modules/string_decoder/package.json +++ b/node_modules/string_decoder/package.json @@ -1,10 +1,13 @@ { "name": "string_decoder", - "version": "1.1.1", + "version": "1.3.0", "description": "The string_decoder module from Node core", "main": "lib/string_decoder.js", + "files": [ + "lib" + ], "dependencies": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" }, "devDependencies": { "babel-polyfill": "^6.23.0", diff --git a/package-lock.json b/package-lock.json index 1d4f7b360a6e7..04dd0fe0c3831 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1990,6 +1990,12 @@ "safe-buffer": "~5.1.1" } }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -6876,9 +6882,23 @@ } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "inBundle": true }, "node_modules/safer-buffer": { @@ -7250,12 +7270,12 @@ } }, "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "inBundle": true, "dependencies": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } }, "node_modules/string-width": { @@ -11881,6 +11901,14 @@ "dev": true, "requires": { "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, "core-util-is": { @@ -15527,9 +15555,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", @@ -15812,11 +15840,11 @@ "dev": true }, "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } }, "string-width": { From 4b913417c4e30980505a02eec50810f895dd52d7 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 2 Sep 2021 07:36:26 -0700 Subject: [PATCH 08/35] deps: npmlog@5.0.1 --- node_modules/npmlog/log.js | 102 ++++++++++----- .../node_modules/are-we-there-yet/LICENSE.md | 18 +++ .../are-we-there-yet/lib/index.js | 4 + .../are-we-there-yet/lib/tracker-base.js | 11 ++ .../are-we-there-yet/lib/tracker-group.js | 116 ++++++++++++++++++ .../are-we-there-yet/lib/tracker-stream.js | 36 ++++++ .../are-we-there-yet/lib/tracker.js | 32 +++++ .../are-we-there-yet/package.json | 53 ++++++++ node_modules/npmlog/package.json | 4 +- package-lock.json | 42 +++++-- package.json | 2 +- 11 files changed, 374 insertions(+), 46 deletions(-) create mode 100644 node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md create mode 100644 node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js create mode 100644 node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js create mode 100644 node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js create mode 100644 node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js create mode 100644 node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js create mode 100644 node_modules/npmlog/node_modules/are-we-there-yet/package.json diff --git a/node_modules/npmlog/log.js b/node_modules/npmlog/log.js index 069154262e4da..85ab8a4c7905c 100644 --- a/node_modules/npmlog/log.js +++ b/node_modules/npmlog/log.js @@ -13,8 +13,9 @@ var stream = process.stderr Object.defineProperty(log, 'stream', { set: function (newStream) { stream = newStream - if (this.gauge) + if (this.gauge) { this.gauge.setWriteTo(stream, stream) + } }, get: function () { return stream @@ -78,20 +79,23 @@ log.setGaugeTemplate = function (template) { } log.enableProgress = function () { - if (this.progressEnabled) + if (this.progressEnabled) { return + } this.progressEnabled = true this.tracker.on('change', this.showProgress) - if (this._paused) + if (this._paused) { return + } this.gauge.enable() } log.disableProgress = function () { - if (!this.progressEnabled) + if (!this.progressEnabled) { return + } this.progressEnabled = false this.tracker.removeListener('change', this.showProgress) this.gauge.disable() @@ -103,19 +107,23 @@ var mixinLog = function (tracker) { // mixin the public methods from log into the tracker // (except: conflicts and one's we handle specially) Object.keys(log).forEach(function (P) { - if (P[0] === '_') + if (P[0] === '_') { return + } if (trackerConstructors.filter(function (C) { return C === P - }).length) + }).length) { return + } - if (tracker[P]) + if (tracker[P]) { return + } - if (typeof log[P] !== 'function') + if (typeof log[P] !== 'function') { return + } var func = log[P] tracker[P] = function () { @@ -143,27 +151,31 @@ trackerConstructors.forEach(function (C) { }) log.clearProgress = function (cb) { - if (!this.progressEnabled) + if (!this.progressEnabled) { return cb && process.nextTick(cb) + } this.gauge.hide(cb) } log.showProgress = function (name, completed) { - if (!this.progressEnabled) + if (!this.progressEnabled) { return + } var values = {} - if (name) + if (name) { values.section = name + } var last = log.record[log.record.length - 1] if (last) { values.subsection = last.prefix var disp = log.disp[last.level] || last.level var logline = this._format(disp, log.style[last.level]) - if (last.prefix) + if (last.prefix) { logline += ' ' + this._format(last.prefix, this.prefixStyle) + } logline += ' ' + last.message.split(/\r?\n/)[0] values.logline = logline @@ -175,13 +187,15 @@ log.showProgress = function (name, completed) { // temporarily stop emitting, but don't drop log.pause = function () { this._paused = true - if (this.progressEnabled) + if (this.progressEnabled) { this.gauge.disable() + } } log.resume = function () { - if (!this._paused) + if (!this._paused) { return + } this._paused = false @@ -190,8 +204,9 @@ log.resume = function () { b.forEach(function (m) { this.emitLog(m) }, this) - if (this.progressEnabled) + if (this.progressEnabled) { this.gauge.enable() + } } log._buffer = [] @@ -220,8 +235,9 @@ log.log = function (lvl, prefix, message) { }) } } - if (stack) + if (stack) { a.unshift(stack + '\n') + } message = util.format.apply(util, a) var m = { @@ -234,8 +250,9 @@ log.log = function (lvl, prefix, message) { this.emit('log', m) this.emit('log.' + lvl, m) - if (m.prefix) + if (m.prefix) { this.emit(m.prefix, m) + } this.record.push(m) var mrs = this.maxRecordSize @@ -253,18 +270,22 @@ log.emitLog = function (m) { this._buffer.push(m) return } - if (this.progressEnabled) + if (this.progressEnabled) { this.gauge.pulse(m.prefix) + } var l = this.levels[m.level] - if (l === undefined) + if (l === undefined) { return + } - if (l < this.levels[this.level]) + if (l < this.levels[this.level]) { return + } - if (l > 0 && !isFinite(l)) + if (l > 0 && !isFinite(l)) { return + } // If 'disp' is null or undefined, use the lvl as a default // Allows: '', 0 as valid disp @@ -277,8 +298,9 @@ log.emitLog = function (m) { } this.write(disp, log.style[m.level]) var p = m.prefix || '' - if (p) + if (p) { this.write(' ') + } this.write(p, this.prefixStyle) this.write(' ' + line + '\n') @@ -287,52 +309,63 @@ log.emitLog = function (m) { } log._format = function (msg, style) { - if (!stream) + if (!stream) { return + } var output = '' if (this.useColor()) { style = style || {} var settings = [] - if (style.fg) + if (style.fg) { settings.push(style.fg) + } - if (style.bg) + if (style.bg) { settings.push('bg' + style.bg[0].toUpperCase() + style.bg.slice(1)) + } - if (style.bold) + if (style.bold) { settings.push('bold') + } - if (style.underline) + if (style.underline) { settings.push('underline') + } - if (style.inverse) + if (style.inverse) { settings.push('inverse') + } - if (settings.length) + if (settings.length) { output += consoleControl.color(settings) + } - if (style.beep) + if (style.beep) { output += consoleControl.beep() + } } output += msg - if (this.useColor()) + if (this.useColor()) { output += consoleControl.color('reset') + } return output } log.write = function (msg, style) { - if (!stream) + if (!stream) { return + } stream.write(this._format(msg, style)) } log.addLevel = function (lvl, n, style, disp) { // If 'disp' is null or undefined, use the lvl as a default - if (disp == null) + if (disp == null) { disp = lvl + } this.levels[lvl] = n this.style[lvl] = style @@ -340,8 +373,9 @@ log.addLevel = function (lvl, n, style, disp) { this[lvl] = function () { var a = new Array(arguments.length + 1) a[0] = lvl - for (var i = 0; i < arguments.length; i++) + for (var i = 0; i < arguments.length; i++) { a[i + 1] = arguments[i] + } return this.log.apply(this, a) }.bind(this) diff --git a/node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md b/node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md new file mode 100644 index 0000000000000..845be76f64e78 --- /dev/null +++ b/node_modules/npmlog/node_modules/are-we-there-yet/LICENSE.md @@ -0,0 +1,18 @@ +ISC License + +Copyright npm, Inc. + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js b/node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js new file mode 100644 index 0000000000000..57d8743fdad17 --- /dev/null +++ b/node_modules/npmlog/node_modules/are-we-there-yet/lib/index.js @@ -0,0 +1,4 @@ +'use strict' +exports.TrackerGroup = require('./tracker-group.js') +exports.Tracker = require('./tracker.js') +exports.TrackerStream = require('./tracker-stream.js') diff --git a/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js new file mode 100644 index 0000000000000..6f436875578a7 --- /dev/null +++ b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-base.js @@ -0,0 +1,11 @@ +'use strict' +var EventEmitter = require('events').EventEmitter +var util = require('util') + +var trackerId = 0 +var TrackerBase = module.exports = function (name) { + EventEmitter.call(this) + this.id = ++trackerId + this.name = name +} +util.inherits(TrackerBase, EventEmitter) diff --git a/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js new file mode 100644 index 0000000000000..9da13f8a7e116 --- /dev/null +++ b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-group.js @@ -0,0 +1,116 @@ +'use strict' +var util = require('util') +var TrackerBase = require('./tracker-base.js') +var Tracker = require('./tracker.js') +var TrackerStream = require('./tracker-stream.js') + +var TrackerGroup = module.exports = function (name) { + TrackerBase.call(this, name) + this.parentGroup = null + this.trackers = [] + this.completion = {} + this.weight = {} + this.totalWeight = 0 + this.finished = false + this.bubbleChange = bubbleChange(this) +} +util.inherits(TrackerGroup, TrackerBase) + +function bubbleChange (trackerGroup) { + return function (name, completed, tracker) { + trackerGroup.completion[tracker.id] = completed + if (trackerGroup.finished) { + return + } + trackerGroup.emit('change', name || trackerGroup.name, trackerGroup.completed(), trackerGroup) + } +} + +TrackerGroup.prototype.nameInTree = function () { + var names = [] + var from = this + while (from) { + names.unshift(from.name) + from = from.parentGroup + } + return names.join('/') +} + +TrackerGroup.prototype.addUnit = function (unit, weight) { + if (unit.addUnit) { + var toTest = this + while (toTest) { + if (unit === toTest) { + throw new Error( + 'Attempted to add tracker group ' + + unit.name + ' to tree that already includes it ' + + this.nameInTree(this)) + } + toTest = toTest.parentGroup + } + unit.parentGroup = this + } + this.weight[unit.id] = weight || 1 + this.totalWeight += this.weight[unit.id] + this.trackers.push(unit) + this.completion[unit.id] = unit.completed() + unit.on('change', this.bubbleChange) + if (!this.finished) { + this.emit('change', unit.name, this.completion[unit.id], unit) + } + return unit +} + +TrackerGroup.prototype.completed = function () { + if (this.trackers.length === 0) { + return 0 + } + var valPerWeight = 1 / this.totalWeight + var completed = 0 + for (var ii = 0; ii < this.trackers.length; ii++) { + var trackerId = this.trackers[ii].id + completed += + valPerWeight * this.weight[trackerId] * this.completion[trackerId] + } + return completed +} + +TrackerGroup.prototype.newGroup = function (name, weight) { + return this.addUnit(new TrackerGroup(name), weight) +} + +TrackerGroup.prototype.newItem = function (name, todo, weight) { + return this.addUnit(new Tracker(name, todo), weight) +} + +TrackerGroup.prototype.newStream = function (name, todo, weight) { + return this.addUnit(new TrackerStream(name, todo), weight) +} + +TrackerGroup.prototype.finish = function () { + this.finished = true + if (!this.trackers.length) { + this.addUnit(new Tracker(), 1, true) + } + for (var ii = 0; ii < this.trackers.length; ii++) { + var tracker = this.trackers[ii] + tracker.finish() + tracker.removeListener('change', this.bubbleChange) + } + this.emit('change', this.name, 1, this) +} + +var buffer = ' ' +TrackerGroup.prototype.debug = function (depth) { + depth = depth || 0 + var indent = depth ? buffer.substr(0, depth) : '' + var output = indent + (this.name || 'top') + ': ' + this.completed() + '\n' + this.trackers.forEach(function (tracker) { + if (tracker instanceof TrackerGroup) { + output += tracker.debug(depth + 1) + } else { + output += indent + ' ' + tracker.name + ': ' + tracker.completed() + '\n' + } + }) + return output +} diff --git a/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js new file mode 100644 index 0000000000000..e1cf85055702a --- /dev/null +++ b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker-stream.js @@ -0,0 +1,36 @@ +'use strict' +var util = require('util') +var stream = require('readable-stream') +var delegate = require('delegates') +var Tracker = require('./tracker.js') + +var TrackerStream = module.exports = function (name, size, options) { + stream.Transform.call(this, options) + this.tracker = new Tracker(name, size) + this.name = name + this.id = this.tracker.id + this.tracker.on('change', delegateChange(this)) +} +util.inherits(TrackerStream, stream.Transform) + +function delegateChange (trackerStream) { + return function (name, completion, tracker) { + trackerStream.emit('change', name, completion, trackerStream) + } +} + +TrackerStream.prototype._transform = function (data, encoding, cb) { + this.tracker.completeWork(data.length ? data.length : 1) + this.push(data) + cb() +} + +TrackerStream.prototype._flush = function (cb) { + this.tracker.finish() + cb() +} + +delegate(TrackerStream.prototype, 'tracker') + .method('completed') + .method('addWork') + .method('finish') diff --git a/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js new file mode 100644 index 0000000000000..a8f8b3ba01391 --- /dev/null +++ b/node_modules/npmlog/node_modules/are-we-there-yet/lib/tracker.js @@ -0,0 +1,32 @@ +'use strict' +var util = require('util') +var TrackerBase = require('./tracker-base.js') + +var Tracker = module.exports = function (name, todo) { + TrackerBase.call(this, name) + this.workDone = 0 + this.workTodo = todo || 0 +} +util.inherits(Tracker, TrackerBase) + +Tracker.prototype.completed = function () { + return this.workTodo === 0 ? 0 : this.workDone / this.workTodo +} + +Tracker.prototype.addWork = function (work) { + this.workTodo += work + this.emit('change', this.name, this.completed(), this) +} + +Tracker.prototype.completeWork = function (work) { + this.workDone += work + if (this.workDone > this.workTodo) { + this.workDone = this.workTodo + } + this.emit('change', this.name, this.completed(), this) +} + +Tracker.prototype.finish = function () { + this.workTodo = this.workDone = 1 + this.emit('change', this.name, 1, this) +} diff --git a/node_modules/npmlog/node_modules/are-we-there-yet/package.json b/node_modules/npmlog/node_modules/are-we-there-yet/package.json new file mode 100644 index 0000000000000..5714e09c3b371 --- /dev/null +++ b/node_modules/npmlog/node_modules/are-we-there-yet/package.json @@ -0,0 +1,53 @@ +{ + "name": "are-we-there-yet", + "version": "2.0.0", + "description": "Keep track of the overall completion of many disparate processes", + "main": "lib/index.js", + "scripts": { + "test": "tap", + "npmclilint": "npmcli-lint", + "lint": "eslint '**/*.js'", + "lintfix": "npm run lint -- --fix", + "posttest": "npm run lint", + "postsnap": "npm run lintfix --", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "snap": "tap" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/are-we-there-yet.git" + }, + "author": "GitHub Inc.", + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/are-we-there-yet/issues" + }, + "homepage": "https://github.com/npm/are-we-there-yet", + "devDependencies": { + "@npmcli/eslint-config": "^1.0.0", + "@npmcli/template-oss": "^1.0.2", + "eslint": "^7.32.0", + "eslint-plugin-node": "^11.1.0", + "tap": "^15.0.9" + }, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "files": [ + "bin", + "lib" + ], + "engines": { + "node": ">=10" + }, + "tap": { + "branches": 68, + "statements": 92, + "functions": 86, + "lines": 92 + }, + "templateVersion": "1.0.2" +} diff --git a/node_modules/npmlog/package.json b/node_modules/npmlog/package.json index 5288b9ca06256..960ea9250d949 100644 --- a/node_modules/npmlog/package.json +++ b/node_modules/npmlog/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "npmlog", "description": "logger for npm", - "version": "5.0.0", + "version": "5.0.1", "repository": { "type": "git", "url": "https://github.com/npm/npmlog.git" @@ -20,7 +20,7 @@ "postsnap": "npm run lintfix --" }, "dependencies": { - "are-we-there-yet": "^1.1.5", + "are-we-there-yet": "^2.0.0", "console-control-strings": "^1.1.0", "gauge": "^3.0.0", "set-blocking": "^2.0.0" diff --git a/package-lock.json b/package-lock.json index 04dd0fe0c3831..f6d1f71862d1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -132,7 +132,7 @@ "npm-profile": "^5.0.3", "npm-registry-fetch": "^11.0.0", "npm-user-validate": "^1.0.1", - "npmlog": "^5.0.0", + "npmlog": "^5.0.1", "opener": "^1.5.2", "pacote": "^11.3.5", "parse-conflict-json": "^1.1.1", @@ -5567,17 +5567,30 @@ "inBundle": true }, "node_modules/npmlog": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.0.tgz", - "integrity": "sha512-ftpIiLjerL2tUg3dCqN8pOSoB90gqZlzv/gaZoxHaKjeLClrfJIEQ1Pdxi6qSzflz916Bljdy8dTWQ4J7hAFSQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", "inBundle": true, "dependencies": { - "are-we-there-yet": "^1.1.5", + "are-we-there-yet": "^2.0.0", "console-control-strings": "^1.1.0", "gauge": "^3.0.0", "set-blocking": "^2.0.0" } }, + "node_modules/npmlog/node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "inBundle": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/null-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", @@ -14560,14 +14573,25 @@ "integrity": "sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==" }, "npmlog": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.0.tgz", - "integrity": "sha512-ftpIiLjerL2tUg3dCqN8pOSoB90gqZlzv/gaZoxHaKjeLClrfJIEQ1Pdxi6qSzflz916Bljdy8dTWQ4J7hAFSQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", "requires": { - "are-we-there-yet": "^1.1.5", + "are-we-there-yet": "^2.0.0", "console-control-strings": "^1.1.0", "gauge": "^3.0.0", "set-blocking": "^2.0.0" + }, + "dependencies": { + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + } } }, "null-check": { diff --git a/package.json b/package.json index f769d346ea47e..1158e3b9d0d5d 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "npm-profile": "^5.0.3", "npm-registry-fetch": "^11.0.0", "npm-user-validate": "^1.0.1", - "npmlog": "^5.0.0", + "npmlog": "^5.0.1", "opener": "^1.5.2", "pacote": "^11.3.5", "parse-conflict-json": "^1.1.1", From 876c755eb0dfc215123682f798b5fca415f7c7d9 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 2 Sep 2021 11:48:32 -0700 Subject: [PATCH 09/35] @npmcli/arborist@2.8.3 * fix: do not fail adding unresolvable optional dep --- node_modules/@npmcli/arborist/bin/actual.js | 6 +- node_modules/@npmcli/arborist/bin/audit.js | 18 +- node_modules/@npmcli/arborist/bin/dedupe.js | 9 +- node_modules/@npmcli/arborist/bin/funding.js | 6 +- node_modules/@npmcli/arborist/bin/ideal.js | 3 +- .../@npmcli/arborist/bin/lib/logging.js | 7 +- .../@npmcli/arborist/bin/lib/options.js | 26 +- .../@npmcli/arborist/bin/lib/timers.js | 9 +- node_modules/@npmcli/arborist/bin/license.js | 14 +- node_modules/@npmcli/arborist/bin/prune.js | 9 +- node_modules/@npmcli/arborist/bin/reify.js | 9 +- node_modules/@npmcli/arborist/bin/virtual.js | 6 +- .../@npmcli/arborist/lib/add-rm-pkg-deps.js | 39 ++- .../@npmcli/arborist/lib/arborist/audit.js | 3 +- .../arborist/lib/arborist/build-ideal-tree.js | 197 +++++++---- .../@npmcli/arborist/lib/arborist/deduper.js | 3 +- .../@npmcli/arborist/lib/arborist/index.js | 12 +- .../arborist/lib/arborist/load-actual.js | 41 ++- .../arborist/lib/arborist/load-virtual.js | 52 ++- .../arborist/lib/arborist/load-workspaces.js | 6 +- .../@npmcli/arborist/lib/arborist/rebuild.js | 47 ++- .../@npmcli/arborist/lib/arborist/reify.js | 229 ++++++++---- .../@npmcli/arborist/lib/audit-report.js | 64 ++-- .../@npmcli/arborist/lib/calc-dep-flags.js | 27 +- .../@npmcli/arborist/lib/can-place-dep.js | 84 +++-- .../arborist/lib/case-insensitive-map.js | 6 +- .../arborist/lib/consistent-resolve.js | 3 +- .../arborist/lib/deepest-nesting-target.js | 6 +- .../@npmcli/arborist/lib/dep-valid.js | 12 +- node_modules/@npmcli/arborist/lib/diff.js | 96 +++-- node_modules/@npmcli/arborist/lib/edge.js | 39 ++- .../@npmcli/arborist/lib/gather-dep-set.js | 3 +- .../@npmcli/arborist/lib/inventory.js | 18 +- node_modules/@npmcli/arborist/lib/link.js | 23 +- node_modules/@npmcli/arborist/lib/node.js | 329 ++++++++++++------ .../@npmcli/arborist/lib/optional-set.js | 6 +- .../@npmcli/arborist/lib/peer-entry-sets.js | 15 +- .../@npmcli/arborist/lib/place-dep.js | 85 +++-- .../@npmcli/arborist/lib/printable.js | 62 ++-- node_modules/@npmcli/arborist/lib/realpath.js | 18 +- .../@npmcli/arborist/lib/shrinkwrap.js | 251 ++++++++----- .../@npmcli/arborist/lib/signal-handling.js | 9 +- .../@npmcli/arborist/lib/spec-from-lock.js | 11 +- node_modules/@npmcli/arborist/lib/tracker.js | 42 ++- .../@npmcli/arborist/lib/tree-check.js | 18 +- .../@npmcli/arborist/lib/version-from-tgz.js | 6 +- node_modules/@npmcli/arborist/lib/vuln.js | 44 ++- .../@npmcli/arborist/lib/yarn-lock.js | 42 ++- node_modules/@npmcli/arborist/package.json | 17 +- package-lock.json | 14 +- package.json | 2 +- 51 files changed, 1379 insertions(+), 724 deletions(-) diff --git a/node_modules/@npmcli/arborist/bin/actual.js b/node_modules/@npmcli/arborist/bin/actual.js index ef254e1d4133d..eb0495997a1b9 100644 --- a/node_modules/@npmcli/arborist/bin/actual.js +++ b/node_modules/@npmcli/arborist/bin/actual.js @@ -7,12 +7,14 @@ require('./lib/timers.js') const start = process.hrtime() new Arborist(options).loadActual(options).then(tree => { const end = process.hrtime(start) - if (!process.argv.includes('--quiet')) + if (!process.argv.includes('--quiet')) { print(tree) + } console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`) - if (options.save) + if (options.save) { tree.meta.save() + } if (options.saveHidden) { tree.meta.hiddenLockfile = true tree.meta.filename = options.path + '/node_modules/.package-lock.json' diff --git a/node_modules/@npmcli/arborist/bin/audit.js b/node_modules/@npmcli/arborist/bin/audit.js index 5075724e2d471..d9ac532d3ed70 100644 --- a/node_modules/@npmcli/arborist/bin/audit.js +++ b/node_modules/@npmcli/arborist/bin/audit.js @@ -7,12 +7,14 @@ require('./lib/logging.js') const Vuln = require('../lib/vuln.js') const printReport = report => { - for (const vuln of report.values()) + for (const vuln of report.values()) { console.log(printVuln(vuln)) + } if (report.topVulns.size) { console.log('\n# top-level vulnerabilities') - for (const vuln of report.topVulns.values()) + for (const vuln of report.topVulns.values()) { console.log(printVuln(vuln)) + } } } @@ -37,12 +39,16 @@ const arb = new Arborist(options) arb.audit(options).then(tree => { process.emit('timeEnd', 'audit script') const end = process.hrtime(start) - if (options.fix) + if (options.fix) { print(tree) - if (!options.quiet) + } + if (!options.quiet) { printReport(arb.auditReport) - if (options.fix) + } + if (options.fix) { console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) - if (tree.meta && options.save) + } + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => console.error(er)) diff --git a/node_modules/@npmcli/arborist/bin/dedupe.js b/node_modules/@npmcli/arborist/bin/dedupe.js index 96f754e34ca9e..b0e83459ef73f 100644 --- a/node_modules/@npmcli/arborist/bin/dedupe.js +++ b/node_modules/@npmcli/arborist/bin/dedupe.js @@ -10,8 +10,9 @@ const printDiff = diff => { depth({ tree: diff, visit: d => { - if (d.location === '') + if (d.location === '') { return + } switch (d.action) { case 'REMOVE': console.error('REMOVE', d.actual.location) @@ -38,9 +39,11 @@ arb.dedupe(options).then(tree => { process.emit('timeEnd', 'install') const end = process.hrtime(start) print(tree) - if (options.dryRun) + if (options.dryRun) { printDiff(arb.diff) + } console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) - if (tree.meta && options.save) + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => console.error(require('util').inspect(er, { depth: Infinity }))) diff --git a/node_modules/@npmcli/arborist/bin/funding.js b/node_modules/@npmcli/arborist/bin/funding.js index fa1237e87e98a..d0f4f31654ae0 100644 --- a/node_modules/@npmcli/arborist/bin/funding.js +++ b/node_modules/@npmcli/arborist/bin/funding.js @@ -19,13 +19,15 @@ a.loadVirtual().then(tree => { const end = process.hrtime(start) if (!query) { for (const node of tree.inventory.values()) { - if (node.package.funding) + if (node.package.funding) { console.log(node.name, node.location, node.package.funding) + } } } else { for (const node of tree.inventory.query('name', query)) { - if (node.package.funding) + if (node.package.funding) { console.log(node.name, node.location, node.package.funding) + } } } console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`) diff --git a/node_modules/@npmcli/arborist/bin/ideal.js b/node_modules/@npmcli/arborist/bin/ideal.js index 74d79ce0a51e9..5d1ed0dcd9dc6 100644 --- a/node_modules/@npmcli/arborist/bin/ideal.js +++ b/node_modules/@npmcli/arborist/bin/ideal.js @@ -11,8 +11,9 @@ new Arborist(options).buildIdealTree(options).then(tree => { const end = process.hrtime(start) print(tree) console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 10e9}s`) - if (tree.meta && options.save) + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => { const opt = { depth: Infinity, color: true } console.error(er.code === 'ERESOLVE' ? inspect(er, opt) : er) diff --git a/node_modules/@npmcli/arborist/bin/lib/logging.js b/node_modules/@npmcli/arborist/bin/lib/logging.js index 9420bca3c320c..8183ece1fd119 100644 --- a/node_modules/@npmcli/arborist/bin/lib/logging.js +++ b/node_modules/@npmcli/arborist/bin/lib/logging.js @@ -24,12 +24,13 @@ const colors = process.stderr.isTTY const magenta = colors ? msg => `\x1B[35m${msg}\x1B[39m` : m => m if (loglevel !== 'silent') { process.on('log', (level, ...args) => { - if (levelMap.get(level) < levelMap.get(loglevel)) + if (levelMap.get(level) < levelMap.get(loglevel)) { return + } const pref = `${process.pid} ${magenta(level)} ` - if (level === 'warn' && args[0] === 'ERESOLVE') + if (level === 'warn' && args[0] === 'ERESOLVE') { args[2] = inspect(args[2], { depth: 10, colors }) - else { + } else { args = args.map(a => { return typeof a === 'string' ? a : inspect(a, { depth: 10, colors }) diff --git a/node_modules/@npmcli/arborist/bin/lib/options.js b/node_modules/@npmcli/arborist/bin/lib/options.js index a1b6719627f50..23e89ddce698b 100644 --- a/node_modules/@npmcli/arborist/bin/lib/options.js +++ b/node_modules/@npmcli/arborist/bin/lib/options.js @@ -11,17 +11,17 @@ for (const arg of process.argv.slice(2)) { } else if (/^--rm=/.test(arg)) { options.rm = options.rm || [] options.rm.push(arg.substr('--rm='.length)) - } else if (arg === '--global') + } else if (arg === '--global') { options.global = true - else if (arg === '--global-style') + } else if (arg === '--global-style') { options.globalStyle = true - else if (arg === '--prefer-dedupe') + } else if (arg === '--prefer-dedupe') { options.preferDedupe = true - else if (arg === '--legacy-peer-deps') + } else if (arg === '--legacy-peer-deps') { options.legacyPeerDeps = true - else if (arg === '--force') + } else if (arg === '--force') { options.force = true - else if (arg === '--update-all') { + } else if (arg === '--update-all') { options.update = options.update || {} options.update.all = true } else if (/^--update=/.test(arg)) { @@ -31,9 +31,9 @@ for (const arg of process.argv.slice(2)) { } else if (/^--omit=/.test(arg)) { options.omit = options.omit || [] options.omit.push(arg.substr('--omit='.length)) - } else if (/^--before=/.test(arg)) + } else if (/^--before=/.test(arg)) { options.before = new Date(arg.substr('--before='.length)) - else if (/^-w.+/.test(arg)) { + } else if (/^-w.+/.test(arg)) { options.workspaces = options.workspaces || [] options.workspaces.push(arg.replace(/^-w/, '')) } else if (/^--workspace=/.test(arg)) { @@ -43,15 +43,17 @@ for (const arg of process.argv.slice(2)) { const [key, ...v] = arg.replace(/^--/, '').split('=') const val = v.join('=') options[key] = val === 'false' ? false : val === 'true' ? true : val - } else if (/^--.+/.test(arg)) + } else if (/^--.+/.test(arg)) { options[arg.replace(/^--/, '')] = true - else if (options.path === undefined) + } else if (options.path === undefined) { options.path = arg - else + } else { options._.push(arg) + } } -if (options.path === undefined) +if (options.path === undefined) { options.path = '.' +} console.error(options) diff --git a/node_modules/@npmcli/arborist/bin/lib/timers.js b/node_modules/@npmcli/arborist/bin/lib/timers.js index b516af92c5b57..242431980e55c 100644 --- a/node_modules/@npmcli/arborist/bin/lib/timers.js +++ b/node_modules/@npmcli/arborist/bin/lib/timers.js @@ -3,21 +3,24 @@ const { format } = require('util') const options = require('./options.js') process.on('time', name => { - if (timers[name]) + if (timers[name]) { throw new Error('conflicting timer! ' + name) + } timers[name] = process.hrtime() }) const dim = process.stderr.isTTY ? msg => `\x1B[2m${msg}\x1B[22m` : m => m const red = process.stderr.isTTY ? msg => `\x1B[31m${msg}\x1B[39m` : m => m process.on('timeEnd', name => { - if (!timers[name]) + if (!timers[name]) { throw new Error('timer not started! ' + name) + } const res = process.hrtime(timers[name]) delete timers[name] const msg = format(`${process.pid} ${name}`, res[0] * 1e3 + res[1] / 1e6) - if (options.timers !== false) + if (options.timers !== false) { console.error(dim(msg)) + } }) process.on('exit', () => { diff --git a/node_modules/@npmcli/arborist/bin/license.js b/node_modules/@npmcli/arborist/bin/license.js index 89d0d879036b0..7fc08dd83eb5b 100644 --- a/node_modules/@npmcli/arborist/bin/license.js +++ b/node_modules/@npmcli/arborist/bin/license.js @@ -8,27 +8,31 @@ const query = options._.shift() a.loadVirtual().then(tree => { // only load the actual tree if the virtual one doesn't have modern metadata - if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2)) + if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2)) { throw 'load actual' - else + } else { return tree + } }).catch((er) => { console.error('loading actual tree', er) return a.loadActual() }).then(tree => { if (!query) { const set = [] - for (const license of tree.inventory.query('license')) + for (const license of tree.inventory.query('license')) { set.push([tree.inventory.query('license', license).size, license]) + } for (const [count, license] of set.sort((a, b) => a[1] && b[1] ? b[0] - a[0] || a[1].localeCompare(b[1], 'en') : a[1] ? -1 : b[1] ? 1 - : 0)) + : 0)) { console.log(count, license) + } } else { - for (const node of tree.inventory.query('license', query === 'undefined' ? undefined : query)) + for (const node of tree.inventory.query('license', query === 'undefined' ? undefined : query)) { console.log(`${node.name} ${node.location} ${node.package.description || ''}`) + } } }) diff --git a/node_modules/@npmcli/arborist/bin/prune.js b/node_modules/@npmcli/arborist/bin/prune.js index 357dbcaafa03f..4809a992388aa 100644 --- a/node_modules/@npmcli/arborist/bin/prune.js +++ b/node_modules/@npmcli/arborist/bin/prune.js @@ -10,8 +10,9 @@ const printDiff = diff => { depth({ tree: diff, visit: d => { - if (d.location === '') + if (d.location === '') { return + } switch (d.action) { case 'REMOVE': console.error('REMOVE', d.actual.location) @@ -38,9 +39,11 @@ arb.prune(options).then(tree => { process.emit('timeEnd', 'install') const end = process.hrtime(start) print(tree) - if (options.dryRun) + if (options.dryRun) { printDiff(arb.diff) + } console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) - if (tree.meta && options.save) + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => console.error(require('util').inspect(er, { depth: Infinity }))) diff --git a/node_modules/@npmcli/arborist/bin/reify.js b/node_modules/@npmcli/arborist/bin/reify.js index d17a0e03b3286..803bac978c69a 100644 --- a/node_modules/@npmcli/arborist/bin/reify.js +++ b/node_modules/@npmcli/arborist/bin/reify.js @@ -10,8 +10,9 @@ const printDiff = diff => { depth({ tree: diff, visit: d => { - if (d.location === '') + if (d.location === '') { return + } switch (d.action) { case 'REMOVE': console.error('REMOVE', d.actual.location) @@ -38,9 +39,11 @@ arb.reify(options).then(tree => { process.emit('timeEnd', 'install') const end = process.hrtime(start) print(tree) - if (options.dryRun) + if (options.dryRun) { printDiff(arb.diff) + } console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) - if (tree.meta && options.save) + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => console.error(require('util').inspect(er, { depth: Infinity }))) diff --git a/node_modules/@npmcli/arborist/bin/virtual.js b/node_modules/@npmcli/arborist/bin/virtual.js index 3352802c2de87..457c945e72c21 100644 --- a/node_modules/@npmcli/arborist/bin/virtual.js +++ b/node_modules/@npmcli/arborist/bin/virtual.js @@ -8,9 +8,11 @@ require('./lib/timers.js') const start = process.hrtime() new Arborist(options).loadVirtual().then(tree => { const end = process.hrtime(start) - if (!options.quiet) + if (!options.quiet) { print(tree) - if (options.save) + } + if (options.save) { tree.meta.save() + } console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`) }).catch(er => console.error(er)) diff --git a/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js b/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js index f78a43319be8c..c1b64a461af8a 100644 --- a/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js +++ b/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js @@ -1,8 +1,9 @@ // add and remove dependency specs to/from pkg manifest const add = ({pkg, add, saveBundle, saveType, log}) => { - for (const spec of add) + for (const spec of add) { addSingle({pkg, spec, saveBundle, saveType, log}) + } return pkg } @@ -24,8 +25,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => { // to keep based on the same order of priority we do when // building the tree as defined in the _loadDeps method of // the node class. - if (!saveType) + if (!saveType) { saveType = inferSaveType(pkg, spec.name) + } if (saveType === 'prod') { // a production dependency can only exist as production (rpj ensures it @@ -48,8 +50,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => { const depType = saveTypeMap.get(saveType) pkg[depType] = pkg[depType] || {} - if (rawSpec !== '' || pkg[depType][name] === undefined) + if (rawSpec !== '' || pkg[depType][name] === undefined) { pkg[depType][name] = rawSpec || '*' + } if (saveType === 'optional') { // Affordance for previous npm versions that require this behaviour pkg.dependencies = pkg.dependencies || {} @@ -58,17 +61,18 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => { if (saveType === 'peer' || saveType === 'peerOptional') { const pdm = pkg.peerDependenciesMeta || {} - if (saveType === 'peer' && pdm[name] && pdm[name].optional) + if (saveType === 'peer' && pdm[name] && pdm[name].optional) { pdm[name].optional = false - else if (saveType === 'peerOptional') { + } else if (saveType === 'peerOptional') { pdm[name] = pdm[name] || {} pdm[name].optional = true pkg.peerDependenciesMeta = pdm } // peerDeps are often also a devDep, so that they can be tested when // using package managers that don't auto-install peer deps - if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) + if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) { pkg.devDependencies[name] = pkg.peerDependencies[name] + } } if (saveBundle && saveType !== 'peer' && saveType !== 'peerOptional') { @@ -87,47 +91,54 @@ const inferSaveType = (pkg, name) => { saveType === 'peerOptional' && (!hasSubKey(pkg, 'peerDependenciesMeta', name) || !pkg.peerDependenciesMeta[name].optional) - ) + ) { return 'peer' + } return saveType } } return 'prod' } +const { hasOwnProperty } = Object.prototype const hasSubKey = (pkg, depType, name) => { - return pkg[depType] && Object.prototype.hasOwnProperty.call(pkg[depType], name) + return pkg[depType] && hasOwnProperty.call(pkg[depType], name) } // Removes a subkey and warns about it if it's being replaced const deleteSubKey = (pkg, depType, name, replacedBy, log) => { if (hasSubKey(pkg, depType, name)) { - if (replacedBy && log) + if (replacedBy && log) { log.warn('idealTree', `Removing ${depType}.${name} in favor of ${replacedBy}.${name}`) + } delete pkg[depType][name] - // clean up peerDependenciesMeta if we are removing something from peerDependencies + // clean up peerDepsMeta if we are removing something from peerDependencies if (depType === 'peerDependencies' && pkg.peerDependenciesMeta) { delete pkg.peerDependenciesMeta[name] - if (!Object.keys(pkg.peerDependenciesMeta).length) + if (!Object.keys(pkg.peerDependenciesMeta).length) { delete pkg.peerDependenciesMeta + } } - if (!Object.keys(pkg[depType]).length) + if (!Object.keys(pkg[depType]).length) { delete pkg[depType] + } } } const rm = (pkg, rm) => { for (const depType of new Set(saveTypeMap.values())) { - for (const name of rm) + for (const name of rm) { deleteSubKey(pkg, depType, name) + } } if (pkg.bundleDependencies) { pkg.bundleDependencies = pkg.bundleDependencies .filter(name => !rm.includes(name)) - if (!pkg.bundleDependencies.length) + if (!pkg.bundleDependencies.length) { delete pkg.bundleDependencies + } } return pkg } diff --git a/node_modules/@npmcli/arborist/lib/arborist/audit.js b/node_modules/@npmcli/arborist/lib/arborist/audit.js index bf1c335e75363..c0cd79bb13e36 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/audit.js +++ b/node_modules/@npmcli/arborist/lib/arborist/audit.js @@ -22,8 +22,9 @@ module.exports = cls => class Auditor extends cls { process.emit('time', 'audit') const tree = await this.loadVirtual() - if (this[_workspaces] && this[_workspaces].length) + if (this[_workspaces] && this[_workspaces].length) { options.filterSet = this.workspaceDependencySet(tree, this[_workspaces]) + } this.auditReport = await AuditReport.load(tree, options) const ret = options.fix ? this.reify(options) : this.auditReport process.emit('timeEnd', 'audit') diff --git a/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js index cda7f8acfb517..c45024d16e86b 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js +++ b/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js @@ -137,8 +137,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { this[_globalStyle] = this[_global] || globalStyle this[_follow] = !!follow - if (this[_workspaces].length && this[_global]) + if (this[_workspaces].length && this[_global]) { throw new Error('Cannot operate on workspaces in global mode') + } this[_explicitRequests] = new Set() this[_preferDedupe] = false @@ -168,18 +169,21 @@ module.exports = cls => class IdealTreeBuilder extends cls { // public method async buildIdealTree (options = {}) { - if (this.idealTree) + if (this.idealTree) { return Promise.resolve(this.idealTree) + } // allow the user to set reify options on the ctor as well. // XXX: deprecate separate reify() options object. options = { ...this.options, ...options } // an empty array or any falsey value is the same as null - if (!options.add || options.add.length === 0) + if (!options.add || options.add.length === 0) { options.add = null - if (!options.rm || options.rm.length === 0) + } + if (!options.rm || options.rm.length === 0) { options.rm = null + } process.emit('time', 'idealTree') @@ -230,11 +234,12 @@ module.exports = cls => class IdealTreeBuilder extends cls { [_checkEngine] (node) { const { engineStrict, npmVersion, nodeVersion } = this.options - const c = () => checkEngine(node.package, npmVersion, nodeVersion, this[_force]) + const c = () => + checkEngine(node.package, npmVersion, nodeVersion, this[_force]) - if (engineStrict) + if (engineStrict) { c() - else { + } else { try { c() } catch (er) { @@ -252,8 +257,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { : Array.isArray(options.update) ? { names: options.update } : options.update || {} - if (update.all || !Array.isArray(update.names)) + if (update.all || !Array.isArray(update.names)) { update.names = [] + } this[_complete] = !!options.complete this[_preferDedupe] = !!options.preferDedupe @@ -283,8 +289,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { : rpj(this.path + '/package.json').then( pkg => this[_rootNodeFromPackage](pkg), er => { - if (er.code === 'EJSONPARSE') + if (er.code === 'EJSONPARSE') { throw er + } return this[_rootNodeFromPackage]({}) } )) @@ -312,8 +319,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { // even though we didn't load it from a package-lock.json FILE, // we still loaded it "from disk", meaning we have to reset // dep flags before assuming that any mutations were reflected. - if (tree.children.size) + if (tree.children.size) { root.meta.loadedFromDisk = true + } } return root }) @@ -382,9 +390,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { process.emit('time', 'idealTree:userRequests') const tree = this.idealTree.target - if (!this[_workspaces].length) + if (!this[_workspaces].length) { await this[_applyUserRequestsToNode](tree, options) - else { + } else { await Promise.all(this.workspaceNodes(tree, this[_workspaces]) .map(node => this[_applyUserRequestsToNode](node, options))) } @@ -396,8 +404,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { // If we have a list of package names to update, and we know it's // going to update them wherever they are, add any paths into those // named nodes to the buildIdealTree queue. - if (!this[_global] && this[_updateNames].length) + if (!this[_global] && this[_updateNames].length) { this[_queueNamedUpdates]() + } // global updates only update the globalTop nodes, but we need to know // that they're there, and not reinstall the world unnecessarily. @@ -408,46 +417,55 @@ module.exports = cls => class IdealTreeBuilder extends cls { tree.package.dependencies = tree.package.dependencies || {} const updateName = this[_updateNames].includes(name) if (this[_updateAll] || updateName) { - if (updateName) + if (updateName) { globalExplicitUpdateNames.push(name) + } const dir = resolve(nm, name) - const st = await lstat(dir).catch(/* istanbul ignore next */ er => null) + const st = await lstat(dir) + .catch(/* istanbul ignore next */ er => null) if (st && st.isSymbolicLink()) { const target = await readlink(dir) const real = resolve(dirname(dir), target) tree.package.dependencies[name] = `file:${real}` - } else + } else { tree.package.dependencies[name] = '*' + } } } } - if (this.auditReport && this.auditReport.size > 0) + if (this.auditReport && this.auditReport.size > 0) { await this[_queueVulnDependents](options) + } const { add, rm } = options if (rm && rm.length) { addRmPkgDeps.rm(tree.package, rm) - for (const name of rm) + for (const name of rm) { this[_explicitRequests].add({ from: tree, name, action: 'DELETE' }) + } } - if (add && add.length) + if (add && add.length) { await this[_add](tree, options) + } // triggers a refresh of all edgesOut. this has to be done BEFORE // adding the edges to explicitRequests, because the package setter // resets all edgesOut. - if (add && add.length || rm && rm.length || this[_global]) + if (add && add.length || rm && rm.length || this[_global]) { tree.package = tree.package + } for (const spec of this[_resolvedAdd]) { - if (spec.tree === tree) + if (spec.tree === tree) { this[_explicitRequests].add(tree.edgesOut.get(spec.name)) + } } - for (const name of globalExplicitUpdateNames) + for (const name of globalExplicitUpdateNames) { this[_explicitRequests].add(tree.edgesOut.get(name)) + } this[_depsQueue].push(tree) } @@ -487,21 +505,24 @@ module.exports = cls => class IdealTreeBuilder extends cls { // if it's an explicit tag, we need to install that specific tag version const isTag = spec.rawSpec && spec.type === 'tag' - if (spec.name && !isTag) + if (spec.name && !isTag) { return spec + } const mani = await pacote.manifest(spec, { ...this.options }) // if it's a tag type, then we need to run it down to an actual version - if (isTag) + if (isTag) { return npa(`${mani.name}@${mani.version}`) + } spec.name = mani.name return spec } async [_updateFilePath] (spec) { - if (spec.type === 'file') + if (spec.type === 'file') { return this[_getRelpathSpec](spec, spec.fetchSpec) + } return spec } @@ -601,8 +622,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { nodesTouched.add(node) } } - for (const node of nodesTouched) + for (const node of nodesTouched) { node.package = node.package + } } } @@ -611,11 +633,13 @@ module.exports = cls => class IdealTreeBuilder extends cls { } [_avoidRange] (name) { - if (!this.auditReport) + if (!this.auditReport) { return null + } const vuln = this.auditReport.get(name) - if (!vuln) + if (!vuln) { return null + } return vuln.range } @@ -652,8 +676,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { const ancient = meta.ancientLockfile const old = meta.loadedFromDisk && !(meta.originalLockfileVersion >= 2) - if (inventory.size === 0 || !ancient && !old) + if (inventory.size === 0 || !ancient && !old) { return + } // if the lockfile is from node v5 or earlier, then we'll have to reload // all the manifests of everything we encounter. this is costly, but at @@ -672,8 +697,9 @@ This is a one-time fix-up, please be patient... this.addTracker('idealTree:inflate') const queue = [] for (const node of inventory.values()) { - if (node.isProjectRoot) + if (node.isProjectRoot) { continue + } queue.push(async () => { this.log.silly('inflate', node.location) @@ -738,8 +764,9 @@ This is a one-time fix-up, please be patient... this[_currentDep] = null } - if (!this[_depsQueue].length) + if (!this[_depsQueue].length) { return this[_resolveLinks]() + } // sort physically shallower deps up to the front of the queue, // because they'll affect things deeper in, then alphabetical @@ -757,8 +784,9 @@ This is a one-time fix-up, please be patient... // satisfied by whatever's in that file anyway. if (this[_depsSeen].has(node) || node.root !== this.idealTree || - hasShrinkwrap && !this[_complete]) + hasShrinkwrap && !this[_complete]) { return this[_buildDepStep]() + } this[_depsSeen].add(node) this[_currentDep] = node @@ -841,8 +869,9 @@ This is a one-time fix-up, please be patient... const tasks = [] const peerSource = this[_peerSetSource].get(node) || node for (const edge of this[_problemEdges](node)) { - if (edge.overridden) + if (edge.overridden) { continue + } // peerSetSource is only relevant when we have a peerEntryEdge // otherwise we're setting regular non-peer deps as if they have @@ -878,8 +907,9 @@ This is a one-time fix-up, please be patient... /* istanbul ignore next */ debug(() => { - if (!dep) + if (!dep) { throw new Error('no dep??') + } }) tasks.push({edge, dep}) @@ -912,17 +942,20 @@ This is a one-time fix-up, please be patient... visit: pd => { const { placed, edge, canPlace: cpd } = pd // if we didn't place anything, nothing to do here - if (!placed) + if (!placed) { return + } // we placed something, that means we changed the tree - if (placed.errors.length) + if (placed.errors.length) { this[_loadFailures].add(placed) + } this[_mutateTree] = true if (cpd.canPlaceSelf === OK) { for (const edgeIn of placed.edgesIn) { - if (edgeIn === edge) + if (edgeIn === edge) { continue + } const { from, valid, overridden } = edgeIn if (!overridden && !valid && !this[_depsSeen].has(from)) { this.addTracker('idealTree', from.name, from.location) @@ -936,8 +969,9 @@ This is a one-time fix-up, please be patient... // intentionally causing something to get nested which was // previously placed in this location. for (const edgeIn of placed.edgesIn) { - if (edgeIn === edge) + if (edgeIn === edge) { continue + } const { valid, overridden } = edgeIn if (!valid && !overridden) { @@ -975,8 +1009,9 @@ This is a one-time fix-up, please be patient... } for (const { to } of node.edgesOut.values()) { - if (to && to.isLink && to.target) + if (to && to.isLink && to.target) { this[_linkNodes].add(to) + } } await Promise.all(promises) @@ -1019,8 +1054,9 @@ This is a one-time fix-up, please be patient... if (required.has(edge.from) && edge.type !== 'peerOptional' || secondEdge && ( - required.has(secondEdge.from) && secondEdge.type !== 'peerOptional')) + required.has(secondEdge.from) && secondEdge.type !== 'peerOptional')) { required.add(node) + } // keep track of the thing that caused this node to be included. const src = parent.sourceReference @@ -1030,16 +1066,18 @@ This is a one-time fix-up, please be patient... // otherwise we'll be tempted to put peers as other top-level installed // things, potentially clobbering what's there already, which is not // what we want. the missing edges will be picked up on the next pass. - if (this[_global] && edge.from.isProjectRoot) + if (this[_global] && edge.from.isProjectRoot) { return node + } // otherwise, we have to make sure that our peers can go along with us. return this[_loadPeerSet](node, required) } [_virtualRoot] (node, reuse = false) { - if (reuse && this[_virtualRoots].has(node)) + if (reuse && this[_virtualRoots].has(node)) { return this[_virtualRoots].get(node) + } const vr = new Node({ path: node.realpath, @@ -1081,16 +1119,19 @@ This is a one-time fix-up, please be patient... return [...node.edgesOut.values()] .filter(edge => { // If it's included in a bundle, we take whatever is specified. - if (bundled.has(edge.name)) + if (bundled.has(edge.name)) { return false + } // If it's already been logged as a load failure, skip it. - if (edge.to && this[_loadFailures].has(edge.to)) + if (edge.to && this[_loadFailures].has(edge.to)) { return false + } // If it's shrinkwrapped, we use what the shrinkwap wants. - if (edge.to && edge.to.inShrinkwrap) + if (edge.to && edge.to.inShrinkwrap) { return false + } // If the edge has no destination, that's a problem, unless // if it's peerOptional and not explicitly requested. @@ -1100,20 +1141,24 @@ This is a one-time fix-up, please be patient... } // If the edge has an error, there's a problem. - if (!edge.valid) + if (!edge.valid) { return true + } - // If user has explicitly asked to update this package by name, it's a problem. - if (this[_updateNames].includes(edge.name)) + // user explicitly asked to update this package by name, problem + if (this[_updateNames].includes(edge.name)) { return true + } - // If we're fixing a security vulnerability with this package, it's a problem. - if (this[_isVulnerable](edge.to)) + // fixing a security vulnerability with this package, problem + if (this[_isVulnerable](edge.to)) { return true + } - // If the user has explicitly asked to install this package, it's a "problem". - if (this[_explicitRequests].has(edge)) + // user has explicitly asked to install this package, problem + if (this[_explicitRequests].has(edge)) { return true + } // No problems! return false @@ -1129,9 +1174,9 @@ This is a one-time fix-up, please be patient... // if available and valid. spec = this.idealTree.meta.checkYarnLock(spec, options) - if (this[_manifests].has(spec.raw)) + if (this[_manifests].has(spec.raw)) { return this[_manifests].get(spec.raw) - else { + } else { this.log.silly('fetch manifest', spec.raw) const p = pacote.manifest(spec, options) .then(mani => { @@ -1201,8 +1246,9 @@ This is a one-time fix-up, please be patient... for (const edge of peerEdges) { // already placed this one, and we're happy with it. - if (edge.valid && edge.to) + if (edge.valid && edge.to) { continue + } const parentEdge = node.parent.edgesOut.get(edge.name) const {isProjectRoot, isWorkspace} = node.parent.sourceReference @@ -1223,11 +1269,17 @@ This is a one-time fix-up, please be patient... // a conflict. this is always a problem in strict mode, never // in force mode, and a problem in non-strict mode if this isn't // on behalf of our project. in all such cases, we warn at least. - const dep = await this[_nodeFromEdge](parentEdge, node.parent, edge, required) + const dep = await this[_nodeFromEdge]( + parentEdge, + node.parent, + edge, + required + ) // hooray! that worked! - if (edge.valid) + if (edge.valid) { continue + } // allow it. either we're overriding, or it's not something // that will be installed by default anyway, and we'll fail when @@ -1260,8 +1312,9 @@ This is a one-time fix-up, please be patient... // isn't also required, then there's a good chance we won't need it, // so allow it for now and let it conflict if it turns out to actually // be necessary for the installation. - if (conflictOK || !required.has(edge.from)) + if (conflictOK || !required.has(edge.from)) { continue + } // ok, it's the root, or we're in unforced strict mode, so this is bad this[_failPeerConflict](edge, parentEdge) @@ -1304,15 +1357,17 @@ This is a one-time fix-up, please be patient... this[_linkNodes].delete(link) // link we never ended up placing, skip it - if (link.root !== this.idealTree) + if (link.root !== this.idealTree) { continue + } const tree = this.idealTree.target const external = !link.target.isDescendantOf(tree) // outside the root, somebody else's problem, ignore it - if (external && !this[_follow]) + if (external && !this[_follow]) { continue + } // didn't find a parent for it or it has not been seen yet // so go ahead and process it. @@ -1328,8 +1383,9 @@ This is a one-time fix-up, please be patient... } } - if (this[_depsQueue].length) + if (this[_depsQueue].length) { return this[_buildDepStep]() + } } [_fixDepFlags] () { @@ -1344,8 +1400,9 @@ This is a one-time fix-up, please be patient... // all set to true, and there can be nothing extraneous, so there's // nothing to prune, because we built it from scratch. if we didn't // add or remove anything, then also nothing to do. - if (metaFromDisk && mutateTree) + if (metaFromDisk && mutateTree) { resetDepFlags(this.idealTree) + } // update all the dev/optional/etc flags in the tree // either we started with a fresh tree, or we @@ -1353,9 +1410,9 @@ This is a one-time fix-up, please be patient... // // if we started from a blank slate, or changed something, then // the dep flags will be all set to true. - if (!metaFromDisk || mutateTree) + if (!metaFromDisk || mutateTree) { calcDepFlags(this.idealTree) - else { + } else { // otherwise just unset all the flags on the root node // since they will sometimes have the default value this.idealTree.extraneous = false @@ -1370,25 +1427,29 @@ This is a one-time fix-up, please be patient... // then the tree is suspect. Prune what is marked as extraneous. // otherwise, don't bother. const needPrune = metaFromDisk && (mutateTree || flagsSuspect) - if (this[_prune] && needPrune) + if (this[_prune] && needPrune) { this[_idealTreePrune]() + } process.emit('timeEnd', 'idealTree:fixDepFlags') } [_idealTreePrune] () { - for (const node of this.idealTree.inventory.filter(n => n.extraneous)) + for (const node of this.idealTree.inventory.filter(n => n.extraneous)) { node.parent = null + } } [_pruneFailedOptional] () { for (const node of this[_loadFailures]) { - if (!node.optional) + if (!node.optional) { throw node.errors[0] + } const set = optionalSet(node) - for (const node of set) + for (const node of set) { node.parent = null + } } } } diff --git a/node_modules/@npmcli/arborist/lib/arborist/deduper.js b/node_modules/@npmcli/arborist/lib/arborist/deduper.js index c78e42e7575d0..1741c31a19a27 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/deduper.js +++ b/node_modules/@npmcli/arborist/lib/arborist/deduper.js @@ -6,8 +6,9 @@ module.exports = cls => class Deduper extends cls { const tree = await this.loadVirtual().catch(() => this.loadActual()) const names = [] for (const name of tree.inventory.query('name')) { - if (tree.inventory.query('name', name).size > 1) + if (tree.inventory.query('name', name).size > 1) { names.push(name) + } } return this.reify({ ...options, diff --git a/node_modules/@npmcli/arborist/lib/arborist/index.js b/node_modules/@npmcli/arborist/lib/arborist/index.js index b26a26c2be2ab..d8ca67faa6065 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/index.js +++ b/node_modules/@npmcli/arborist/lib/arborist/index.js @@ -59,8 +59,9 @@ class Arborist extends Base { packumentCache: options.packumentCache || new Map(), log: options.log || procLog, } - if (options.saveType && !saveTypeMap.get(options.saveType)) + if (options.saveType && !saveTypeMap.get(options.saveType)) { throw new Error(`Invalid saveType ${options.saveType}`) + } this.cache = resolve(this.options.cache) this.path = resolve(this.options.path) process.emit('timeEnd', 'arborist:ctor') @@ -81,17 +82,20 @@ class Arborist extends Base { const dep = edge.to if (dep) { set.add(dep) - if (dep.isLink) + if (dep.isLink) { set.add(dep.target) + } } } for (const child of node.children.values()) { - if (child.extraneous) + if (child.extraneous) { extraneous.add(child) + } } } - for (const extra of extraneous) + for (const extra of extraneous) { set.add(extra) + } return set } } diff --git a/node_modules/@npmcli/arborist/lib/arborist/load-actual.js b/node_modules/@npmcli/arborist/lib/arborist/load-actual.js index 0338b2cd847b2..68e58af7d9858 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/load-actual.js +++ b/node_modules/@npmcli/arborist/lib/arborist/load-actual.js @@ -78,8 +78,9 @@ module.exports = cls => class ActualLoader extends cls { [_resetDepFlags] (tree, root) { // reset all deps to extraneous prior to recalc if (!root) { - for (const node of tree.inventory.values()) + for (const node of tree.inventory.values()) { node.extraneous = true + } } // only reset root flags if we're not re-rooting, @@ -176,8 +177,9 @@ module.exports = cls => class ActualLoader extends cls { await this[_loadFSTree](this[_actualTree]) await this[_loadWorkspaces](this[_actualTree]) await this[_loadWorkspaceTargets](this[_actualTree]) - if (!ignoreMissing) + if (!ignoreMissing) { await this[_findMissingEdges]() + } this[_findFSParents]() this[_transplant](root) @@ -200,8 +202,9 @@ module.exports = cls => class ActualLoader extends cls { // if there are workspace targets without Link nodes created, load // the targets, so that we know what they are. async [_loadWorkspaceTargets] (tree) { - if (!tree.workspaces || !tree.workspaces.size) + if (!tree.workspaces || !tree.workspaces.size) { return + } const promises = [] for (const path of tree.workspaces.values()) { @@ -215,18 +218,21 @@ module.exports = cls => class ActualLoader extends cls { } [_transplant] (root) { - if (!root || root === this[_actualTree]) + if (!root || root === this[_actualTree]) { return + } this[_actualTree][_changePath](root.path) for (const node of this[_actualTree].children.values()) { - if (!this[_transplantFilter](node)) + if (!this[_transplantFilter](node)) { node.root = null + } } root.replace(this[_actualTree]) - for (const node of this[_actualTree].fsChildren) + for (const node of this[_actualTree].fsChildren) { node.root = this[_transplantFilter](node) ? root : null + } this[_actualTree] = root } @@ -291,8 +297,9 @@ module.exports = cls => class ActualLoader extends cls { // it'll get parented later, making the fsParent scan a no-op, but better // safe than sorry, since it's cheap. const { parent, realpath } = options - if (!parent) + if (!parent) { this[_topNodes].add(realpath) + } return process.env._TEST_ARBORIST_SLOW_LINK_TARGET_ === '1' ? new Promise(res => setTimeout(() => res(new Node(options)), 100)) : new Node(options) @@ -309,8 +316,9 @@ module.exports = cls => class ActualLoader extends cls { // if a link target points at a node outside of the root tree's // node_modules hierarchy, then load that node as well. return this[_loadFSTree](link.target).then(() => link) - } else if (target.then) + } else if (target.then) { target.then(node => link.target = node) + } return link } @@ -321,13 +329,15 @@ module.exports = cls => class ActualLoader extends cls { // if a Link target has started, but not completed, then // a Promise will be in the cache to indicate this. - if (node.then) + if (node.then) { return node.then(node => this[_loadFSTree](node)) + } // impossible except in pathological ELOOP cases /* istanbul ignore if */ - if (did.has(node.realpath)) + if (did.has(node.realpath)) { return Promise.resolve(node) + } did.add(node.realpath) return this[_loadFSChildren](node) @@ -371,8 +381,11 @@ module.exports = cls => class ActualLoader extends cls { const depPromises = [] for (const [name, edge] of node.edgesOut.entries()) { - if (!edge.missing && !(edge.to && (edge.to.dummy || edge.to.parent !== node))) + const notMissing = !edge.missing && + !(edge.to && (edge.to.dummy || edge.to.parent !== node)) + if (notMissing) { continue + } // start the walk from the dirname, because we would have found // the dep in the loadFSTree step already if it was local. @@ -383,14 +396,16 @@ module.exports = cls => class ActualLoader extends cls { // allows for finding the transitive deps of link targets. // ie, if it has to go up and back out to get to the path // from the nearest common ancestor, we've gone too far. - if (ancestor && /^\.\.(?:[\\/]|$)/.test(relative(ancestor, p))) + if (ancestor && /^\.\.(?:[\\/]|$)/.test(relative(ancestor, p))) { break + } const entries = nmContents.get(p) || await readdir(p + '/node_modules').catch(() => []) nmContents.set(p, entries) - if (!entries.includes(name)) + if (!entries.includes(name)) { continue + } const d = this[_cache].has(p) ? await this[_cache].get(p) : new Node({ path: p, root: node.root, dummy: true }) diff --git a/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js b/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js index d1edcaca01d7e..fa0aa0746e11a 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js +++ b/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js @@ -40,8 +40,9 @@ module.exports = cls => class VirtualLoader extends cls { // public method async loadVirtual (options = {}) { - if (this.virtualTree) + if (this.virtualTree) { return this.virtualTree + } // allow the user to set reify options on the ctor as well. // XXX: deprecate separate reify() options object. @@ -85,18 +86,21 @@ module.exports = cls => class VirtualLoader extends cls { root.optional = false root.devOptional = false root.peer = false - } else + } else { this[flagsSuspect] = true + } this[checkRootEdges](s, root) root.meta = s this.virtualTree = root const {links, nodes} = this[resolveNodes](s, root) await this[resolveLinks](links, nodes) - if (!(s.originalLockfileVersion >= 2)) + if (!(s.originalLockfileVersion >= 2)) { this[assignBundles](nodes) - if (this[flagsSuspect]) + } + if (this[flagsSuspect]) { this[reCalcDepFlags](nodes.values()) + } return root } @@ -104,8 +108,9 @@ module.exports = cls => class VirtualLoader extends cls { // reset all dep flags // can't use inventory here, because virtualTree might not be root for (const node of nodes) { - if (node.isRoot || node === this[rootOptionProvided]) + if (node.isRoot || node === this[rootOptionProvided]) { continue + } node.extraneous = true node.dev = true node.optional = true @@ -123,8 +128,9 @@ module.exports = cls => class VirtualLoader extends cls { // loaded virtually from tree, no chance of being out of sync // ancient lockfiles are critically damaged by this process, // so we need to just hope for the best in those cases. - if (!s.loadedFromDisk || s.ancientLockfile) + if (!s.loadedFromDisk || s.ancientLockfile) { return + } const lock = s.get('') const prod = lock.dependencies || {} @@ -140,16 +146,18 @@ module.exports = cls => class VirtualLoader extends cls { } } } - for (const name of Object.keys(optional)) + for (const name of Object.keys(optional)) { delete prod[name] + } const lockWS = [] const workspaces = this[loadWorkspacesVirtual]({ cwd: this.path, lockfile: s.data, }) - for (const [name, path] of workspaces.entries()) + for (const [name, path] of workspaces.entries()) { lockWS.push(['workspace', name, `file:${path}`]) + } const lockEdges = [ ...depsToEdges('prod', prod), @@ -174,8 +182,9 @@ module.exports = cls => class VirtualLoader extends cls { for (let i = 0; i < lockEdges.length; i++) { if (rootEdges[i][0] !== lockEdges[i][0] || rootEdges[i][1] !== lockEdges[i][1] || - rootEdges[i][2] !== lockEdges[i][2]) + rootEdges[i][2] !== lockEdges[i][2]) { return this[flagsSuspect] = true + } } } @@ -185,13 +194,15 @@ module.exports = cls => class VirtualLoader extends cls { const nodes = new Map([['', root]]) for (const [location, meta] of Object.entries(s.data.packages)) { // skip the root because we already got it - if (!location) + if (!location) { continue + } - if (meta.link) + if (meta.link) { links.set(location, meta) - else + } else { nodes.set(location, this[loadNode](location, meta)) + } } return {links, nodes} } @@ -212,8 +223,9 @@ module.exports = cls => class VirtualLoader extends cls { if (!link.target.parent) { const pj = link.realpath + '/package.json' const pkg = await rpj(pj).catch(() => null) - if (pkg) + if (pkg) { link.target.package = pkg + } } } } @@ -221,12 +233,14 @@ module.exports = cls => class VirtualLoader extends cls { [assignBundles] (nodes) { for (const [location, node] of nodes) { // Skip assignment of parentage for the root package - if (!location || node.isLink && !node.target.location) + if (!location || node.isLink && !node.target.location) { continue + } const { name, parent, package: { inBundle }} = node - if (!parent) + if (!parent) { continue + } // read inBundle from package because 'package' here is // actually a v2 lockfile metadata entry. @@ -236,10 +250,11 @@ module.exports = cls => class VirtualLoader extends cls { const { package: ppkg } = parent const { inBundle: parentBundled } = ppkg if (inBundle && !parentBundled && parent.edgesOut.has(node.name)) { - if (!ppkg.bundleDependencies) + if (!ppkg.bundleDependencies) { ppkg.bundleDependencies = [name] - else + } else { ppkg.bundleDependencies.push(name) + } } } } @@ -248,8 +263,9 @@ module.exports = cls => class VirtualLoader extends cls { const p = this.virtualTree ? this.virtualTree.realpath : this.path const path = resolve(p, location) // shrinkwrap doesn't include package name unless necessary - if (!sw.name) + if (!sw.name) { sw.name = nameFromFolder(path) + } const dev = sw.dev const optional = sw.optional diff --git a/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js b/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js index 93d078415f585..0a7965ae30ca1 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js +++ b/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js @@ -7,15 +7,17 @@ const _loadWorkspacesVirtual = Symbol.for('loadWorkspacesVirtual') module.exports = cls => class MapWorkspaces extends cls { [_appendWorkspaces] (node, workspaces) { - if (node && workspaces.size) + if (node && workspaces.size) { node.workspaces = workspaces + } return node } async [_loadWorkspaces] (node) { - if (node.workspaces) + if (node.workspaces) { return node + } const workspaces = await mapWorkspaces({ cwd: node.path, diff --git a/node_modules/@npmcli/arborist/lib/arborist/rebuild.js b/node_modules/@npmcli/arborist/lib/arborist/rebuild.js index 8e447bb8f5ad1..743794f4bda51 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/rebuild.js +++ b/node_modules/@npmcli/arborist/lib/arborist/rebuild.js @@ -61,8 +61,9 @@ module.exports = cls => class Builder extends cls { async rebuild ({ nodes, handleOptionalFailure = false } = {}) { // nothing to do if we're not building anything! - if (this[_ignoreScripts] && !this[_binLinks]) + if (this[_ignoreScripts] && !this[_binLinks]) { return + } // when building for the first time, as part of reify, we ignore // failures in optional nodes, and just delete them. however, when @@ -76,8 +77,9 @@ module.exports = cls => class Builder extends cls { if (this[_workspaces] && this[_workspaces].length) { const filterSet = this.workspaceDependencySet(tree, this[_workspaces]) nodes = tree.inventory.filter(node => filterSet.has(node)) - } else + } else { nodes = tree.inventory.values() + } } // separates links nodes so that it can run @@ -88,10 +90,11 @@ module.exports = cls => class Builder extends cls { for (const node of nodes) { // we skip the target nodes to that workspace in order to make sure // we only run lifecycle scripts / place bin links once per workspace - if (node.isLink) + if (node.isLink) { linkNodes.add(node) - else + } else { depNodes.add(node) + } } await this[_build](depNodes, {}) @@ -118,17 +121,20 @@ module.exports = cls => class Builder extends cls { process.emit('time', `build:${type}`) await this[_buildQueues](nodes) - if (!this[_ignoreScripts]) + if (!this[_ignoreScripts]) { await this[_runScripts]('preinstall') - if (this[_binLinks] && type !== 'links') + } + if (this[_binLinks] && type !== 'links') { await this[_linkAllBins]() + } // links should also run prepare scripts and only link bins after that if (type === 'links') { await this[_runScripts]('prepare') - if (this[_binLinks]) + if (this[_binLinks]) { await this[_linkAllBins]() + } } if (!this[_ignoreScripts]) { @@ -173,8 +179,9 @@ module.exports = cls => class Builder extends cls { const { preinstall, install, postinstall, prepare } = scripts const tests = { bin, preinstall, install, postinstall, prepare } for (const [key, has] of Object.entries(tests)) { - if (has) + if (has) { this[_queues][key].push(node) + } } } process.emit('timeEnd', 'build:queue') @@ -186,15 +193,17 @@ module.exports = cls => class Builder extends cls { // the node path. Otherwise a package can have a preinstall script // that unlinks something, to allow them to silently overwrite system // binaries, which is unsafe and insecure. - if (!node.globalTop || this[_force]) + if (!node.globalTop || this[_force]) { return + } const { path, package: pkg } = node await binLinks.checkBins({ pkg, path, top: true, global: true }) } async [_addToBuildSet] (node, set, refreshed = false) { - if (set.has(node)) + if (set.has(node)) { return + } if (this[_oldMeta] === null) { const {root: {meta}} = node @@ -233,8 +242,9 @@ module.exports = cls => class Builder extends cls { await isNodeGypPackage(node.path) if (bin || preinstall || install || postinstall || prepare || isGyp) { - if (bin) + if (bin) { await this[_checkBins](node) + } if (isGyp) { scripts.install = defaultGypInstallScript node.package.scripts = scripts @@ -246,8 +256,9 @@ module.exports = cls => class Builder extends cls { async [_runScripts] (event) { const queue = this[_queues][event] - if (!queue.length) + if (!queue.length) { return + } process.emit('time', `build:run:${event}`) const stdio = this.options.foregroundScripts ? 'inherit' : 'pipe' @@ -266,8 +277,9 @@ module.exports = cls => class Builder extends cls { } = node.target // skip any that we know we'll be deleting - if (this[_trashList].has(path)) + if (this[_trashList].has(path)) { return + } const timer = `build:run:${event}:${location}` process.emit('time', timer) @@ -321,23 +333,26 @@ module.exports = cls => class Builder extends cls { async [_linkAllBins] () { const queue = this[_queues].bin - if (!queue.length) + if (!queue.length) { return + } process.emit('time', 'build:link') const promises = [] // sort the queue by node path, so that the module-local collision // detector in bin-links will always resolve the same way. - for (const node of queue.sort(sortNodes)) + for (const node of queue.sort(sortNodes)) { promises.push(this[_createBinLinks](node)) + } await promiseAllRejectLate(promises) process.emit('timeEnd', 'build:link') } async [_createBinLinks] (node) { - if (this[_trashList].has(node.path)) + if (this[_trashList].has(node.path)) { return + } process.emit('time', `build:link:${node.location}`) diff --git a/node_modules/@npmcli/arborist/lib/arborist/reify.js b/node_modules/@npmcli/arborist/lib/arborist/reify.js index 965435f84fb41..3a9c479748864 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/reify.js +++ b/node_modules/@npmcli/arborist/lib/arborist/reify.js @@ -158,8 +158,9 @@ module.exports = cls => class Reifier extends cls { async [_validatePath] () { // don't create missing dirs on dry runs - if (this[_packageLockOnly] || this[_dryRun]) + if (this[_packageLockOnly] || this[_dryRun]) { return + } // we do NOT want to set ownership on this folder, especially // recursively, because it can have other side effects to do that @@ -172,8 +173,9 @@ module.exports = cls => class Reifier extends cls { async [_reifyPackages] () { // we don't submit the audit report or write to disk on dry runs - if (this[_dryRun]) + if (this[_dryRun]) { return + } if (this[_packageLockOnly]) { // we already have the complete tree, so just audit it now, @@ -220,8 +222,9 @@ module.exports = cls => class Reifier extends cls { for (const action of actions) { try { await this[action]() - if (reifyTerminated) + if (reifyTerminated) { throw reifyTerminated + } } catch (er) { await this[rollback](er) /* istanbul ignore next - rollback throws, should never hit this */ @@ -233,8 +236,9 @@ module.exports = cls => class Reifier extends cls { // no rollback for this one, just exit with the error, since the // install completed and can't be safely recovered at this point. await this[_removeTrash]() - if (reifyTerminated) + if (reifyTerminated) { throw reifyTerminated + } // done modifying the file system, no need to keep listening for sigs removeHandler() @@ -261,18 +265,21 @@ module.exports = cls => class Reifier extends cls { filter: (node, kid) => { // if it's not the project root, and we have no explicit requests, // then we're already into a nested dep, so we keep it - if (this.explicitRequests.size === 0 || !node.isProjectRoot) + if (this.explicitRequests.size === 0 || !node.isProjectRoot) { return true + } // if we added it as an edgeOut, then we want it - if (this.idealTree.edgesOut.has(kid)) + if (this.idealTree.edgesOut.has(kid)) { return true + } // if it's an explicit request, then we want it const hasExplicit = [...this.explicitRequests] .some(edge => edge.name === kid) - if (hasExplicit) + if (hasExplicit) { return true + } // ignore the rest of the global install folder return false @@ -280,8 +287,10 @@ module.exports = cls => class Reifier extends cls { } : { ignoreMissing: true } if (!this[_global]) { - return Promise.all([this.loadActual(actualOpt), this.buildIdealTree(bitOpt)]) - .then(() => process.emit('timeEnd', 'reify:loadTrees')) + return Promise.all([ + this.loadActual(actualOpt), + this.buildIdealTree(bitOpt), + ]).then(() => process.emit('timeEnd', 'reify:loadTrees')) } // the global install space tends to have a lot of stuff in it. don't @@ -295,8 +304,9 @@ module.exports = cls => class Reifier extends cls { } [_diffTrees] () { - if (this[_packageLockOnly]) + if (this[_packageLockOnly]) { return + } process.emit('time', 'reify:diffTrees') // XXX if we have an existing diff already, there should be a way @@ -311,20 +321,24 @@ module.exports = cls => class Reifier extends cls { // children where there's an explicit request. for (const { name } of this.explicitRequests) { const ideal = idealTree.children.get(name) - if (ideal) + if (ideal) { filterNodes.push(ideal) + } const actual = actualTree.children.get(name) - if (actual) + if (actual) { filterNodes.push(actual) + } } } else { for (const ws of this[_workspaces]) { const ideal = this.idealTree.children.get(ws) - if (ideal) + if (ideal) { filterNodes.push(ideal) + } const actual = this.actualTree.children.get(ws) - if (actual) + if (actual) { filterNodes.push(actual) + } } } @@ -360,8 +374,9 @@ module.exports = cls => class Reifier extends cls { const retired = retirePath(path) moves[path] = retired this[_trashList].add(retired) - } else + } else { this[_trashList].add(path) + } } } @@ -393,10 +408,11 @@ module.exports = cls => class Reifier extends cls { if (er.code === 'ENOENT') { return didMkdirp ? null : mkdirp(dirname(to)).then(() => this[_renamePath](from, to, true)) - } else if (er.code === 'EEXIST') + } else if (er.code === 'EEXIST') { return rimraf(to).then(() => moveFile(from, to)) - else + } else { throw er + } }) } @@ -417,8 +433,9 @@ module.exports = cls => class Reifier extends cls { // adding to the trash list will skip reifying, and delete them // if they are currently in the tree and otherwise untouched. [_addOmitsToTrashList] () { - if (!this[_omitDev] && !this[_omitOptional] && !this[_omitPeer]) + if (!this[_omitDev] && !this[_omitOptional] && !this[_omitPeer]) { return + } process.emit('time', 'reify:trashOmits') @@ -429,8 +446,9 @@ module.exports = cls => class Reifier extends cls { node.optional && this[_omitOptional] || node.devOptional && this[_omitOptional] && this[_omitDev]) - for (const node of this.idealTree.inventory.filter(filter)) + for (const node of this.idealTree.inventory.filter(filter)) { this[_addNodeToTrashList](node) + } process.emit('timeEnd', 'reify:trashOmits') } @@ -452,10 +470,12 @@ module.exports = cls => class Reifier extends cls { const dirsChecked = new Set() return promiseAllRejectLate(leaves.map(async node => { for (const d of walkUp(node.path)) { - if (d === node.top.path) + if (d === node.top.path) { break - if (dirsChecked.has(d)) + } + if (dirsChecked.has(d)) { continue + } dirsChecked.add(d) const st = await lstat(d).catch(er => null) // this can happen if we have a link to a package with a name @@ -487,8 +507,9 @@ module.exports = cls => class Reifier extends cls { .map(path => rimraf(path).catch(er => failures.push([path, er]))) return promiseAllRejectLate(unlinks) .then(() => { - if (failures.length) + if (failures.length) { this.log.warn('cleanup', 'Failed to remove some directories', failures) + } }) .then(() => process.emit('timeEnd', 'reify:rollback:createSparse')) .then(() => this[_rollbackRetireShallowNodes](er)) @@ -504,8 +525,9 @@ module.exports = cls => class Reifier extends cls { d.ideal.hasShrinkwrap && !seen.has(d.ideal) && !this[_trashList].has(d.ideal.path)) - if (!shrinkwraps.length) + if (!shrinkwraps.length) { return + } process.emit('time', 'reify:loadShrinkwraps') @@ -535,8 +557,9 @@ module.exports = cls => class Reifier extends cls { // to the trash list // Always return the node. [_reifyNode] (node) { - if (this[_trashList].has(node.path)) + if (this[_trashList].has(node.path)) { return node + } const timer = `reifyNode:${node.location}` process.emit('time', timer) @@ -569,8 +592,9 @@ module.exports = cls => class Reifier extends cls { // do not allow node_modules to be a symlink async [_validateNodeModules] (nm) { - if (this[_force] || this[_nmValidated].has(nm)) + if (this[_force] || this[_nmValidated].has(nm)) { return + } const st = await lstat(nm).catch(() => null) if (!st || st.isDirectory()) { this[_nmValidated].add(nm) @@ -642,8 +666,9 @@ module.exports = cls => class Reifier extends cls { [_warnDeprecated] (node) { const {_id, deprecated} = node.package - if (deprecated) + if (deprecated) { this.log.warn('deprecated', `${_id}: ${deprecated}`) + } } // if the node is optional, then the failure of the promise is nonfatal @@ -677,8 +702,9 @@ module.exports = cls => class Reifier extends cls { [_loadBundlesAndUpdateTrees] ( depth = 0, bundlesByDepth = this[_getBundlesByDepth]() ) { - if (depth === 0) + if (depth === 0) { process.emit('time', 'reify:loadBundles') + } const maxBundleDepth = bundlesByDepth.get('maxBundleDepth') if (depth > maxBundleDepth) { @@ -698,8 +724,9 @@ module.exports = cls => class Reifier extends cls { node.target !== node.root && !this[_trashList].has(node.path)) - if (!set.length) + if (!set.length) { return this[_loadBundlesAndUpdateTrees](depth + 1, bundlesByDepth) + } // extract all the nodes with bundles return promiseAllRejectLate(set.map(node => { @@ -725,12 +752,14 @@ module.exports = cls => class Reifier extends cls { // it's actually in the bundle if it gets transplanted notTransplanted.delete(node.name) return true - } else + } else { return false + } }, }) - for (const name of notTransplanted) + for (const name of notTransplanted) { this[_bundleMissing].add(node.children.get(name)) + } }))) // move onto the next level of bundled items .then(() => this[_loadBundlesAndUpdateTrees](depth + 1, bundlesByDepth)) @@ -743,18 +772,21 @@ module.exports = cls => class Reifier extends cls { tree: this.diff, visit: diff => { const node = diff.ideal - if (!node) + if (!node) { return - if (node.isProjectRoot) + } + if (node.isProjectRoot) { return + } const { bundleDependencies } = node.package if (bundleDependencies && bundleDependencies.length) { maxBundleDepth = Math.max(maxBundleDepth, node.depth) - if (!bundlesByDepth.has(node.depth)) + if (!bundlesByDepth.has(node.depth)) { bundlesByDepth.set(node.depth, [node]) - else + } else { bundlesByDepth.get(node.depth).push(node) + } } }, getChildren: diff => diff.children, @@ -791,13 +823,15 @@ module.exports = cls => class Reifier extends cls { // create the list of nodes shadowed by children of bundlers for (const bundles of bundlesByDepth.values()) { // skip the 'maxBundleDepth' item - if (!Array.isArray(bundles)) + if (!Array.isArray(bundles)) { continue + } for (const node of bundles) { for (const name of node.children.keys()) { const shadow = node.parent.resolve(name) - if (!shadow) + if (!shadow) { continue + } bundleShadowed.add(shadow) shadow.extraneous = true } @@ -851,8 +885,9 @@ module.exports = cls => class Reifier extends cls { } [_submitQuickAudit] () { - if (this.options.audit === false) + if (this.options.audit === false) { return this.auditReport = null + } // we submit the quick audit at this point in the process, as soon as // we have all the deps resolved, so that it can overlap with the other @@ -865,8 +900,9 @@ module.exports = cls => class Reifier extends cls { const tree = this.idealTree // if we're operating on a workspace, only audit the workspace deps - if (this[_workspaces] && this[_workspaces].length) + if (this[_workspaces] && this[_workspaces].length) { options.filterSet = this.workspaceDependencySet(tree, this[_workspaces]) + } this.auditReport = AuditReport.load(tree, options) .then(res => { @@ -891,8 +927,9 @@ module.exports = cls => class Reifier extends cls { tree: this.diff, visit: diff => { // no unpacking if we don't want to change this thing - if (diff.action !== 'CHANGE' && diff.action !== 'ADD') + if (diff.action !== 'CHANGE' && diff.action !== 'ADD') { return + } const node = diff.ideal const bd = this[_bundleUnpacked].has(node) @@ -902,13 +939,18 @@ module.exports = cls => class Reifier extends cls { // check whether we still need to unpack this one. // test the inDepBundle last, since that's potentially a tree walk. const doUnpack = node && // can't unpack if removed! - !node.isRoot && // root node already exists - !bd && // already unpacked to read bundle - !sw && // already unpacked to read sw - (bundleMissing || !node.inDepBundle) // already unpacked by another dep's bundle - - if (doUnpack) + // root node already exists + !node.isRoot && + // already unpacked to read bundle + !bd && + // already unpacked to read sw + !sw && + // already unpacked by another dep's bundle + (bundleMissing || !node.inDepBundle) + + if (doUnpack) { unpacks.push(this[_reifyNode](node)) + } }, getChildren: diff => diff.children, }) @@ -933,8 +975,9 @@ module.exports = cls => class Reifier extends cls { this[_retiredUnchanged] = {} return promiseAllRejectLate(this.diff.children.map(diff => { // skip if nothing was retired - if (diff.action !== 'CHANGE' && diff.action !== 'REMOVE') + if (diff.action !== 'CHANGE' && diff.action !== 'REMOVE') { return + } const { path: realFolder } = diff.actual const retireFolder = moves[realFolder] @@ -955,12 +998,14 @@ module.exports = cls => class Reifier extends cls { this[_retiredUnchanged][retireFolder] = [] return promiseAllRejectLate(diff.unchanged.map(node => { // no need to roll back links, since we'll just delete them anyway - if (node.isLink) + if (node.isLink) { return mkdirp(dirname(node.path)).then(() => this[_reifyNode](node)) + } // will have been moved/unpacked along with bundler - if (node.inDepBundle && !this[_bundleMissing].has(node)) + if (node.inDepBundle && !this[_bundleMissing].has(node)) { return + } this[_retiredUnchanged][retireFolder].push(node) @@ -1014,8 +1059,9 @@ module.exports = cls => class Reifier extends cls { dfwalk({ tree: this.diff, leave: diff => { - if (!diff.ideal.isProjectRoot) + if (!diff.ideal.isProjectRoot) { nodes.push(diff.ideal) + } }, // process adds before changes, ignore removals getChildren: diff => diff && diff.children, @@ -1030,8 +1076,9 @@ module.exports = cls => class Reifier extends cls { // skip links that only live within node_modules as they are most // likely managed by packages we installed, we only want to rebuild // unchanged links we directly manage - if (node.isLink && node.target.fsTop === tree) + if (node.isLink && node.target.fsTop === tree) { nodes.push(node) + } } return this.rebuild({ nodes, handleOptionalFailure: true }) @@ -1048,12 +1095,14 @@ module.exports = cls => class Reifier extends cls { const failures = [] const rm = path => rimraf(path).catch(er => failures.push([path, er])) - for (const path of this[_trashList]) + for (const path of this[_trashList]) { promises.push(rm(path)) + } return promiseAllRejectLate(promises).then(() => { - if (failures.length) + if (failures.length) { this.log.warn('cleanup', 'Failed to remove some directories', failures) + } }) .then(() => process.emit('timeEnd', 'reify:trash')) } @@ -1067,8 +1116,9 @@ module.exports = cls => class Reifier extends cls { // save it first, then prune out the optional trash, and then return it. // support save=false option - if (options.save === false || this[_global] || this[_dryRun]) + if (options.save === false || this[_global] || this[_dryRun]) { return false + } process.emit('time', 'reify:save') @@ -1089,6 +1139,14 @@ module.exports = cls => class Reifier extends cls { const spec = subSpec ? subSpec.rawSpec : rawSpec const child = edge.to + // if we tried to install an optional dep, but it was a version + // that we couldn't resolve, this MAY be missing. if we haven't + // blown up by now, it's because it was not a problem, though, so + // just move on. + if (!child) { + continue + } + let newSpec if (req.registry) { const version = child.version @@ -1105,8 +1163,9 @@ module.exports = cls => class Reifier extends cls { !isRange || spec === '*' || subset(prefixRange, spec, { loose: true }) - ) + ) { range = prefixRange + } const pname = child.packageName const alias = name !== pname @@ -1115,10 +1174,11 @@ module.exports = cls => class Reifier extends cls { // save the git+https url if it has auth, otherwise shortcut const h = req.hosted const opt = { noCommittish: false } - if (h.https && h.auth) + if (h.https && h.auth) { newSpec = `git+${h.https(opt)}` - else + } else { newSpec = h.shortcut(opt) + } } else if (req.type === 'directory' || req.type === 'file') { // save the relative path in package.json // Normally saveSpec is updated with the proper relative @@ -1128,34 +1188,41 @@ module.exports = cls => class Reifier extends cls { const p = req.fetchSpec.replace(/^file:/, '') const rel = relpath(addTree.realpath, p) newSpec = `file:${rel}` - } else + } else { newSpec = req.saveSpec + } if (options.saveType) { const depType = saveTypeMap.get(options.saveType) pkg[depType][name] = newSpec // rpj will have moved it here if it was in both // if it is empty it will be deleted later - if (options.saveType === 'prod' && pkg.optionalDependencies) + if (options.saveType === 'prod' && pkg.optionalDependencies) { delete pkg.optionalDependencies[name] + } } else { - if (hasSubKey(pkg, 'dependencies', name)) + if (hasSubKey(pkg, 'dependencies', name)) { pkg.dependencies[name] = newSpec + } if (hasSubKey(pkg, 'devDependencies', name)) { pkg.devDependencies[name] = newSpec // don't update peer or optional if we don't have to - if (hasSubKey(pkg, 'peerDependencies', name) && !intersects(newSpec, pkg.peerDependencies[name])) + if (hasSubKey(pkg, 'peerDependencies', name) && !intersects(newSpec, pkg.peerDependencies[name])) { pkg.peerDependencies[name] = newSpec + } - if (hasSubKey(pkg, 'optionalDependencies', name) && !intersects(newSpec, pkg.optionalDependencies[name])) + if (hasSubKey(pkg, 'optionalDependencies', name) && !intersects(newSpec, pkg.optionalDependencies[name])) { pkg.optionalDependencies[name] = newSpec + } } else { - if (hasSubKey(pkg, 'peerDependencies', name)) + if (hasSubKey(pkg, 'peerDependencies', name)) { pkg.peerDependencies[name] = newSpec + } - if (hasSubKey(pkg, 'optionalDependencies', name)) + if (hasSubKey(pkg, 'optionalDependencies', name)) { pkg.optionalDependencies[name] = newSpec + } } } @@ -1196,8 +1263,9 @@ module.exports = cls => class Reifier extends cls { } // grab any from explicitRequests that had deps removed - for (const { from: tree } of this.explicitRequests) + for (const { from: tree } of this.explicitRequests) { updatedTrees.add(tree) + } for (const tree of updatedTrees) { // refresh the edges so they have the correct specs @@ -1211,8 +1279,9 @@ module.exports = cls => class Reifier extends cls { } async [_saveLockFile] (saveOpt) { - if (!this[_usePackageLock]) + if (!this[_usePackageLock]) { return + } const { meta } = this.idealTree @@ -1224,8 +1293,9 @@ module.exports = cls => class Reifier extends cls { for (const path of this[_trashList]) { const loc = relpath(this.idealTree.realpath, path) const node = this.idealTree.inventory.get(loc) - if (node && node.root === this.idealTree) + if (node && node.root === this.idealTree) { node.parent = null + } } // if we filtered to only certain nodes, then anything ELSE needs @@ -1244,54 +1314,60 @@ module.exports = cls => class Reifier extends cls { // if it's an ideal node from the filter set, then skip it // because we already made whatever changes were necessary - if (filterSet.has(ideal)) + if (filterSet.has(ideal)) { continue + } // otherwise, if it's not in the actualTree, then it's not a thing // that we actually added. And if it IS in the actualTree, then // it's something that we left untouched, so we need to record // that. const actual = this.actualTree.inventory.get(loc) - if (!actual) + if (!actual) { ideal.root = null - else { + } else { if ([...actual.linksIn].some(link => filterSet.has(link))) { seen.add(actual.location) continue } const { realpath, isLink } = actual - if (isLink && ideal.isLink && ideal.realpath === realpath) + if (isLink && ideal.isLink && ideal.realpath === realpath) { continue - else + } else { reroot.add(actual) + } } } // now find any actual nodes that may not be present in the ideal // tree, but were left behind by virtue of not being in the filter for (const [loc, actual] of this.actualTree.inventory.entries()) { - if (seen.has(loc)) + if (seen.has(loc)) { continue + } seen.add(loc) // we know that this is something that ISN'T in the idealTree, // or else we will have addressed it in the previous loop. // If it's in the filterSet, that means we intentionally removed // it, so nothing to do here. - if (filterSet.has(actual)) + if (filterSet.has(actual)) { continue + } reroot.add(actual) } // go through the rerooted actual nodes, and move them over. - for (const actual of reroot) + for (const actual of reroot) { actual.root = this.idealTree + } // prune out any tops that lack a linkIn, they are no longer relevant. for (const top of this.idealTree.tops) { - if (top.linksIn.size === 0) + if (top.linksIn.size === 0) { top.root = null + } } // need to calculate dep flags, since nodes may have been marked @@ -1307,7 +1383,8 @@ module.exports = cls => class Reifier extends cls { this.actualTree = this.idealTree this.idealTree = null - if (!this[_global]) + if (!this[_global]) { await this.actualTree.meta.save() + } } } diff --git a/node_modules/@npmcli/arborist/lib/audit-report.js b/node_modules/@npmcli/arborist/lib/audit-report.js index 8f7d6546d64f4..2e6c207b33eb3 100644 --- a/node_modules/@npmcli/arborist/lib/audit-report.js +++ b/node_modules/@npmcli/arborist/lib/audit-report.js @@ -63,8 +63,9 @@ class AuditReport extends Map { prod = false } } - if (prod) + if (prod) { dependencies.prod++ + } } // if it doesn't have any topVulns, then it's fixable with audit fix @@ -104,8 +105,9 @@ class AuditReport extends Map { async run () { this.report = await this[_getReport]() this.log.silly('audit report', this.report) - if (this.report) + if (this.report) { await this[_init]() + } return this } @@ -119,8 +121,9 @@ class AuditReport extends Map { const promises = [] for (const [name, advisories] of Object.entries(this.report)) { - for (const advisory of advisories) + for (const advisory of advisories) { promises.push(this.calculator.calculate(name, advisory)) + } } // now the advisories are calculated with a set of versions @@ -136,43 +139,51 @@ class AuditReport extends Map { // adding multiple advisories with the same range is fine, but no // need to search for nodes we already would have added. const k = `${name}@${range}` - if (seen.has(k)) + if (seen.has(k)) { continue + } seen.add(k) const vuln = this.get(name) || new Vuln({ name, advisory }) - if (this.has(name)) + if (this.has(name)) { vuln.addAdvisory(advisory) + } super.set(name, vuln) const p = [] for (const node of this.tree.inventory.query('packageName', name)) { - if (!shouldAudit(node, this[_omit], this.filterSet)) + if (!shouldAudit(node, this[_omit], this.filterSet)) { continue + } // if not vulnerable by this advisory, keep searching - if (!advisory.testVersion(node.version)) + if (!advisory.testVersion(node.version)) { continue + } // we will have loaded the source already if this is a metavuln - if (advisory.type === 'metavuln') + if (advisory.type === 'metavuln') { vuln.addVia(this.get(advisory.dependency)) + } // already marked this one, no need to do it again - if (vuln.nodes.has(node)) + if (vuln.nodes.has(node)) { continue + } // haven't marked this one yet. get its dependents. vuln.nodes.add(node) for (const { from: dep, spec } of node.edgesIn) { - if (dep.isTop && !vuln.topNodes.has(dep)) + if (dep.isTop && !vuln.topNodes.has(dep)) { this[_checkTopNode](dep, vuln, spec) - else { + } else { // calculate a metavuln, if necessary - p.push(this.calculator.calculate(dep.packageName, advisory).then(meta => { - if (meta.testVersion(dep.version, spec)) + const calc = this.calculator.calculate(dep.packageName, advisory) + p.push(calc.then(meta => { + if (meta.testVersion(dep.version, spec)) { advisories.add(meta) + } })) } } @@ -193,9 +204,11 @@ class AuditReport extends Map { // the nodes it references, then remove it from the advisory list. // happens when using omit with old audit endpoint. for (const advisory of vuln.advisories) { - const relevant = [...vuln.nodes].some(n => advisory.testVersion(n.version)) - if (!relevant) + const relevant = [...vuln.nodes] + .some(n => advisory.testVersion(n.version)) + if (!relevant) { vuln.deleteAdvisory(advisory) + } } } process.emit('timeEnd', 'auditReport:init') @@ -221,18 +234,21 @@ class AuditReport extends Map { // this will always be set to at least {name, versions:{}} const paku = vuln.packument - if (!vuln.testSpec(spec)) + if (!vuln.testSpec(spec)) { return true + } // similarly, even if we HAVE a packument, but we're looking for it // somewhere other than the registry, and we got something vulnerable, // then we're stuck with it. const specObj = npa(spec) - if (!specObj.registry) + if (!specObj.registry) { return false + } - if (specObj.subSpec) + if (specObj.subSpec) { spec = specObj.subSpec.rawSpec + } // We don't provide fixes for top nodes other than root, but we // still check to see if the node is fixable with a different version, @@ -287,8 +303,9 @@ class AuditReport extends Map { async [_getReport] () { // if we're not auditing, just return false - if (this.options.audit === false || this.tree.inventory.size === 1) + if (this.options.audit === false || this.tree.inventory.size === 1) { return null + } process.emit('time', 'auditReport:getReport') try { @@ -299,8 +316,9 @@ class AuditReport extends Map { // no sense asking if we don't have anything to audit, // we know it'll be empty - if (!Object.keys(body).length) + if (!Object.keys(body).length) { return null + } const res = await fetch('/-/npm/v1/security/advisories/bulk', { ...this.options, @@ -353,13 +371,15 @@ const prepareBulkData = (tree, omit, filterSet) => { for (const name of tree.inventory.query('packageName')) { const set = new Set() for (const node of tree.inventory.query('packageName', name)) { - if (!shouldAudit(node, omit, filterSet)) + if (!shouldAudit(node, omit, filterSet)) { continue + } set.add(node.version) } - if (set.size) + if (set.size) { payload[name] = [...set] + } } return payload } diff --git a/node_modules/@npmcli/arborist/lib/calc-dep-flags.js b/node_modules/@npmcli/arborist/lib/calc-dep-flags.js index 968fc83c5136c..95ecc8a617b08 100644 --- a/node_modules/@npmcli/arborist/lib/calc-dep-flags.js +++ b/node_modules/@npmcli/arborist/lib/calc-dep-flags.js @@ -11,7 +11,8 @@ const calcDepFlags = (tree, resetRoot = true) => { tree, visit: node => calcDepFlagsStep(node), filter: node => node, - getChildren: (node, tree) => [...tree.edgesOut.values()].map(edge => edge.to), + getChildren: (node, tree) => + [...tree.edgesOut.values()].map(edge => edge.to), }) return ret } @@ -39,8 +40,9 @@ const calcDepFlagsStep = (node) => { node.edgesOut.forEach(({peer, optional, dev, to}) => { // if the dep is missing, then its flags are already maximally unset - if (!to) + if (!to) { return + } // everything with any kind of edge into it is not extraneous to.extraneous = false @@ -59,28 +61,34 @@ const calcDepFlagsStep = (node) => { !node.optional && !optional const unsetPeer = !node.peer && !peer - if (unsetPeer) + if (unsetPeer) { unsetFlag(to, 'peer') + } - if (unsetDevOpt) + if (unsetDevOpt) { unsetFlag(to, 'devOptional') + } - if (unsetDev) + if (unsetDev) { unsetFlag(to, 'dev') + } - if (unsetOpt) + if (unsetOpt) { unsetFlag(to, 'optional') + } }) return node } const resetParents = (node, flag) => { - if (node[flag]) + if (node[flag]) { return + } - for (let p = node; p && (p === node || p[flag]); p = p.resolveParent) + for (let p = node; p && (p === node || p[flag]); p = p.resolveParent) { p[flag] = false + } } // typically a short walk, since it only traverses deps that @@ -92,8 +100,9 @@ const unsetFlag = (node, flag) => { tree: node, visit: node => { node.extraneous = node[flag] = false - if (node.isLink) + if (node.isLink) { node.target.extraneous = node.target[flag] = false + } }, getChildren: node => [...node.target.edgesOut.values()] .filter(edge => edge.to && edge.to[flag] && diff --git a/node_modules/@npmcli/arborist/lib/can-place-dep.js b/node_modules/@npmcli/arborist/lib/can-place-dep.js index 9601ad7af3163..7e2e1a0e2d29b 100644 --- a/node_modules/@npmcli/arborist/lib/can-place-dep.js +++ b/node_modules/@npmcli/arborist/lib/can-place-dep.js @@ -64,14 +64,17 @@ class CanPlaceDep { } = options debug(() => { - if (!dep) + if (!dep) { throw new Error('no dep provided to CanPlaceDep') + } - if (!target) + if (!target) { throw new Error('no target provided to CanPlaceDep') + } - if (!edge) + if (!edge) { throw new Error('no edge provided to CanPlaceDep') + } this._treeSnapshot = JSON.stringify([...target.root.inventory.entries()] .map(([loc, {packageName, version, resolved}]) => { @@ -108,8 +111,9 @@ class CanPlaceDep { this.edgeOverride = !dep.satisfies(edge) this.canPlace = this.checkCanPlace() - if (!this.canPlaceSelf) + if (!this.canPlaceSelf) { this.canPlaceSelf = this.canPlace + } debug(() => { const treeSnapshot = JSON.stringify([...target.root.inventory.entries()] @@ -131,15 +135,18 @@ class CanPlaceDep { // if the dep failed to load, we're going to fail the build or // prune it out anyway, so just move forward placing/replacing it. - if (dep.errors.length) + if (dep.errors.length) { return current ? REPLACE : OK + } // cannot place peers inside their dependents, except for tops - if (targetEdge && targetEdge.peer && !target.isTop) + if (targetEdge && targetEdge.peer && !target.isTop) { return CONFLICT + } - if (targetEdge && !dep.satisfies(targetEdge) && targetEdge !== this.edge) + if (targetEdge && !dep.satisfies(targetEdge) && targetEdge !== this.edge) { return CONFLICT + } return current ? this.checkCanPlaceCurrent() : this.checkCanPlaceNoCurrent() } @@ -150,8 +157,9 @@ class CanPlaceDep { const { preferDedupe, explicitRequest, current, target, edge, dep } = this if (dep.matches(current)) { - if (current.satisfies(edge) || this.edgeOverride) + if (current.satisfies(edge) || this.edgeOverride) { return explicitRequest ? REPLACE : KEEP + } } const { version: curVer } = current @@ -163,19 +171,22 @@ class CanPlaceDep { * but it is theoretically possible if peer deps are pinned. In * that case we treat it like any other conflict, and keep trying */ const cpp = this.canPlacePeers(REPLACE) - if (cpp !== CONFLICT) + if (cpp !== CONFLICT) { return cpp + } } // ok, can't replace the current with new one, but maybe current is ok? - if (current.satisfies(edge) && (!explicitRequest || preferDedupe)) + if (current.satisfies(edge) && (!explicitRequest || preferDedupe)) { return KEEP + } // if we prefer deduping, then try replacing newer with older if (preferDedupe && !tryReplace && dep.canReplace(current)) { const cpp = this.canPlacePeers(REPLACE) - if (cpp !== CONFLICT) + if (cpp !== CONFLICT) { return cpp + } } // Check for interesting cases! @@ -185,29 +196,33 @@ class CanPlaceDep { const myDeepest = this.deepestNestingTarget // ok, i COULD be placed deeper, so leave the current one alone. - if (target !== myDeepest) + if (target !== myDeepest) { return CONFLICT + } // if we are not checking a peerDep, then we MUST place it here, in the // target that has a non-peer dep on it. - if (!edge.peer && target === edge.from) + if (!edge.peer && target === edge.from) { return this.canPlacePeers(REPLACE) + } // if we aren't placing a peer in a set, then we're done here. // This is ignored because it SHOULD be redundant, as far as I can tell, // with the deepest target and target===edge.from tests. But until we // can prove that isn't possible, this condition is here for safety. /* istanbul ignore if - allegedly impossible */ - if (!this.parent && !edge.peer) + if (!this.parent && !edge.peer) { return CONFLICT + } // check the deps in the peer group for each edge into that peer group // if ALL of them can be pushed deeper, or if it's ok to replace its // members with the contents of the new peer group, then we're good. let canReplace = true for (const [entryEdge, currentPeers] of peerEntrySets(current)) { - if (entryEdge === this.edge || entryEdge === this.peerEntryEdge) + if (entryEdge === this.edge || entryEdge === this.peerEntryEdge) { continue + } // First, see if it's ok to just replace the peerSet entirely. // we do this by walking out from the entryEdge, because in a case like @@ -231,8 +246,9 @@ class CanPlaceDep { const entryNode = entryEdge.to const entryRep = dep.parent.children.get(entryNode.name) if (entryRep) { - if (entryRep.canReplace(entryNode, dep.parent.children.keys())) + if (entryRep.canReplace(entryNode, dep.parent.children.keys())) { continue + } } let canClobber = !entryRep @@ -240,12 +256,14 @@ class CanPlaceDep { const peerReplacementWalk = new Set([entryNode]) OUTER: for (const currentPeer of peerReplacementWalk) { for (const edge of currentPeer.edgesOut.values()) { - if (!edge.peer || !edge.valid) + if (!edge.peer || !edge.valid) { continue + } const rep = dep.parent.children.get(edge.name) if (!rep) { - if (edge.to) + if (edge.to) { peerReplacementWalk.add(edge.to) + } continue } if (!rep.satisfies(edge)) { @@ -255,14 +273,16 @@ class CanPlaceDep { } } } - if (canClobber) + if (canClobber) { continue + } // ok, we can't replace, but maybe we can nest the current set deeper? let canNestCurrent = true for (const currentPeer of currentPeers) { - if (!canNestCurrent) + if (!canNestCurrent) { break + } // still possible to nest this peerSet const curDeep = deepestNestingTarget(entryEdge.from, currentPeer.name) @@ -270,14 +290,16 @@ class CanPlaceDep { canNestCurrent = false canReplace = false } - if (canNestCurrent) + if (canNestCurrent) { continue + } } } // if we can nest or replace all the current peer groups, we can replace. - if (canReplace) + if (canReplace) { return this.canPlacePeers(REPLACE) + } return CONFLICT } @@ -293,8 +315,9 @@ class CanPlaceDep { if (current) { for (const edge of current.edgesIn.values()) { if (edge.from.isDescendantOf(target) && edge.valid) { - if (!dep.satisfies(edge)) + if (!dep.satisfies(edge)) { return CONFLICT + } } } } @@ -316,8 +339,9 @@ class CanPlaceDep { get allChildren () { const set = new Set(this.children) for (const child of set) { - for (const grandchild of child.children) + for (const grandchild of child.children) { set.add(grandchild) + } } return [...set] } @@ -329,15 +353,17 @@ class CanPlaceDep { // check if peers can go here. returns state or CONFLICT canPlacePeers (state) { this.canPlaceSelf = state - if (this._canPlacePeers) + if (this._canPlacePeers) { return this._canPlacePeers + } // TODO: represent peerPath in ERESOLVE error somehow? const peerPath = [...this.peerPath, this.dep] let sawConflict = false for (const peerEdge of this.dep.edgesOut.values()) { - if (!peerEdge.peer || !peerEdge.to || peerPath.includes(peerEdge.to)) + if (!peerEdge.peer || !peerEdge.to || peerPath.includes(peerEdge.to)) { continue + } const peer = peerEdge.to // it may be the case that the *initial* dep can be nested, but a peer // of that dep needs to be placed shallower, because the target has @@ -354,13 +380,15 @@ class CanPlaceDep { }) /* istanbul ignore next */ debug(() => { - if (this.children.some(c => c.dep === cpp.dep)) + if (this.children.some(c => c.dep === cpp.dep)) { throw new Error('checking same dep repeatedly') + } }) this.children.push(cpp) - if (cpp.canPlace === CONFLICT) + if (cpp.canPlace === CONFLICT) { sawConflict = true + } } this._canPlacePeers = sawConflict ? CONFLICT : state diff --git a/node_modules/@npmcli/arborist/lib/case-insensitive-map.js b/node_modules/@npmcli/arborist/lib/case-insensitive-map.js index 8254c3f7a55e9..016ce6017b01e 100644 --- a/node_modules/@npmcli/arborist/lib/case-insensitive-map.js +++ b/node_modules/@npmcli/arborist/lib/case-insensitive-map.js @@ -10,8 +10,9 @@ module.exports = class Map extends OGMap { constructor (items = []) { super() this[_keys] = new OGMap() - for (const [key, val] of items) + for (const [key, val] of items) { this.set(key, val) + } } [_normKey] (key) { @@ -26,8 +27,9 @@ module.exports = class Map extends OGMap { set (key, val) { const normKey = this[_normKey](key) - if (this[_keys].has(normKey)) + if (this[_keys].has(normKey)) { super.delete(this[_keys].get(normKey)) + } this[_keys].set(normKey, key) return super.set(key, val) } diff --git a/node_modules/@npmcli/arborist/lib/consistent-resolve.js b/node_modules/@npmcli/arborist/lib/consistent-resolve.js index 3227648241901..e34e40a46d002 100644 --- a/node_modules/@npmcli/arborist/lib/consistent-resolve.js +++ b/node_modules/@npmcli/arborist/lib/consistent-resolve.js @@ -5,8 +5,9 @@ const npa = require('npm-package-arg') const relpath = require('./relpath.js') const consistentResolve = (resolved, fromPath, toPath, relPaths = false) => { - if (!resolved) + if (!resolved) { return null + } try { const hostedOpt = { noCommittish: false } diff --git a/node_modules/@npmcli/arborist/lib/deepest-nesting-target.js b/node_modules/@npmcli/arborist/lib/deepest-nesting-target.js index 9c433a7652da2..2c6647f5db7ba 100644 --- a/node_modules/@npmcli/arborist/lib/deepest-nesting-target.js +++ b/node_modules/@npmcli/arborist/lib/deepest-nesting-target.js @@ -5,11 +5,13 @@ const deepestNestingTarget = (start, name) => { for (const target of start.ancestry()) { // note: this will skip past the first target if edge is peer - if (target.isProjectRoot || !target.resolveParent || target.globalTop) + if (target.isProjectRoot || !target.resolveParent || target.globalTop) { return target + } const targetEdge = target.edgesOut.get(name) - if (!targetEdge || !targetEdge.peer) + if (!targetEdge || !targetEdge.peer) { return target + } } } diff --git a/node_modules/@npmcli/arborist/lib/dep-valid.js b/node_modules/@npmcli/arborist/lib/dep-valid.js index 01e5e21e94ce5..d80437f20c8e4 100644 --- a/node_modules/@npmcli/arborist/lib/dep-valid.js +++ b/node_modules/@npmcli/arborist/lib/dep-valid.js @@ -44,8 +44,9 @@ const depValid = (child, requested, requestor) => { switch (requested.type) { case 'range': - if (requested.fetchSpec === '*') + if (requested.fetchSpec === '*') { return true + } // fallthrough case 'version': // if it's a version or a range other than '*', semver it @@ -108,17 +109,20 @@ const depValid = (child, requested, requestor) => { } const tarballValid = (child, requested, requestor) => { - if (child.isLink) + if (child.isLink) { return false + } - if (child.resolved) + if (child.resolved) { return child.resolved.replace(/\\/g, '/') === `file:${requested.fetchSpec.replace(/\\/g, '/')}` + } // if we have a legacy mutated package.json file. we can't be 100% // sure that it resolved to the same file, but if it was the same // request, that's a pretty good indicator of sameness. - if (child.package._requested) + if (child.package._requested) { return child.package._requested.saveSpec === requested.saveSpec + } // ok, we're probably dealing with some legacy cruft here, not much // we can do at this point unfortunately. diff --git a/node_modules/@npmcli/arborist/lib/diff.js b/node_modules/@npmcli/arborist/lib/diff.js index 2008ef7a35bdd..0d17bde9583ac 100644 --- a/node_modules/@npmcli/arborist/lib/diff.js +++ b/node_modules/@npmcli/arborist/lib/diff.js @@ -31,7 +31,12 @@ class Diff { this.removed = [] } - static calculate ({actual, ideal, filterNodes = [], shrinkwrapInflated = new Set()}) { + static calculate ({ + actual, + ideal, + filterNodes = [], + shrinkwrapInflated = new Set(), + }) { // if there's a filterNode, then: // - get the path from the root to the filterNode. The root or // root.target should have an edge either to the filterNode or @@ -43,8 +48,9 @@ class Diff { const extraneous = new Set() for (const filterNode of filterNodes) { const { root } = filterNode - if (root !== ideal && root !== actual) + if (root !== ideal && root !== actual) { throw new Error('invalid filterNode: outside idealTree/actualTree') + } const rootTarget = root.target const edge = [...rootTarget.edgesOut.values()].filter(e => { return e.to && (e.to === filterNode || e.to.target === filterNode) @@ -73,8 +79,9 @@ class Diff { : [...actualNode.edgesOut.values()].filter(e => e.to).map(e => e.to) if (actualNode) { for (const child of actualNode.children.values()) { - if (child.extraneous) + if (child.extraneous) { extraneous.add(child) + } } } @@ -82,8 +89,9 @@ class Diff { }, }) } - for (const extra of extraneous) + for (const extra of extraneous) { filterSet.add(extra) + } return depth({ tree: new Diff({actual, ideal, filterSet, shrinkwrapInflated}), @@ -94,23 +102,27 @@ class Diff { } const getAction = ({actual, ideal}) => { - if (!ideal) + if (!ideal) { return 'REMOVE' + } // bundled meta-deps are copied over to the ideal tree when we visit it, // so they'll appear to be missing here. There's no need to handle them // in the diff, though, because they'll be replaced at reify time anyway // Otherwise, add the missing node. - if (!actual) + if (!actual) { return ideal.inDepBundle ? null : 'ADD' + } // always ignore the root node - if (ideal.isRoot && actual.isRoot) + if (ideal.isRoot && actual.isRoot) { return null + } // if the versions don't match, it's a change no matter what - if (ideal.version !== actual.version) + if (ideal.version !== actual.version) { return 'CHANGE' + } const binsExist = ideal.binPaths.every((path) => existsSync(path)) @@ -125,33 +137,38 @@ const getAction = ({actual, ideal}) => { const noIntegrity = !ideal.integrity && !actual.integrity const noResolved = !ideal.resolved && !actual.resolved const resolvedMatch = ideal.resolved && ideal.resolved === actual.resolved - if (noIntegrity && binsExist && (resolvedMatch || noResolved)) + if (noIntegrity && binsExist && (resolvedMatch || noResolved)) { return null + } // otherwise, verify that it's the same bits // note that if ideal has integrity, and resolved doesn't, we treat // that as a 'change', so that it gets re-fetched and locked down. const integrityMismatch = !ideal.integrity || !actual.integrity || !ssri.parse(ideal.integrity).match(actual.integrity) - if (integrityMismatch || !binsExist) + if (integrityMismatch || !binsExist) { return 'CHANGE' + } return null } const allChildren = node => { - if (!node) + if (!node) { return new Map() + } // if the node is root, and also a link, then what we really // want is to traverse the target's children - if (node.isRoot && node.isLink) + if (node.isRoot && node.isLink) { return allChildren(node.target) + } const kids = new Map() for (const n of [node, ...node.fsChildren]) { - for (const kid of n.children.values()) + for (const kid of n.children.values()) { kids.set(kid.path, kid) + } } return kids } @@ -160,7 +177,14 @@ const allChildren = node => { // to create the diff tree const getChildren = diff => { const children = [] - const {actual, ideal, unchanged, removed, filterSet, shrinkwrapInflated} = diff + const { + actual, + ideal, + unchanged, + removed, + filterSet, + shrinkwrapInflated, + } = diff // Note: we DON'T diff fsChildren themselves, because they are either // included in the package contents, or part of some other project, and @@ -182,26 +206,45 @@ const getChildren = diff => { for (const path of paths) { const actual = actualKids.get(path) const ideal = idealKids.get(path) - diffNode(actual, ideal, children, unchanged, removed, filterSet, shrinkwrapInflated) + diffNode({ + actual, + ideal, + children, + unchanged, + removed, + filterSet, + shrinkwrapInflated, + }) } - if (diff.leaves && !children.length) + if (diff.leaves && !children.length) { diff.leaves.push(diff) + } return children } -const diffNode = (actual, ideal, children, unchanged, removed, filterSet, shrinkwrapInflated) => { - if (filterSet.size && !(filterSet.has(ideal) || filterSet.has(actual))) +const diffNode = ({ + actual, + ideal, + children, + unchanged, + removed, + filterSet, + shrinkwrapInflated, +}) => { + if (filterSet.size && !(filterSet.has(ideal) || filterSet.has(actual))) { return + } const action = getAction({actual, ideal}) // if it's a match, then get its children // otherwise, this is the child diff node if (action || (!shrinkwrapInflated.has(ideal) && ideal.hasShrinkwrap)) { - if (action === 'REMOVE') + if (action === 'REMOVE') { removed.push(actual) + } children.push(new Diff({actual, ideal, filterSet, shrinkwrapInflated})) } else { unchanged.push(ideal) @@ -227,13 +270,22 @@ const diffNode = (actual, ideal, children, unchanged, removed, filterSet, shrink if (actual && bd && bd.length) { const bundledChildren = [] for (const node of actual.children.values()) { - if (node.inBundle) + if (node.inBundle) { bundledChildren.push(node) + } } - for (const node of bundledChildren) + for (const node of bundledChildren) { node.parent = ideal + } } - children.push(...getChildren({actual, ideal, unchanged, removed, filterSet, shrinkwrapInflated})) + children.push(...getChildren({ + actual, + ideal, + unchanged, + removed, + filterSet, + shrinkwrapInflated, + })) } } diff --git a/node_modules/@npmcli/arborist/lib/edge.js b/node_modules/@npmcli/arborist/lib/edge.js index 9d5ece40e5fae..777ecc44a7c00 100644 --- a/node_modules/@npmcli/arborist/lib/edge.js +++ b/node_modules/@npmcli/arborist/lib/edge.js @@ -45,22 +45,26 @@ class Edge { constructor (options) { const { type, name, spec, accept, from } = options - if (typeof spec !== 'string') + if (typeof spec !== 'string') { throw new TypeError('must provide string spec') + } - if (type === 'workspace' && npa(spec).type !== 'directory') + if (type === 'workspace' && npa(spec).type !== 'directory') { throw new TypeError('workspace edges must be a symlink') + } this[_spec] = spec if (accept !== undefined) { - if (typeof accept !== 'string') + if (typeof accept !== 'string') { throw new TypeError('accept field must be a string if provided') + } this[_accept] = accept || '*' } - if (typeof name !== 'string') + if (typeof name !== 'string') { throw new TypeError('must provide dependency name') + } this[_name] = name if (!types.has(type)) { @@ -69,20 +73,23 @@ class Edge { `(valid types are: ${Edge.types.join(', ')})`) } this[_type] = type - if (!from) + if (!from) { throw new TypeError('must provide "from" node') + } this[_setFrom](from) this[_error] = this[_loadError]() this.overridden = false } satisfiedBy (node) { - return node.name === this.name && depValid(node, this.spec, this.accept, this.from) + return node.name === this.name && + depValid(node, this.spec, this.accept, this.from) } explain (seen = []) { - if (this[_explanation]) + if (this[_explanation]) { return this[_explanation] + } return this[_explanation] = this[_explain](seen) } @@ -101,8 +108,9 @@ class Edge { } get bundled () { - if (!this.from) + if (!this.from) { return false + } const { package: { bundleDependencies = [] } } = this.from return bundleDependencies.includes(this.name) } @@ -175,20 +183,24 @@ class Edge { this[_explanation] = null const newTo = this[_from].resolve(this.name) if (newTo !== this[_to]) { - if (this[_to]) + if (this[_to]) { this[_to].edgesIn.delete(this) + } this[_to] = newTo this[_error] = this[_loadError]() - if (this[_to]) + if (this[_to]) { this[_to].addEdgeIn(this) - } else if (hard) + } + } else if (hard) { this[_error] = this[_loadError]() + } } detach () { this[_explanation] = null - if (this[_to]) + if (this[_to]) { this[_to].edgesIn.delete(this) + } this[_from].edgesOut.delete(this.name) this[_to] = null this[_error] = 'DETACHED' @@ -198,8 +210,9 @@ class Edge { [_setFrom] (node) { this[_explanation] = null this[_from] = node - if (node.edgesOut.has(this.name)) + if (node.edgesOut.has(this.name)) { node.edgesOut.get(this.name).detach() + } node.addEdgeOut(this) this.reload() } diff --git a/node_modules/@npmcli/arborist/lib/gather-dep-set.js b/node_modules/@npmcli/arborist/lib/gather-dep-set.js index 1dc9a0b188eaa..2c85a640fddfb 100644 --- a/node_modules/@npmcli/arborist/lib/gather-dep-set.js +++ b/node_modules/@npmcli/arborist/lib/gather-dep-set.js @@ -14,8 +14,9 @@ const gatherDepSet = (set, edgeFilter) => { // as the deps set increases in size. for (const node of deps) { for (const edge of node.edgesOut.values()) { - if (edge.to && edgeFilter(edge)) + if (edge.to && edgeFilter(edge)) { deps.add(edge.to) + } } } diff --git a/node_modules/@npmcli/arborist/lib/inventory.js b/node_modules/@npmcli/arborist/lib/inventory.js index a4ae11c2ab41e..34b6f98a8b286 100644 --- a/node_modules/@npmcli/arborist/lib/inventory.js +++ b/node_modules/@npmcli/arborist/lib/inventory.js @@ -13,11 +13,13 @@ const debug = require('./debug.js') const getLicense = pkg => { if (pkg) { const lic = pkg.license || pkg.licence - if (lic) + if (lic) { return lic + } const lics = pkg.licenses || pkg.licences - if (Array.isArray(lics)) + if (Array.isArray(lics)) { return lics[0] + } } } @@ -42,8 +44,9 @@ class Inventory extends Map { * filter (fn) { for (const node of this.values()) { - if (fn(node)) + if (fn(node)) { yield node + } } } @@ -62,8 +65,9 @@ class Inventory extends Map { const current = super.get(node[this.primaryKey]) if (current) { - if (current === node) + if (current === node) { return + } this.delete(current) } super.set(node[this.primaryKey], node) @@ -85,8 +89,9 @@ class Inventory extends Map { } delete (node) { - if (!this.has(node)) + if (!this.has(node)) { return + } super.delete(node[this.primaryKey]) for (const [key, map] of this[_index].entries()) { @@ -95,8 +100,9 @@ class Inventory extends Map { const set = map.get(val) if (set) { set.delete(node) - if (set.size === 0) + if (set.size === 0) { map.delete(node[key]) + } } } } diff --git a/node_modules/@npmcli/arborist/lib/link.js b/node_modules/@npmcli/arborist/lib/link.js index 4d15428d87360..0289e04151ef5 100644 --- a/node_modules/@npmcli/arborist/lib/link.js +++ b/node_modules/@npmcli/arborist/lib/link.js @@ -11,8 +11,9 @@ class Link extends Node { constructor (options) { const { root, realpath, target, parent, fsParent } = options - if (!realpath && !(target && target.path)) + if (!realpath && !(target && target.path)) { throw new TypeError('must provide realpath for Link node') + } super({ ...options, @@ -23,11 +24,11 @@ class Link extends Node { : null), }) - if (target) + if (target) { this.target = target - else if (this.realpath === this.root.path) + } else if (this.realpath === this.root.path) { this.target = this.root - else { + } else { this.target = new Node({ ...options, path: realpath, @@ -48,8 +49,9 @@ class Link extends Node { set target (target) { const current = this[_target] - if (target === current) + if (target === current) { return + } if (current && current.then) { debug(() => { @@ -72,25 +74,28 @@ class Link extends Node { } if (!target) { - if (current && current.linksIn) + if (current && current.linksIn) { current.linksIn.delete(this) + } if (this.path) { this[_delistFromMeta]() this[_target] = null this.package = {} this[_refreshLocation]() - } else + } else { this[_target] = null + } return } if (!this.path) { // temp node pending assignment to a tree // we know it's not in the inventory yet, because no path. - if (target.path) + if (target.path) { this.realpath = target.path - else + } else { target.path = target.realpath = this.realpath + } target.root = this.root this[_target] = target target.linksIn.add(this) diff --git a/node_modules/@npmcli/arborist/lib/node.js b/node_modules/@npmcli/arborist/lib/node.js index 5616019dd9cc2..a872f24805b59 100644 --- a/node_modules/@npmcli/arborist/lib/node.js +++ b/node_modules/@npmcli/arborist/lib/node.js @@ -120,8 +120,9 @@ class Node { // should be equal if not a link this.path = path ? resolve(path) : null - if (!this.name && (!this.path || this.path !== dirname(this.path))) + if (!this.name && (!this.path || this.path !== dirname(this.path))) { throw new TypeError('could not detect node name from path or package') + } this.realpath = !this.isLink ? this.path : resolve(realpath) @@ -142,8 +143,9 @@ class Node { // // Otherwise, hopefully a shrinkwrap will help us out. const resolved = consistentResolve(pkg._resolved) - if (resolved && !(/^file:/.test(resolved) && pkg._where)) + if (resolved && !(/^file:/.test(resolved) && pkg._where)) { this.resolved = resolved + } } this.integrity = integrity || pkg._integrity || null this.hasShrinkwrap = hasShrinkwrap || pkg._hasShrinkwrap || false @@ -215,18 +217,21 @@ class Node { // see parent/root setters below. // root is set to parent's root if we have a parent, otherwise if it's // null, then it's set to the node itself. - if (!parent && !fsParent) + if (!parent && !fsParent) { this.root = root || null + } // mostly a convenience for testing, but also a way to create // trees in a more declarative way than setting parent on each if (children) { - for (const c of children) + for (const c of children) { new Node({ ...c, parent: this }) + } } if (fsChildren) { - for (const c of fsChildren) + for (const c of fsChildren) { new Node({ ...c, fsParent: this }) + } } // now load all the dep edges @@ -239,8 +244,9 @@ class Node { set meta (meta) { this[_meta] = meta - if (meta) + if (meta) { meta.add(this) + } } get global () { @@ -260,8 +266,9 @@ class Node { // deletes edges if they already exists if (this[_workspaces]) { for (const name of this[_workspaces].keys()) { - if (!workspaces.has(name)) + if (!workspaces.has(name)) { this.edgesOut.get(name).detach() + } } } @@ -271,8 +278,9 @@ class Node { } get binPaths () { - if (!this.parent) + if (!this.parent) { return [] + } return getBinPaths({ pkg: this[_package], @@ -319,8 +327,9 @@ class Node { // only do this more than once at the root level, so the resolve() calls // are only one level deep, and there's not much to be saved, anyway. // simpler to just toss them all out. - for (const edge of this.edgesOut.values()) + for (const edge of this.edgesOut.values()) { edge.detach() + } this[_explanation] = null /* istanbul ignore next - should be impossible */ @@ -341,8 +350,9 @@ class Node { // node.explain(nodes seen already, edge we're trying to satisfy // if edge is not specified, it lists every edge into the node. explain (edge = null, seen = []) { - if (this[_explanation]) + if (this[_explanation]) { return this[_explanation] + } return this[_explanation] = this[_explain](edge, seen) } @@ -374,11 +384,13 @@ class Node { } } - if (this.sourceReference) + if (this.sourceReference) { return this.sourceReference.explain(edge, seen) + } - if (seen.includes(this)) + if (seen.includes(this)) { return why + } why.location = this.location why.isWorkspace = this.isWorkspace @@ -387,56 +399,64 @@ class Node { seen = seen.concat(this) why.dependents = [] - if (edge) + if (edge) { why.dependents.push(edge.explain(seen)) - else { + } else { // ignore invalid edges, since those aren't satisfied by this thing, // and are not keeping it held in this spot anyway. const edges = [] for (const edge of this.edgesIn) { - if (!edge.valid && !edge.from.isProjectRoot) + if (!edge.valid && !edge.from.isProjectRoot) { continue + } edges.push(edge) } - for (const edge of edges) + for (const edge of edges) { why.dependents.push(edge.explain(seen)) + } } - if (this.linksIn.size) + if (this.linksIn.size) { why.linksIn = [...this.linksIn].map(link => link[_explain](edge, seen)) + } return why } isDescendantOf (node) { for (let p = this; p; p = p.resolveParent) { - if (p === node) + if (p === node) { return true + } } return false } getBundler (path = []) { // made a cycle, definitely not bundled! - if (path.includes(this)) + if (path.includes(this)) { return null + } path.push(this) const parent = this[_parent] - if (!parent) + if (!parent) { return null + } const pBundler = parent.getBundler(path) - if (pBundler) + if (pBundler) { return pBundler + } const ppkg = parent.package const bd = ppkg && ppkg.bundleDependencies // explicit bundling - if (Array.isArray(bd) && bd.includes(this.name)) + if (Array.isArray(bd) && bd.includes(this.name)) { return parent + } // deps that are deduped up to the bundling level are bundled. // however, if they get their dep met further up than that, @@ -444,11 +464,13 @@ class Node { // unmet bundled deps will not cause your deps to be bundled. for (const edge of this.edgesIn) { const eBundler = edge.from.getBundler(path) - if (!eBundler) + if (!eBundler) { continue + } - if (eBundler === parent) + if (eBundler === parent) { return eBundler + } } return null @@ -467,8 +489,9 @@ class Node { } get isWorkspace () { - if (this.isProjectRoot) + if (this.isProjectRoot) { return false + } const { root } = this const { type, to } = root.edgesOut.get(this.packageName) || {} return type === 'workspace' && to && (to.target === this || to === this) @@ -486,15 +509,17 @@ class Node { } * ancestry () { - for (let anc = this; anc; anc = anc.resolveParent) + for (let anc = this; anc; anc = anc.resolveParent) { yield anc + } } set root (root) { // setting to null means this is the new root // should only ever be one step - while (root && root.root !== root) + while (root && root.root !== root) { root = root.root + } root = root || this @@ -504,8 +529,9 @@ class Node { // can't set the root (yet) if there's no way to determine location // this allows us to do new Node({...}) and then set the root later. // just make the assignment so we don't lose it, and move on. - if (!this.path || !root.realpath || !root.path) + if (!this.path || !root.realpath || !root.path) { return this[_root] = root + } // temporarily become a root node this[_root] = this @@ -521,8 +547,9 @@ class Node { if (this.isLink) { if (target) { target.linksIn.delete(this) - if (target.root === this) + if (target.root === this) { target[_delistFromMeta]() + } } this[_target] = null } @@ -539,16 +566,17 @@ class Node { this[_fsParent] = null } - if (root === this) + if (root === this) { this[_refreshLocation]() - else { + } else { // setting to some different node. const loc = relpath(root.realpath, this.path) const current = root.inventory.get(loc) // clobber whatever is there now - if (current) + if (current) { current.root = null + } this[_root] = root // set this.location and add to inventory @@ -556,8 +584,9 @@ class Node { // try to find our parent/fsParent in the new root inventory for (const p of walkUp(dirname(this.path))) { - if (p === this.path) + if (p === this.path) { continue + } const ploc = relpath(root.realpath, p) const parent = root.inventory.get(ploc) if (parent) { @@ -576,8 +605,9 @@ class Node { const isParent = this.location === childLoc if (isParent) { const oldChild = parent.children.get(this.name) - if (oldChild && oldChild !== this) + if (oldChild && oldChild !== this) { oldChild.root = null + } if (this.parent) { this.parent.children.delete(this.name) this.parent[_reloadNamedEdges](this.name) @@ -586,13 +616,15 @@ class Node { this[_parent] = parent // don't do it for links, because they don't have a target yet // we'll hit them up a bit later on. - if (!this.isLink) + if (!this.isLink) { parent[_reloadNamedEdges](this.name) + } } else { /* istanbul ignore if - should be impossible, since we break * all fsParent/child relationships when moving? */ - if (this.fsParent) + if (this.fsParent) { this.fsParent.fsChildren.delete(this) + } parent.fsChildren.add(this) this[_fsParent] = parent } @@ -601,10 +633,11 @@ class Node { } // if it doesn't have a parent, it's a top node - if (!this.parent) + if (!this.parent) { root.tops.add(this) - else + } else { root.tops.delete(this) + } // assign parentage for any nodes that need to have this as a parent // this can happen when we have a node at nm/a/nm/b added *before* @@ -614,24 +647,30 @@ class Node { const nmloc = `${this.location}${this.location ? '/' : ''}node_modules/` const isChild = n => n.location === nmloc + n.name // check dirname so that /foo isn't treated as the fsparent of /foo-bar - const isFsChild = n => dirname(n.path).startsWith(this.path) && - n !== this && - !n.parent && - (!n.fsParent || n.fsParent === this || dirname(this.path).startsWith(n.fsParent.path)) + const isFsChild = n => { + return dirname(n.path).startsWith(this.path) && + n !== this && + !n.parent && + (!n.fsParent || + n.fsParent === this || + dirname(this.path).startsWith(n.fsParent.path)) + } const isKid = n => isChild(n) || isFsChild(n) // only walk top nodes, since anything else already has a parent. for (const child of root.tops) { - if (!isKid(child)) + if (!isKid(child)) { continue + } // set up the internal parentage links - if (this.isLink) + if (this.isLink) { child.root = null - else { + } else { // can't possibly have a parent, because it's in tops - if (child.fsParent) + if (child.fsParent) { child.fsParent.fsChildren.delete(child) + } child[_fsParent] = null if (isChild(child)) { this.children.set(child.name, child) @@ -648,13 +687,15 @@ class Node { // to that realpath, or a thing at that realpath if we're adding a link // (if we're adding a regular node, we already deleted the old one) for (const node of root.inventory.query('realpath', this.realpath)) { - if (node === this) + if (node === this) { continue + } /* istanbul ignore next - should be impossible */ debug(() => { - if (node.root !== root) + if (node.root !== root) { throw new Error('inventory contains node from other root') + } }) if (this.isLink) { @@ -663,8 +704,9 @@ class Node { this[_package] = target.package target.linksIn.add(this) // reload edges here, because now we have a target - if (this.parent) + if (this.parent) { this.parent[_reloadNamedEdges](this.name) + } break } else { /* istanbul ignore else - should be impossible */ @@ -672,8 +714,9 @@ class Node { node[_target] = this node[_package] = this.package this.linksIn.add(node) - if (node.parent) + if (node.parent) { node.parent[_reloadNamedEdges](node.name) + } } else { debug(() => { throw Object.assign(new Error('duplicate node in root setter'), { @@ -690,14 +733,16 @@ class Node { // reload all edgesIn where the root doesn't match, so we don't have // cross-tree dependency graphs for (const edge of this.edgesIn) { - if (edge.from.root !== root) + if (edge.from.root !== root) { edge.reload() + } } // reload all edgesOut where root doens't match, or is missing, since // it might not be missing in the new tree for (const edge of this.edgesOut.values()) { - if (!edge.to || edge.to.root !== root) + if (!edge.to || edge.to.root !== root) { edge.reload() + } } // now make sure our family comes along for the ride! @@ -721,15 +766,17 @@ class Node { } } for (const child of family) { - if (child.root !== root) + if (child.root !== root) { child.root = root + } } // if we had a target, and didn't find one in the new root, then bring // it over as well, but only if we're setting the link into a new root, // as we don't want to lose the target any time we remove a link. - if (this.isLink && target && !this.target && root !== this) + if (this.isLink && target && !this.target && root !== this) { target.root = root + } // tree should always be valid upon root setter completion. treeCheck(this) @@ -741,11 +788,13 @@ class Node { } [_loadWorkspaces] () { - if (!this[_workspaces]) + if (!this[_workspaces]) { return + } - for (const [name, path] of this[_workspaces].entries()) + for (const [name, path] of this[_workspaces].entries()) { new Edge({ from: this, name, spec: `file:${path}`, type: 'workspace' }) + } } [_loadDeps] () { @@ -764,10 +813,11 @@ class Node { const peerDependencies = {} const peerOptional = {} for (const [name, dep] of Object.entries(pd)) { - if (pm[name] && pm[name].optional) + if (pm[name] && pm[name].optional) { peerOptional[name] = dep - else + } else { peerDependencies[name] = dep + } } this[_loadDepType](peerDependencies, 'peer') this[_loadDepType](peerOptional, 'peerOptional') @@ -784,8 +834,9 @@ class Node { } = sourceReference || {} const thisDev = isTop && !globalTop && path const srcDev = !sourceReference || srcTop && !srcGlobalTop && srcPath - if (thisDev && srcDev) + if (thisDev && srcDev) { this[_loadDepType](this.package.devDependencies, 'dev') + } } [_loadDepType] (deps, type) { @@ -794,8 +845,9 @@ class Node { // prioritize a new edge over an existing one for (const [name, spec] of Object.entries(deps || {})) { const current = this.edgesOut.get(name) - if (!current || current.type !== 'workspace') + if (!current || current.type !== 'workspace') { new Edge({ from: this, name, spec, accept: ad[name], type }) + } } } @@ -803,25 +855,29 @@ class Node { const parent = this[_fsParent] /* istanbul ignore next - should be impossible */ debug(() => { - if (parent === this) + if (parent === this) { throw new Error('node set to its own fsParent') + } }) return parent } set fsParent (fsParent) { if (!fsParent) { - if (this[_fsParent]) + if (this[_fsParent]) { this.root = null + } return } debug(() => { - if (fsParent === this) + if (fsParent === this) { throw new Error('setting node to its own fsParent') + } - if (fsParent.realpath === this.realpath) + if (fsParent.realpath === this.realpath) { throw new Error('setting fsParent to same path') + } // the initial set MUST be an actual walk-up from the realpath // subsequent sets will re-root on the new fsParent's path. @@ -837,16 +893,19 @@ class Node { } }) - if (fsParent.isLink) + if (fsParent.isLink) { fsParent = fsParent.target + } // setting a thing to its own fsParent is not normal, but no-op for safety - if (this === fsParent || fsParent.realpath === this.realpath) + if (this === fsParent || fsParent.realpath === this.realpath) { return + } // nothing to do - if (this[_fsParent] === fsParent) + if (this[_fsParent] === fsParent) { return + } const oldFsParent = this[_fsParent] const newPath = !oldFsParent ? this.path @@ -874,11 +933,13 @@ class Node { } // update this.path/realpath for this and all children/fsChildren - if (pathChange) + if (pathChange) { this[_changePath](newPath) + } - if (oldParent) + if (oldParent) { oldParent[_reloadNamedEdges](oldName) + } // clobbers anything at that path, resets all appropriate references this.root = fsParent.root @@ -894,11 +955,13 @@ class Node { // will go ahead and create the invalid state, and then try to resolve // it with more tree construction, because it's a user request. canReplaceWith (node, ignorePeers = []) { - if (node.name !== this.name) + if (node.name !== this.name) { return false + } - if (node.packageName !== this.packageName) + if (node.packageName !== this.packageName) { return false + } ignorePeers = new Set(ignorePeers) @@ -915,12 +978,14 @@ class Node { edge.from.parent === this.parent && edge.peer && ignorePeers.has(edge.from.name) - if (ignored) + if (ignored) { continue + } // only care about edges that don't originate from this node - if (!depSet.has(edge.from) && !edge.satisfiedBy(node)) + if (!depSet.has(edge.from) && !edge.satisfiedBy(node)) { return false + } } return true @@ -935,41 +1000,49 @@ class Node { // to if it was removed, or nothing is depending on it in the first place. canDedupe (preferDedupe = false) { // not allowed to mess with shrinkwraps or bundles - if (this.inDepBundle || this.inShrinkwrap) + if (this.inDepBundle || this.inShrinkwrap) { return false + } // it's a top level pkg, or a dep of one - if (!this.resolveParent || !this.resolveParent.resolveParent) + if (!this.resolveParent || !this.resolveParent.resolveParent) { return false + } // no one wants it, remove it - if (this.edgesIn.size === 0) + if (this.edgesIn.size === 0) { return true + } const other = this.resolveParent.resolveParent.resolve(this.name) // nothing else, need this one - if (!other) + if (!other) { return false + } // if it's the same thing, then always fine to remove - if (other.matches(this)) + if (other.matches(this)) { return true + } // if the other thing can't replace this, then skip it - if (!other.canReplace(this)) + if (!other.canReplace(this)) { return false + } // if we prefer dedupe, or if the version is greater/equal, take the other - if (preferDedupe || semver.gte(other.version, this.version)) + if (preferDedupe || semver.gte(other.version, this.version)) { return true + } return false } satisfies (requested) { - if (requested instanceof Edge) + if (requested instanceof Edge) { return this.name === requested.name && requested.satisfiedBy(this) + } const parsed = npa(requested) const { name = this.name, rawSpec: spec } = parsed @@ -983,29 +1056,35 @@ class Node { matches (node) { // if the nodes are literally the same object, obviously a match. - if (node === this) + if (node === this) { return true + } // if the names don't match, they're different things, even if // the package contents are identical. - if (node.name !== this.name) + if (node.name !== this.name) { return false + } // if they're links, they match if the targets match - if (this.isLink) + if (this.isLink) { return node.isLink && this.target.matches(node.target) + } // if they're two project root nodes, they're different if the paths differ - if (this.isProjectRoot && node.isProjectRoot) + if (this.isProjectRoot && node.isProjectRoot) { return this.path === node.path + } // if the integrity matches, then they're the same. - if (this.integrity && node.integrity) + if (this.integrity && node.integrity) { return this.integrity === node.integrity + } // if no integrity, check resolved - if (this.resolved && node.resolved) + if (this.resolved && node.resolved) { return this.resolved === node.resolved + } // if no resolved, check both package name and version // otherwise, conclude that they are different things @@ -1031,39 +1110,44 @@ class Node { // parent's children map, and leave it at that. const nameMatch = node.parent && node.parent.children.get(this.name) === node - if (nameMatch) + if (nameMatch) { this.path = resolve(node.parent.path, 'node_modules', this.name) - else { + } else { this.path = node.path this.name = node.name } - if (!this.isLink) + if (!this.isLink) { this.realpath = this.path + } this[_refreshLocation]() // keep children when a node replaces another if (!this.isLink) { - for (const kid of node.children.values()) + for (const kid of node.children.values()) { kid.parent = this + } } - if (!node.isRoot) + if (!node.isRoot) { this.root = node.root + } treeCheck(this) } get inShrinkwrap () { - return this.parent && (this.parent.hasShrinkwrap || this.parent.inShrinkwrap) + return this.parent && + (this.parent.hasShrinkwrap || this.parent.inShrinkwrap) } get parent () { const parent = this[_parent] /* istanbul ignore next - should be impossible */ debug(() => { - if (parent === this) + if (parent === this) { throw new Error('node set to its own parent') + } }) return parent } @@ -1083,23 +1167,27 @@ class Node { if (!parent) { // but only delete it if we actually had a parent in the first place // otherwise it's just setting to null when it's already null - if (this[_parent]) + if (this[_parent]) { this.root = null + } return } - if (parent.isLink) + if (parent.isLink) { parent = parent.target + } // setting a thing to its own parent is not normal, but no-op for safety - if (this === parent) + if (this === parent) { return + } const oldParent = this[_parent] // nothing to do - if (oldParent === parent) + if (oldParent === parent) { return + } // ok now we know something is actually changing, and parent is not a link const newPath = resolve(parent.path, 'node_modules', this.name) @@ -1116,8 +1204,9 @@ class Node { } // update this.path/realpath for this and all children/fsChildren - if (pathChange) + if (pathChange) { this[_changePath](newPath) + } // clobbers anything at that path, resets all appropriate references this.root = parent.root @@ -1127,16 +1216,19 @@ class Node { // Removes the node from its root the metadata and inventory. [_delistFromMeta] () { const root = this.root - if (!root.realpath || !this.path) + if (!root.realpath || !this.path) { return + } root.inventory.delete(this) root.tops.delete(this) - if (root.meta) + if (root.meta) { root.meta.delete(this.path) + } /* istanbul ignore next - should be impossible */ debug(() => { - if ([...root.inventory.values()].includes(this)) + if ([...root.inventory.values()].includes(this)) { throw new Error('failed to delist') + } }) } @@ -1148,8 +1240,9 @@ class Node { this.path = newPath const namePattern = /(?:^|\/|\\)node_modules[\\/](@[^/\\]+[\\/][^\\/]+|[^\\/]+)$/ const nameChange = newPath.match(namePattern) - if (nameChange && this.name !== nameChange[1]) + if (nameChange && this.name !== nameChange[1]) { this.name = nameChange[1].replace(/\\/g, '/') + } // if we move a link target, update link realpaths if (!this.isLink) { @@ -1161,10 +1254,12 @@ class Node { } } // if we move /x to /y, then a module at /x/a/b becomes /y/a/b - for (const child of this.fsChildren) + for (const child of this.fsChildren) { child[_changePath](resolve(newPath, relative(oldPath, child.path))) - for (const [name, child] of this.children.entries()) + } + for (const [name, child] of this.children.entries()) { child[_changePath](resolve(newPath, 'node_modules', name)) + } this[_refreshLocation]() } @@ -1179,8 +1274,9 @@ class Node { this.location = loc root.inventory.add(this) - if (root.meta) + if (root.meta) { root.meta.add(this) + } } addEdgeOut (edge) { @@ -1191,8 +1287,9 @@ class Node { this.edgesIn.add(edge) // try to get metadata from the yarn.lock file - if (this.root.meta) + if (this.root.meta) { this.root.meta.addEdge(edge) + } } [_reloadNamedEdges] (name, rootLoc = this.location) { @@ -1202,13 +1299,16 @@ class Node { edge.to.location === `${rootLoc}/node_modules/${edge.name}` const sameResolved = edge && this.resolve(name) === edge.to const recheck = rootLocResolved || !sameResolved - if (edge && recheck) + if (edge && recheck) { edge.reload(true) - for (const c of this.children.values()) + } + for (const c of this.children.values()) { c[_reloadNamedEdges](name, rootLoc) + } - for (const c of this.fsChildren) + for (const c of this.fsChildren) { c[_reloadNamedEdges](name, rootLoc) + } } get isLink () { @@ -1255,15 +1355,18 @@ class Node { /* istanbul ignore next - should be impossible, * but I keep doing this mistake in tests */ debug(() => { - if (typeof name !== 'string' || !name) + if (typeof name !== 'string' || !name) { throw new Error('non-string passed to Node.resolve') + } }) const mine = this.children.get(name) - if (mine) + if (mine) { return mine + } const resolveParent = this.resolveParent - if (resolveParent) + if (resolveParent) { return resolveParent.resolve(name) + } return null } diff --git a/node_modules/@npmcli/arborist/lib/optional-set.js b/node_modules/@npmcli/arborist/lib/optional-set.js index 9472158bc44be..9f5184ea02442 100644 --- a/node_modules/@npmcli/arborist/lib/optional-set.js +++ b/node_modules/@npmcli/arborist/lib/optional-set.js @@ -10,8 +10,9 @@ const gatherDepSet = require('./gather-dep-set.js') const optionalSet = node => { - if (!node.optional) + if (!node.optional) { return new Set() + } // start with the node, then walk up the dependency graph until we // get to the boundaries that define the optional set. since the @@ -21,8 +22,9 @@ const optionalSet = node => { const set = new Set([node]) for (const node of set) { for (const edge of node.edgesIn) { - if (!edge.optional) + if (!edge.optional) { set.add(edge.from) + } } } diff --git a/node_modules/@npmcli/arborist/lib/peer-entry-sets.js b/node_modules/@npmcli/arborist/lib/peer-entry-sets.js index 11f9a431607ec..2c4322ee678ca 100644 --- a/node_modules/@npmcli/arborist/lib/peer-entry-sets.js +++ b/node_modules/@npmcli/arborist/lib/peer-entry-sets.js @@ -15,12 +15,14 @@ const peerEntrySets = node => { const unionSet = new Set([node]) for (const node of unionSet) { for (const edge of node.edgesOut.values()) { - if (edge.valid && edge.peer && edge.to) + if (edge.valid && edge.peer && edge.to) { unionSet.add(edge.to) + } } for (const edge of node.edgesIn) { - if (edge.valid && edge.peer) + if (edge.valid && edge.peer) { unionSet.add(edge.from) + } } } const entrySets = new Map() @@ -28,16 +30,18 @@ const peerEntrySets = node => { for (const edge of peer.edgesIn) { // if not valid, it doesn't matter anyway. either it's been previously // overridden, or it's the thing we're interested in replacing. - if (!edge.valid) + if (!edge.valid) { continue + } // this is the entry point into the peer set if (!edge.peer || edge.from.isTop) { // get the subset of peer brought in by this peer entry edge const sub = new Set([peer]) for (const peer of sub) { for (const edge of peer.edgesOut.values()) { - if (edge.valid && edge.peer && edge.to) + if (edge.valid && edge.peer && edge.to) { sub.add(edge.to) + } } } // if this subset does not include the node we are focused on, @@ -60,8 +64,9 @@ const peerEntrySets = node => { // Edge(a->b) => Set(b, d, e, f, g) // Edge(a->d) => Set(d, e, f, g) // } - if (sub.has(node)) + if (sub.has(node)) { entrySets.set(edge, sub) + } } } } diff --git a/node_modules/@npmcli/arborist/lib/place-dep.js b/node_modules/@npmcli/arborist/lib/place-dep.js index c0023e74ad8ea..d7cc7d935afc8 100644 --- a/node_modules/@npmcli/arborist/lib/place-dep.js +++ b/node_modules/@npmcli/arborist/lib/place-dep.js @@ -85,8 +85,9 @@ class PlaceDep { !edge.error && !explicitRequest && !updateNames.includes(edge.name) && - !this.isVulnerable(edge.to)) + !this.isVulnerable(edge.to)) { return + } // walk up the tree until we hit either a top/root node, or a place // where the dep is not a peer dep. @@ -110,8 +111,9 @@ class PlaceDep { // but we CAN place it under a, so the correct thing to do is keep // walking up the tree. const targetEdge = target.edgesOut.get(edge.name) - if (!target.isTop && targetEdge && targetEdge.peer) + if (!target.isTop && targetEdge && targetEdge.peer) { continue + } const cpd = new CanPlaceDep({ dep, @@ -141,34 +143,39 @@ class PlaceDep { // should treat (b) and (d) as OK, and place them in the last place // where they did not themselves conflict, and skip c@2 if conflict // is ok by virtue of being forced or not ours and not strict. - if (cpd.canPlaceSelf !== CONFLICT) + if (cpd.canPlaceSelf !== CONFLICT) { canPlaceSelf = cpd + } // we found a place this can go, along with all its peer friends. // we break when we get the first conflict - if (cpd.canPlace !== CONFLICT) + if (cpd.canPlace !== CONFLICT) { canPlace = cpd - else + } else { break + } // if it's a load failure, just plop it in the first place attempted, // since we're going to crash the build or prune it out anyway. // but, this will frequently NOT be a successful canPlace, because // it'll have no version or other information. - if (dep.errors.length) + if (dep.errors.length) { break + } // nest packages like npm v1 and v2 // very disk-inefficient - if (legacyBundling) + if (legacyBundling) { break + } // when installing globally, or just in global style, we never place // deps above the first level. if (globalStyle) { const rp = target.resolveParent - if (rp && rp.isProjectRoot) + if (rp && rp.isProjectRoot) { break + } } } @@ -183,8 +190,9 @@ class PlaceDep { if (!canPlace) { // if not forced, or it's our dep, or strictPeerDeps is set, then // this is an ERESOLVE error. - if (!this.conflictOk) + if (!this.conflictOk) { return this.failPeerConflict() + } // ok! we're gonna allow the conflict, but we should still warn // if we have a current, then we treat CONFLICT as a KEEP. @@ -237,8 +245,9 @@ class PlaceDep { // it's a conflict. Treat it as a KEEP, but warn and move on. if (placementType === KEEP) { // this was an overridden peer dep - if (edge.peer && !edge.valid) + if (edge.peer && !edge.valid) { this.warnPeerConflict() + } // if we get a KEEP in a update scenario, then we MAY have something // already duplicating this unnecessarily! For example: @@ -287,21 +296,24 @@ class PlaceDep { }) this.oldDep = target.children.get(this.name) - if (this.oldDep) + if (this.oldDep) { this.replaceOldDep() - else + } else { this.placed.parent = target + } // if it's an overridden peer dep, warn about it - if (edge.peer && !this.placed.satisfies(edge)) + if (edge.peer && !this.placed.satisfies(edge)) { this.warnPeerConflict() + } // If the edge is not an error, then we're updating something, and // MAY end up putting a better/identical node further up the tree in // a way that causes an unnecessary duplication. If so, remove the // now-unnecessary node. - if (edge.valid && edge.to && edge.to !== this.placed) + if (edge.valid && edge.to && edge.to !== this.placed) { this.pruneDedupable(edge.to, false) + } // in case we just made some duplicates that can be removed, // prune anything deeper in the tree that can be replaced by this @@ -310,8 +322,9 @@ class PlaceDep { this.pruneDedupable(node, false) // only walk the direct children of the ones we kept if (node.root === target.root) { - for (const kid of node.children.values()) + for (const kid of node.children.values()) { this.pruneDedupable(kid, false) + } } } } @@ -323,8 +336,9 @@ class PlaceDep { // otherwise they'd be gone and the peer set would change throughout // this loop. for (const peerEdge of this.placed.edgesOut.values()) { - if (peerEdge.valid || !peerEdge.peer || peerEdge.overridden) + if (peerEdge.valid || !peerEdge.peer || peerEdge.overridden) { continue + } const peer = virtualRoot.children.get(peerEdge.name) @@ -332,12 +346,14 @@ class PlaceDep { // it's an optional peer dep. If it's not being properly met (ie, // peerEdge.valid is false), then this is likely heading for an // ERESOLVE error, unless it can walk further up the tree. - if (!peer) + if (!peer) { continue + } // overridden peerEdge, just accept what's there already - if (!peer.satisfies(peerEdge)) + if (!peer.satisfies(peerEdge)) { continue + } this.children.push(new PlaceDep({ parent: this, @@ -363,8 +379,9 @@ class PlaceDep { // later anyway. const oldDeps = [] for (const [name, edge] of this.oldDep.edgesOut.entries()) { - if (!this.placed.edgesOut.has(name) && edge.to) + if (!this.placed.edgesOut.has(name) && edge.to) { oldDeps.push(...gatherDepSet([edge.to], e => e.to !== edge.to)) + } } this.placed.replace(this.oldDep) this.pruneForReplacement(this.placed, oldDeps) @@ -377,8 +394,9 @@ class PlaceDep { .filter(e => e.to && !e.valid).map(e => e.to)) for (const dep of oldDeps) { const set = gatherDepSet([dep], e => e.to !== dep && e.valid) - for (const dep of set) + for (const dep of set) { invalidDeps.add(dep) + } } // ignore dependency edges from the node being replaced, but @@ -388,8 +406,9 @@ class PlaceDep { edge.from !== node && edge.to !== node && edge.valid) // now just delete whatever's left, because it's junk - for (const dep of deps) + for (const dep of deps) { dep.root = null + } } // prune all the nodes in a branch of the tree that can be safely removed @@ -402,8 +421,9 @@ class PlaceDep { // the dep set, except for this node we're deduping, so that we // also prune deps that would be made extraneous. const deps = gatherDepSet([node], e => e.to !== node && e.valid) - for (const node of deps) + for (const node of deps) { node.root = null + } return } if (descend) { @@ -413,13 +433,15 @@ class PlaceDep { const nodeSort = (a, b) => a.location.localeCompare(b.location, 'en') const children = [...node.children.values()].sort(nodeSort) - for (const child of children) + for (const child of children) { this.pruneDedupable(child) + } const fsChildren = [...node.fsChildren].sort(nodeSort) for (const topNode of fsChildren) { const children = [...topNode.children.values()].sort(nodeSort) - for (const child of children) + for (const child of children) { this.pruneDedupable(child) + } } } } @@ -432,11 +454,13 @@ class PlaceDep { const { edge } = this.top const { from: node } = edge - if (node.isWorkspace || node.isProjectRoot) + if (node.isWorkspace || node.isProjectRoot) { return true + } - if (!edge.peer) + if (!edge.peer) { return false + } // re-entry case. check if any non-peer edges come from the project, // or any entryEdges on peer groups are from the root. @@ -446,13 +470,15 @@ class PlaceDep { hasPeerEdges = true continue } - if (edge.from.isWorkspace || edge.from.isProjectRoot) + if (edge.from.isWorkspace || edge.from.isProjectRoot) { return true + } } if (hasPeerEdges) { for (const edge of peerEntrySets(node).keys()) { - if (edge.from.isWorkspace || edge.from.isProjectRoot) + if (edge.from.isWorkspace || edge.from.isProjectRoot) { return true + } } } @@ -541,8 +567,9 @@ class PlaceDep { get allChildren () { const set = new Set(this.children) for (const child of set) { - for (const grandchild of child.children) + for (const grandchild of child.children) { set.add(grandchild) + } } return [...set] } diff --git a/node_modules/@npmcli/arborist/lib/printable.js b/node_modules/@npmcli/arborist/lib/printable.js index 4aa2fffd104b4..af24ccb959288 100644 --- a/node_modules/@npmcli/arborist/lib/printable.js +++ b/node_modules/@npmcli/arborist/lib/printable.js @@ -7,45 +7,62 @@ const relpath = require('./relpath.js') class ArboristNode { constructor (tree, path) { this.name = tree.name - if (tree.packageName && tree.packageName !== this.name) + if (tree.packageName && tree.packageName !== this.name) { this.packageName = tree.packageName - if (tree.version) + } + if (tree.version) { this.version = tree.version + } this.location = tree.location this.path = tree.path - if (tree.realpath !== this.path) + if (tree.realpath !== this.path) { this.realpath = tree.realpath - if (tree.resolved !== null) + } + if (tree.resolved !== null) { this.resolved = tree.resolved - if (tree.extraneous) + } + if (tree.extraneous) { this.extraneous = true - if (tree.dev) + } + if (tree.dev) { this.dev = true - if (tree.optional) + } + if (tree.optional) { this.optional = true - if (tree.devOptional && !tree.dev && !tree.optional) + } + if (tree.devOptional && !tree.dev && !tree.optional) { this.devOptional = true - if (tree.peer) + } + if (tree.peer) { this.peer = true - if (tree.inBundle) + } + if (tree.inBundle) { this.bundled = true - if (tree.inDepBundle) + } + if (tree.inDepBundle) { this.bundler = tree.getBundler().location - if (tree.isProjectRoot) + } + if (tree.isProjectRoot) { this.isProjectRoot = true - if (tree.isWorkspace) + } + if (tree.isWorkspace) { this.isWorkspace = true + } const bd = tree.package && tree.package.bundleDependencies - if (bd && bd.length) + if (bd && bd.length) { this.bundleDependencies = bd - if (tree.inShrinkwrap) + } + if (tree.inShrinkwrap) { this.inShrinkwrap = true - else if (tree.hasShrinkwrap) + } else if (tree.hasShrinkwrap) { this.hasShrinkwrap = true - if (tree.error) + } + if (tree.error) { this.error = treeError(tree.error) - if (tree.errors && tree.errors.length) + } + if (tree.errors && tree.errors.length) { this.errors = tree.errors.map(treeError) + } // edgesOut sorted by name if (tree.edgesOut.size) { @@ -109,10 +126,12 @@ class Edge { this.type = edge.type this.name = edge.name this.spec = edge.spec || '*' - if (edge.error) + if (edge.error) { this.error = edge.error - if (edge.overridden) + } + if (edge.overridden) { this.overridden = edge.overridden + } } } @@ -151,8 +170,9 @@ class EdgeIn extends Edge { } const printableTree = (tree, path = []) => { - if (!tree) + if (!tree) { return tree + } const Cls = tree.isLink ? ArboristLink : tree.sourceReference ? ArboristVirtualNode diff --git a/node_modules/@npmcli/arborist/lib/realpath.js b/node_modules/@npmcli/arborist/lib/realpath.js index fa467c097a60b..bc4bbbce38485 100644 --- a/node_modules/@npmcli/arborist/lib/realpath.js +++ b/node_modules/@npmcli/arborist/lib/realpath.js @@ -14,18 +14,21 @@ const { resolve, basename, dirname } = require('path') const realpathCached = (path, rpcache, stcache, depth) => { // just a safety against extremely deep eloops /* istanbul ignore next */ - if (depth > 2000) + if (depth > 2000) { throw eloop(path) + } path = resolve(path) - if (rpcache.has(path)) + if (rpcache.has(path)) { return Promise.resolve(rpcache.get(path)) + } const dir = dirname(path) const base = basename(path) - if (base && rpcache.has(dir)) + if (base && rpcache.has(dir)) { return realpathChild(dir, base, rpcache, stcache, depth) + } // if it's the root, then we know it's real if (!base) { @@ -40,8 +43,9 @@ const realpathCached = (path, rpcache, stcache, depth) => { } const lstatCached = (path, stcache) => { - if (stcache.has(path)) + if (stcache.has(path)) { return Promise.resolve(stcache.get(path)) + } const p = lstat(path).then(st => { stcache.set(path, st) @@ -66,8 +70,9 @@ const realpathChild = (dir, base, rpcache, stcache, depth) => { const realdir = rpcache.get(dir) // that unpossible /* istanbul ignore next */ - if (typeof realdir === 'undefined') + if (typeof realdir === 'undefined') { throw new Error('in realpathChild without parent being in realpath cache') + } const realish = resolve(realdir, base) return lstatCached(realish, stcache).then(st => { @@ -78,8 +83,9 @@ const realpathChild = (dir, base, rpcache, stcache, depth) => { return readlink(realish).then(target => { const resolved = resolve(realdir, target) - if (realish === resolved) + if (realish === resolved) { throw eloop(realish) + } return realpathCached(resolved, rpcache, stcache, depth + 1) }).then(real => { diff --git a/node_modules/@npmcli/arborist/lib/shrinkwrap.js b/node_modules/@npmcli/arborist/lib/shrinkwrap.js index 83cb1f66f3a10..6e7e0e31f166b 100644 --- a/node_modules/@npmcli/arborist/lib/shrinkwrap.js +++ b/node_modules/@npmcli/arborist/lib/shrinkwrap.js @@ -47,8 +47,9 @@ const readlink = promisify(fs.readlink) const lstat = promisify(fs.lstat) /* istanbul ignore next - version specific polyfill */ const readdir = async (path, opt) => { - if (!opt || !opt.withFileTypes) + if (!opt || !opt.withFileTypes) { return readdir_(path, opt) + } const ents = await readdir_(path, opt) if (typeof ents[0] === 'string') { return Promise.all(ents.map(async ent => { @@ -97,20 +98,22 @@ const consistentResolve = require('./consistent-resolve.js') const maybeReadFile = file => { return readFile(file, 'utf8').then(d => d, er => { /* istanbul ignore else - can't test without breaking module itself */ - if (er.code === 'ENOENT') + if (er.code === 'ENOENT') { return '' - else + } else { throw er + } }) } const maybeStatFile = file => { return stat(file).then(st => st.isFile(), er => { /* istanbul ignore else - can't test without breaking module itself */ - if (er.code === 'ENOENT') + if (er.code === 'ENOENT') { return null - else + } else { throw er + } }) } @@ -163,13 +166,16 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => { const rel = relpath(path, dir) if (dir !== path) { const dirTime = (await stat(dir)).mtime - if (dirTime > lockTime) + if (dirTime > lockTime) { throw 'out of date, updated: ' + rel - if (!isScope && !isNM && !data.packages[rel]) + } + if (!isScope && !isNM && !data.packages[rel]) { throw 'missing from lockfile: ' + rel + } seen.add(rel) - } else + } else { seen = new Set([rel]) + } const parent = isParent ? dir : resolve(dir, 'node_modules') const children = dir === path @@ -179,26 +185,29 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => { return children.catch(() => []) .then(ents => Promise.all(ents.map(async ent => { const child = resolve(parent, ent.name) - if (ent.isDirectory() && !/^\./.test(ent.name)) + if (ent.isDirectory() && !/^\./.test(ent.name)) { await assertNoNewer(path, data, lockTime, child, seen) - else if (ent.isSymbolicLink()) { + } else if (ent.isSymbolicLink()) { const target = resolve(parent, await readlink(child)) const tstat = await stat(target).catch( /* istanbul ignore next - windows */ () => null) seen.add(relpath(path, child)) /* istanbul ignore next - windows cannot do this */ - if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target))) + if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target))) { await assertNoNewer(path, data, lockTime, target, seen) + } } }))) .then(() => { - if (dir !== path) + if (dir !== path) { return + } // assert that all the entries in the lockfile were seen for (const loc of new Set(Object.keys(data.packages))) { - if (!seen.has(loc)) + if (!seen.has(loc)) { throw 'missing from node_modules: ' + loc + } } }) } @@ -252,39 +261,48 @@ class Shrinkwrap { const meta = {} pkgMetaKeys.forEach(key => { const val = metaFieldFromPkg(node.package, key) - if (val) + if (val) { meta[key.replace(/^_/, '')] = val + } }) // we only include name if different from the node path name, and for the // root to help prevent churn based on the name of the directory the // project is in const pname = node.packageName - if (pname && (node === node.root || pname !== node.name)) + if (pname && (node === node.root || pname !== node.name)) { meta.name = pname + } - if (node.isTop && node.package.devDependencies) + if (node.isTop && node.package.devDependencies) { meta.devDependencies = node.package.devDependencies + } nodeMetaKeys.forEach(key => { - if (node[key]) + if (node[key]) { meta[key] = node[key] + } }) const resolved = consistentResolve(node.resolved, node.path, path, true) - if (resolved) + if (resolved) { meta.resolved = resolved + } - if (node.extraneous) + if (node.extraneous) { meta.extraneous = true - else { - if (node.peer) + } else { + if (node.peer) { meta.peer = true - if (node.dev) + } + if (node.dev) { meta.dev = true - if (node.optional) + } + if (node.optional) { meta.optional = true - if (node.devOptional && !node.dev && !node.optional) + } + if (node.devOptional && !node.dev && !node.optional) { meta.devOptional = true + } } return meta } @@ -423,8 +441,9 @@ class Shrinkwrap { this.indent = indent !== undefined ? indent : this.indent this.newline = newline !== undefined ? newline : this.newline - if (!this.hiddenLockfile || !data.packages) + if (!this.hiddenLockfile || !data.packages) { return data + } // add a few ms just to account for jitter const lockTime = +(await stat(this.filename)).mtime + 10 @@ -467,8 +486,9 @@ class Shrinkwrap { // migrate a v1 package lock to the new format. const meta = this[_metaFromLock](location, name, lock) // dependencies nested under a link are actually under the link target - if (meta.link) + if (meta.link) { location = meta.resolved + } if (lock.dependencies) { for (const [name, dep] of Object.entries(lock.dependencies)) { const loc = location + (location ? '/' : '') + 'node_modules/' + name @@ -488,13 +508,15 @@ class Shrinkwrap { pkgMetaKeys.forEach(key => { const val = metaFieldFromPkg(pkg, key) const k = key.replace(/^_/, '') - if (val) + if (val) { root[k] = val + } }) for (const [loc, meta] of Object.entries(this.data.packages)) { - if (!meta.requires || !loc) + if (!meta.requires || !loc) { continue + } // resolve each require to a meta entry // if this node isn't optional, but the dep is, then it's an optionalDep @@ -523,27 +545,33 @@ class Shrinkwrap { [_resolveMetaNode] (loc, name) { for (let path = loc; true; path = path.replace(/(^|\/)[^/]*$/, '')) { const check = `${path}${path ? '/' : ''}node_modules/${name}` - if (this.data.packages[check]) + if (this.data.packages[check]) { return this.data.packages[check] + } - if (!path) + if (!path) { break + } } return null } [_lockFromLoc] (lock, path, i = 0) { - if (!lock) + if (!lock) { return null + } - if (path[i] === '') + if (path[i] === '') { i++ + } - if (i >= path.length) + if (i >= path.length) { return lock + } - if (!lock.dependencies) + if (!lock.dependencies) { return null + } return this[_lockFromLoc](lock.dependencies[path[i]], path, i + 1) } @@ -555,8 +583,9 @@ class Shrinkwrap { } delete (nodePath) { - if (!this.data) + if (!this.data) { throw new Error('run load() before getting or setting data') + } const location = this[_pathToLoc](nodePath) this[_awaitingUpdate].delete(location) @@ -564,22 +593,26 @@ class Shrinkwrap { const path = location.split(/(?:^|\/)node_modules\//) const name = path.pop() const pLock = this[_lockFromLoc](this.data, path) - if (pLock && pLock.dependencies) + if (pLock && pLock.dependencies) { delete pLock.dependencies[name] + } } get (nodePath) { - if (!this.data) + if (!this.data) { throw new Error('run load() before getting or setting data') + } const location = this[_pathToLoc](nodePath) - if (this[_awaitingUpdate].has(location)) + if (this[_awaitingUpdate].has(location)) { this[_updateWaitingNode](location) + } // first try to get from the newer spot, which we know has // all the things we need. - if (this.data.packages[location]) + if (this.data.packages[location]) { return this.data.packages[location] + } // otherwise, fall back to the legacy metadata, and hope for the best // get the node in the shrinkwrap corresponding to this spot @@ -595,8 +628,9 @@ class Shrinkwrap { // from a lockfile which may be outdated or incomplete. Since v1 // lockfiles used the "version" field to contain a variety of // different possible types of data, this gets a little complicated. - if (!lock) + if (!lock) { return {} + } // try to figure out a npm-package-arg spec from the lockfile entry // This will return null if we could not get anything valid out of it. @@ -613,29 +647,35 @@ class Shrinkwrap { } // also save the link target, omitting version since we don't know // what it is, but we know it isn't a link to itself! - if (!this.data.packages[target]) + if (!this.data.packages[target]) { this[_metaFromLock](target, name, { ...lock, version: null }) + } return this.data.packages[location] } const meta = {} // when calling loadAll we'll change these into proper dep objects - if (lock.requires && typeof lock.requires === 'object') + if (lock.requires && typeof lock.requires === 'object') { meta.requires = lock.requires + } - if (lock.optional) + if (lock.optional) { meta.optional = true - if (lock.dev) + } + if (lock.dev) { meta.dev = true + } // the root will typically have a name from the root project's // package.json file. - if (location === '') + if (location === '') { meta.name = lock.name + } // if we have integrity, save it now. - if (lock.integrity) + if (lock.integrity) { meta.integrity = lock.integrity + } if (lock.version && !lock.integrity) { // this is usually going to be a git url or symlink, but it could @@ -668,12 +708,13 @@ class Shrinkwrap { // have a fetchSpec equal to the fully resolved thing. // Registry deps, we take what's in the lockfile. if (lock.resolved || (spec.type && !spec.registry)) { - if (spec.registry) + if (spec.registry) { meta.resolved = lock.resolved - else if (spec.type === 'file') + } else if (spec.type === 'file') { meta.resolved = consistentResolve(spec, this.path, this.path, true) - else if (spec.fetchSpec) + } else if (spec.fetchSpec) { meta.resolved = spec.fetchSpec + } } // at this point, if still we don't have a version, do our best to @@ -685,32 +726,37 @@ class Shrinkwrap { versionFromTgz(spec.name, meta.resolved) if (fromTgz) { meta.version = fromTgz.version - if (fromTgz.name !== name) + if (fromTgz.name !== name) { meta.name = fromTgz.name + } } } else if (spec.type === 'alias') { meta.name = spec.subSpec.name meta.version = spec.subSpec.fetchSpec - } else if (spec.type === 'version') + } else if (spec.type === 'version') { meta.version = spec.fetchSpec + } // ok, I did my best! good luck! } - if (lock.bundled) + if (lock.bundled) { meta.inBundle = true + } // save it for next time return this.data.packages[location] = meta } add (node) { - if (!this.data) + if (!this.data) { throw new Error('run load() before getting or setting data') + } // will be actually updated on read const loc = relpath(this.path, node.path) - if (node.path === this.path) + if (node.path === this.path) { this.tree = node + } // if we have metadata about this node, and it's a match, then // try to decorate it. @@ -758,18 +804,21 @@ class Shrinkwrap { } addEdge (edge) { - if (!this.yarnLock || !edge.valid) + if (!this.yarnLock || !edge.valid) { return + } const { to: node } = edge // if it's already set up, nothing to do - if (node.resolved !== null && node.integrity !== null) + if (node.resolved !== null && node.integrity !== null) { return + } // if the yarn lock is empty, nothing to do - if (!this.yarnLock.entries || !this.yarnLock.entries.size) + if (!this.yarnLock.entries || !this.yarnLock.entries.size) { return + } // we relativize the path here because that's how it shows up in the lock // XXX how is this different from pathFixed above?? @@ -783,11 +832,13 @@ class Shrinkwrap { if (!entry || mismatch(node.version, entry.version) || mismatch(node.integrity, entry.integrity) || - mismatch(pathFixed, entry.resolved)) + mismatch(pathFixed, entry.resolved)) { return + } - if (entry.resolved && yarnRegRe.test(entry.resolved) && spec.registry) + if (entry.resolved && yarnRegRe.test(entry.resolved) && spec.registry) { entry.resolved = entry.resolved.replace(yarnRegRe, 'https://registry.npmjs.org/') + } node.integrity = node.integrity || entry.integrity || null node.resolved = node.resolved || @@ -804,30 +855,35 @@ class Shrinkwrap { commit () { if (this.tree) { - if (this.yarnLock) + if (this.yarnLock) { this.yarnLock.fromTree(this.tree) + } const root = Shrinkwrap.metaFromNode(this.tree.target, this.path) this.data.packages = {} - if (Object.keys(root).length) + if (Object.keys(root).length) { this.data.packages[''] = root + } for (const node of this.tree.root.inventory.values()) { // only way this.tree is not root is if the root is a link to it - if (node === this.tree || node.isRoot || node.location === '') + if (node === this.tree || node.isRoot || node.location === '') { continue + } const loc = relpath(this.path, node.path) this.data.packages[loc] = Shrinkwrap.metaFromNode(node, this.path) } } else if (this[_awaitingUpdate].size > 0) { - for (const loc of this[_awaitingUpdate].keys()) + for (const loc of this[_awaitingUpdate].keys()) { this[_updateWaitingNode](loc) + } } // hidden lockfiles don't include legacy metadata or a root entry if (this.hiddenLockfile) { delete this.data.packages[''] delete this.data.dependencies - } else if (this.tree) + } else if (this.tree) { this[_buildLegacyLockfile](this.tree, this.data) + } return this.data } @@ -836,8 +892,9 @@ class Shrinkwrap { if (node === this.tree) { // the root node lock.name = node.packageName || node.name - if (node.version) + if (node.version) { lock.version = node.version + } } // npm v6 and before tracked 'from', meaning "the request that led @@ -868,26 +925,29 @@ class Shrinkwrap { const spec = !edge ? rSpec : npa.resolve(node.name, edge.spec, edge.from.realpath) - if (node.isLink) + if (node.isLink) { lock.version = `file:${relpath(this.path, node.realpath)}` - else if (spec && (spec.type === 'file' || spec.type === 'remote')) + } else if (spec && (spec.type === 'file' || spec.type === 'remote')) { lock.version = spec.saveSpec - else if (spec && spec.type === 'git' || rSpec.type === 'git') { + } else if (spec && spec.type === 'git' || rSpec.type === 'git') { lock.version = node.resolved /* istanbul ignore else - don't think there are any cases where a git * spec (or indeed, ANY npa spec) doesn't have a .raw member */ - if (spec.raw) + if (spec.raw) { lock.from = spec.raw + } } else if (!node.isRoot && node.package && node.packageName && - node.packageName !== node.name) + node.packageName !== node.name) { lock.version = `npm:${node.packageName}@${node.version}` - else if (node.package && node.version) + } else if (node.package && node.version) { lock.version = node.version + } - if (node.inDepBundle) + if (node.inDepBundle) { lock.bundled = true + } // when we didn't resolve to git, file, or dir, and didn't request // git, file, dir, or remote, then the resolved value is necessary. @@ -899,77 +959,90 @@ class Shrinkwrap { spec.type !== 'directory' && spec.type !== 'git' && spec.type !== 'file' && - spec.type !== 'remote') + spec.type !== 'remote') { lock.resolved = node.resolved + } - if (node.integrity) + if (node.integrity) { lock.integrity = node.integrity + } - if (node.extraneous) + if (node.extraneous) { lock.extraneous = true - else if (!node.isLink) { - if (node.peer) + } else if (!node.isLink) { + if (node.peer) { lock.peer = true + } - if (node.devOptional && !node.dev && !node.optional) + if (node.devOptional && !node.dev && !node.optional) { lock.devOptional = true + } - if (node.dev) + if (node.dev) { lock.dev = true + } - if (node.optional) + if (node.optional) { lock.optional = true + } } const depender = node.target if (depender.edgesOut.size > 0) { if (node !== this.tree) { - lock.requires = [...depender.edgesOut.entries()].reduce((set, [k, v]) => { + const entries = [...depender.edgesOut.entries()] + lock.requires = entries.reduce((set, [k, v]) => { // omit peer deps from legacy lockfile requires field, because // npm v6 doesn't handle peer deps, and this triggers some bad // behavior if the dep can't be found in the dependencies list. const { spec, peer } = v - if (peer) + if (peer) { return set + } if (spec.startsWith('file:')) { // turn absolute file: paths into relative paths from the node // this especially shows up with workspace edges when the root // node is also a workspace in the set. const p = resolve(node.realpath, spec.substr('file:'.length)) set[k] = `file:${relpath(node.realpath, p)}` - } else + } else { set[k] = spec + } return set }, {}) - } else + } else { lock.requires = true + } } // now we walk the children, putting them in the 'dependencies' object const {children} = node.target - if (!children.size) + if (!children.size) { delete lock.dependencies - else { + } else { const kidPath = [...path, node.realpath] const dependencies = {} // skip any that are already in the descent path, so cyclical link // dependencies don't blow up with ELOOP. let found = false for (const [name, kid] of children.entries()) { - if (path.includes(kid.realpath)) + if (path.includes(kid.realpath)) { continue + } dependencies[name] = this[_buildLegacyLockfile](kid, {}, kidPath) found = true } - if (found) + if (found) { lock.dependencies = dependencies + } } return lock } save (options = {}) { - if (!this.data) + if (!this.data) { throw new Error('run load() before saving data') + } const { format = true } = options const defaultIndent = this.indent || 2 diff --git a/node_modules/@npmcli/arborist/lib/signal-handling.js b/node_modules/@npmcli/arborist/lib/signal-handling.js index 1051cd593970a..0afbb05dcfc64 100644 --- a/node_modules/@npmcli/arborist/lib/signal-handling.js +++ b/node_modules/@npmcli/arborist/lib/signal-handling.js @@ -13,8 +13,9 @@ const setup = fn => { const sigListeners = { loaded: false } const unload = () => { - if (!sigListeners.loaded) + if (!sigListeners.loaded) { return + } for (const sig of signals) { try { process.removeListener(sig, sigListeners[sig]) @@ -43,8 +44,9 @@ const setup = fn => { // if we exit normally, but caught a signal which would have been fatal, // then re-send it once we're done with whatever cleanup we have to do. unload() - if (process.listeners(sig).length < 1) + if (process.listeners(sig).length < 1) { process.once('beforeExit', onBeforeExit) + } fn({ signal: sig }) } @@ -56,8 +58,9 @@ const setup = fn => { try { // if we call this a bunch of times, avoid triggering the warning const { length } = process.listeners(sig) - if (length >= max) + if (length >= max) { process.setMaxListeners(length + 1) + } process.on(sig, sigListeners[sig]) } catch (er) {} } diff --git a/node_modules/@npmcli/arborist/lib/spec-from-lock.js b/node_modules/@npmcli/arborist/lib/spec-from-lock.js index eccf472a96a80..789741976269d 100644 --- a/node_modules/@npmcli/arborist/lib/spec-from-lock.js +++ b/node_modules/@npmcli/arborist/lib/spec-from-lock.js @@ -5,19 +5,22 @@ const specFromLock = (name, lock, where) => { try { if (lock.version) { const spec = npa.resolve(name, lock.version, where) - if (lock.integrity || spec.type === 'git') + if (lock.integrity || spec.type === 'git') { return spec + } } if (lock.from) { // legacy metadata includes "from", but not integrity const spec = npa.resolve(name, lock.from, where) - if (spec.registry && lock.version) + if (spec.registry && lock.version) { return npa.resolve(name, lock.version, where) - else if (!lock.resolved) + } else if (!lock.resolved) { return spec + } } - if (lock.resolved) + if (lock.resolved) { return npa.resolve(name, lock.resolved, where) + } } catch (_) { } try { return npa.resolve(name, lock.version, where) diff --git a/node_modules/@npmcli/arborist/lib/tracker.js b/node_modules/@npmcli/arborist/lib/tracker.js index aefd5fe1bbf58..b50f06eaa5518 100644 --- a/node_modules/@npmcli/arborist/lib/tracker.js +++ b/node_modules/@npmcli/arborist/lib/tracker.js @@ -11,35 +11,37 @@ module.exports = cls => class Tracker extends cls { addTracker (section, subsection = null, key = null) { // TrackerGroup type object not found - if (!this.log.newGroup) + if (!this.log.newGroup) { return + } - if (section === null || section === undefined) + if (section === null || section === undefined) { this[_onError](`Tracker can't be null or undefined`) + } - if (key === null) + if (key === null) { key = subsection + } const hasTracker = this[_progress].has(section) const hasSubtracker = this[_progress].has(`${section}:${key}`) - if (hasTracker && subsection === null) + if (hasTracker && subsection === null) { // 0. existing tracker, no subsection this[_onError](`Tracker "${section}" already exists`) - - else if (!hasTracker && subsection === null) { + } else if (!hasTracker && subsection === null) { // 1. no existing tracker, no subsection // Create a new tracker from this.log // starts progress bar - if (this[_progress].size === 0) + if (this[_progress].size === 0) { this.log.enableProgress() + } this[_progress].set(section, this.log.newGroup(section)) - } else if (!hasTracker && subsection !== null) + } else if (!hasTracker && subsection !== null) { // 2. no parent tracker and subsection this[_onError](`Parent tracker "${section}" does not exist`) - - else if (!hasTracker || !hasSubtracker) { + } else if (!hasTracker || !hasSubtracker) { // 3. existing parent tracker, no subsection tracker // Create a new subtracker in this[_progress] from parent tracker this[_progress].set(`${section}:${key}`, @@ -52,14 +54,17 @@ module.exports = cls => class Tracker extends cls { finishTracker (section, subsection = null, key = null) { // TrackerGroup type object not found - if (!this.log.newGroup) + if (!this.log.newGroup) { return + } - if (section === null || section === undefined) + if (section === null || section === undefined) { this[_onError](`Tracker can't be null or undefined`) + } - if (key === null) + if (key === null) { key = subsection + } const hasTracker = this[_progress].has(section) const hasSubtracker = this[_progress].has(`${section}:${key}`) @@ -71,8 +76,9 @@ module.exports = cls => class Tracker extends cls { // not have any remaining children const keys = this[_progress].keys() for (const key of keys) { - if (key.match(new RegExp(section + ':'))) + if (key.match(new RegExp(section + ':'))) { this.finishTracker(section, key) + } } // remove parent tracker @@ -81,13 +87,13 @@ module.exports = cls => class Tracker extends cls { // remove progress bar if all // trackers are finished - if (this[_progress].size === 0) + if (this[_progress].size === 0) { this.log.disableProgress() - } else if (!hasTracker && subsection === null) + } + } else if (!hasTracker && subsection === null) { // 1. no existing parent tracker, no subsection this[_onError](`Tracker "${section}" does not exist`) - - else if (!hasTracker || hasSubtracker) { + } else if (!hasTracker || hasSubtracker) { // 2. subtracker exists // Finish subtracker and remove from this[_progress] this[_progress].get(`${section}:${key}`).finish() diff --git a/node_modules/@npmcli/arborist/lib/tree-check.js b/node_modules/@npmcli/arborist/lib/tree-check.js index a7e8d9c014213..44b5484c68240 100644 --- a/node_modules/@npmcli/arborist/lib/tree-check.js +++ b/node_modules/@npmcli/arborist/lib/tree-check.js @@ -5,8 +5,9 @@ const checkTree = (tree, checkUnreachable = true) => { // this can only happen in tests where we have a "tree" object // that isn't actually a tree. - if (!tree.root || !tree.root.inventory) + if (!tree.root || !tree.root.inventory) { return tree + } const { inventory } = tree.root const seen = new Set() @@ -21,8 +22,9 @@ const checkTree = (tree, checkUnreachable = true) => { 'root=' + !!(node && node.isRoot), ]) - if (!node || seen.has(node) || node.then) + if (!node || seen.has(node) || node.then) { return + } seen.add(node) @@ -116,14 +118,18 @@ const checkTree = (tree, checkUnreachable = true) => { check(fsParent, node, 'fsParent') check(target, node, 'target') log.push(['CHILDREN', node.location, ...node.children.keys()]) - for (const kid of node.children.values()) + for (const kid of node.children.values()) { check(kid, node, 'children') - for (const kid of node.fsChildren) + } + for (const kid of node.fsChildren) { check(kid, node, 'fsChildren') - for (const link of node.linksIn) + } + for (const link of node.linksIn) { check(link, node, 'linksIn') - for (const top of node.tops) + } + for (const top of node.tops) { check(top, node, 'tops') + } log.push(['DONE', node.location]) } check(tree) diff --git a/node_modules/@npmcli/arborist/lib/version-from-tgz.js b/node_modules/@npmcli/arborist/lib/version-from-tgz.js index 4b433ea636a8b..d5d8f7345c9bb 100644 --- a/node_modules/@npmcli/arborist/lib/version-from-tgz.js +++ b/node_modules/@npmcli/arborist/lib/version-from-tgz.js @@ -4,8 +4,9 @@ const {basename} = require('path') const {parse} = require('url') module.exports = (name, tgz) => { const base = basename(tgz) - if (!base.endsWith('.tgz')) + if (!base.endsWith('.tgz')) { return null + } const u = parse(tgz) if (/^https?:/.test(u.protocol)) { @@ -35,8 +36,9 @@ module.exports = (name, tgz) => { } const versionFromBaseScopeName = (base, scope, name) => { - if (!base.startsWith(name + '-')) + if (!base.startsWith(name + '-')) { return null + } const parsed = semver.parse(base.substring(name.length + 1, base.length - 4)) return parsed ? { diff --git a/node_modules/@npmcli/arborist/lib/vuln.js b/node_modules/@npmcli/arborist/lib/vuln.js index 5b1d1dc1ab83d..da44e7c34d63c 100644 --- a/node_modules/@npmcli/arborist/lib/vuln.js +++ b/node_modules/@npmcli/arborist/lib/vuln.js @@ -28,8 +28,9 @@ const severities = new Map([ [null, -1], ]) -for (const [name, val] of severities.entries()) +for (const [name, val] of severities.entries()) { severities.set(val, name) +} class Vuln { constructor ({ name, advisory }) { @@ -43,7 +44,7 @@ class Vuln { this[_simpleRange] = null this.nodes = new Set() // assume a fix is available unless it hits a top node - // that locks it in place, setting this to false or {isSemVerMajor, version}. + // that locks it in place, setting this false or {isSemVerMajor, version}. this[_fixAvailable] = true this.addAdvisory(advisory) this.packument = advisory.packument @@ -65,30 +66,35 @@ class Vuln { // - true: fix does not require -f for (const v of this.via) { // don't blow up on loops - if (v.fixAvailable === f) + if (v.fixAvailable === f) { continue + } - if (f === false) + if (f === false) { v.fixAvailable = f - else if (v.fixAvailable === true) + } else if (v.fixAvailable === true) { v.fixAvailable = f - else if (typeof f === 'object' && ( - typeof v.fixAvailable !== 'object' || !v.fixAvailable.isSemVerMajor)) + } else if (typeof f === 'object' && ( + typeof v.fixAvailable !== 'object' || !v.fixAvailable.isSemVerMajor)) { v.fixAvailable = f + } } } testSpec (spec) { const specObj = npa(spec) - if (!specObj.registry) + if (!specObj.registry) { return true + } - if (specObj.subSpec) + if (specObj.subSpec) { spec = specObj.subSpec.rawSpec + } for (const v of this.versions) { - if (satisfies(v, spec) && !satisfies(v, this.range, semverOpt)) + if (satisfies(v, spec) && !satisfies(v, this.range, semverOpt)) { return false + } } return true } @@ -135,14 +141,16 @@ class Vuln { this[_range] = null this[_simpleRange] = null // refresh severity - for (const advisory of this.advisories) + for (const advisory of this.advisories) { this.addAdvisory(advisory) + } // remove any effects that are no longer relevant const vias = new Set([...this.advisories].map(a => a.dependency)) for (const via of this.via) { - if (!vias.has(via.name)) + if (!vias.has(via.name)) { this.deleteVia(via) + } } } @@ -151,8 +159,9 @@ class Vuln { const sev = severities.get(advisory.severity) this[_range] = null this[_simpleRange] = null - if (sev > severities.get(this.severity)) + if (sev > severities.get(this.severity)) { this.severity = advisory.severity + } } get range () { @@ -161,8 +170,9 @@ class Vuln { } get simpleRange () { - if (this[_simpleRange] && this[_simpleRange] === this[_range]) + if (this[_simpleRange] && this[_simpleRange] === this[_range]) { return this[_simpleRange] + } const versions = [...this.advisories][0].versions const range = this.range @@ -171,12 +181,14 @@ class Vuln { } isVulnerable (node) { - if (this.nodes.has(node)) + if (this.nodes.has(node)) { return true + } const { version } = node.package - if (!version) + if (!version) { return false + } for (const v of this.advisories) { if (v.testVersion(version)) { diff --git a/node_modules/@npmcli/arborist/lib/yarn-lock.js b/node_modules/@npmcli/arborist/lib/yarn-lock.js index e237cc5c6a461..384ba447d72fa 100644 --- a/node_modules/@npmcli/arborist/lib/yarn-lock.js +++ b/node_modules/@npmcli/arborist/lib/yarn-lock.js @@ -82,13 +82,15 @@ class YarnLock { const linere = /([^\r\n]*)\r?\n/gm let match let lineNum = 0 - if (!/\n$/.test(data)) + if (!/\n$/.test(data)) { data += '\n' + } while (match = linere.exec(data)) { const line = match[1] lineNum++ - if (line.charAt(0) === '#') + if (line.charAt(0) === '#') { continue + } if (line === '') { this.endCurrent() continue @@ -117,8 +119,9 @@ class YarnLock { const metadata = this.splitQuoted(line.trimLeft(), ' ') if (metadata.length === 2) { // strip off the legacy shasum hashes - if (metadata[0] === 'resolved') + if (metadata[0] === 'resolved') { metadata[1] = metadata[1].replace(/#.*/, '') + } this.current[metadata[0]] = metadata[1] continue } @@ -141,9 +144,9 @@ class YarnLock { let o = 0 for (let i = 0; i < split.length; i++) { const chunk = split[i] - if (/^".*"$/.test(chunk)) + if (/^".*"$/.test(chunk)) { out[o++] = chunk.trim().slice(1, -1) - else if (/^"/.test(chunk)) { + } else if (/^"/.test(chunk)) { let collect = chunk.trimLeft().slice(1) while (++i < split.length) { const n = split[i] @@ -152,12 +155,14 @@ class YarnLock { if (/[^\\](\\\\)*"$/.test(n)) { collect += n.trimRight().slice(0, -1) break - } else + } else { collect += n + } } out[o++] = collect - } else + } else { out[o++] = chunk.trim() + } } return out } @@ -226,17 +231,19 @@ class YarnLock { // no previous entry for this spec at all, so it's new if (!prev) { // if we saw a match already, then assign this spec to it as well - if (priorEntry) + if (priorEntry) { priorEntry.addSpec(s) - else + } else { newSpecs.push(s) + } continue } const m = match(prev, n) // there was a prior entry, but a different thing. skip this one - if (!m) + if (!m) { continue + } // previous matches, but first time seeing it, so already has this spec. // go ahead and add all the previously unseen specs, though @@ -259,8 +266,9 @@ class YarnLock { // if we never found a matching prior, then this is a whole new thing if (!priorEntry) { const entry = Object.assign(new YarnLockEntry(newSpecs), n) - for (const s of newSpecs) + for (const s of newSpecs) { this.entries.set(s, entry) + } } else { // pick up any new info that we got for this node, so that we can // decorate with integrity/resolved/etc. @@ -270,12 +278,15 @@ class YarnLock { entryDataFromNode (node) { const n = {} - if (node.package.dependencies) + if (node.package.dependencies) { n.dependencies = node.package.dependencies - if (node.package.optionalDependencies) + } + if (node.package.optionalDependencies) { n.optionalDependencies = node.package.optionalDependencies - if (node.version) + } + if (node.version) { n.version = node.version + } if (node.resolved) { n.resolved = consistentResolve( node.resolved, @@ -284,8 +295,9 @@ class YarnLock { true ) } - if (node.integrity) + if (node.integrity) { n.integrity = node.integrity + } return n } diff --git a/node_modules/@npmcli/arborist/package.json b/node_modules/@npmcli/arborist/package.json index 42ec2eca3b310..5d0e31af975d2 100644 --- a/node_modules/@npmcli/arborist/package.json +++ b/node_modules/@npmcli/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "2.8.2", + "version": "2.8.3", "description": "Manage node_modules trees", "dependencies": { "@npmcli/installed-package-contents": "^1.0.7", @@ -36,13 +36,9 @@ "walk-up-path": "^1.0.0" }, "devDependencies": { + "@npmcli/lint": "^1.0.2", "benchmark": "^2.1.4", "chalk": "^4.1.0", - "eslint": "^7.9.0", - "eslint-plugin-import": "^2.22.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.1", "minify-registry-metadata": "^2.1.0", "tap": "^15.0.9", "tcompare": "^5.0.6" @@ -50,18 +46,19 @@ "scripts": { "test": "npm run test-only --", "test-only": "tap", - "posttest": "npm run lint", + "posttest": "npm run lint --", "snap": "tap", - "postsnap": "npm run lintfix", + "postsnap": "npm run lintfix --", "test-proxy": "ARBORIST_TEST_PROXY=1 tap --snapshot", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", "eslint": "eslint", - "lint": "npm run eslint -- \"lib/**/*.js\" \"test/arborist/*.js\" \"test/*.js\" \"bin/**/*.js\"", + "lint": "npm run npmclilint -- \"lib/**/*.*js\" \"bin/**/*.*js\" \"test/*.*js\" \"test/arborist/*.*js\"", "lintfix": "npm run lint -- --fix", "benchmark": "node scripts/benchmark.js", - "benchclean": "rm -rf scripts/benchmark/*/" + "benchclean": "rm -rf scripts/benchmark/*/", + "npmclilint": "npmcli-lint" }, "repository": { "type": "git", diff --git a/package-lock.json b/package-lock.json index f6d1f71862d1a..bf0747bbaf470 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "packages/*" ], "dependencies": { - "@npmcli/arborist": "^2.8.2", + "@npmcli/arborist": "^2.8.3", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^2.3.0", "@npmcli/map-workspaces": "^1.0.4", @@ -762,9 +762,9 @@ } }, "node_modules/@npmcli/arborist": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.2.tgz", - "integrity": "sha512-6E1XJ0YXBaI9J+25gcTF110MGNx3jv6npr4Rz1U0UAqkuVV7bbDznVJvNqi6F0p8vgrE+Smf9jDTn1DR+7uBjQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.3.tgz", + "integrity": "sha512-miFcxbZjmQqeFTeRSLLh+lc/gxIKDO5L4PVCp+dp+kmcwJmYsEJmF7YvHR2yi3jF+fxgvLf3CCFzboPIXAuabg==", "inBundle": true, "dependencies": { "@npmcli/installed-package-contents": "^1.0.7", @@ -11009,9 +11009,9 @@ "dev": true }, "@npmcli/arborist": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.2.tgz", - "integrity": "sha512-6E1XJ0YXBaI9J+25gcTF110MGNx3jv6npr4Rz1U0UAqkuVV7bbDznVJvNqi6F0p8vgrE+Smf9jDTn1DR+7uBjQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.3.tgz", + "integrity": "sha512-miFcxbZjmQqeFTeRSLLh+lc/gxIKDO5L4PVCp+dp+kmcwJmYsEJmF7YvHR2yi3jF+fxgvLf3CCFzboPIXAuabg==", "requires": { "@npmcli/installed-package-contents": "^1.0.7", "@npmcli/map-workspaces": "^1.0.2", diff --git a/package.json b/package.json index 1158e3b9d0d5d..7d411a7f86d12 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@npmcli/arborist": "^2.8.2", + "@npmcli/arborist": "^2.8.3", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^2.3.0", "@npmcli/map-workspaces": "^1.0.4", From b0fe9e1c57b87dad113dfa291f0b2a07472a25e9 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Thu, 2 Sep 2021 12:46:59 -0700 Subject: [PATCH 10/35] docs: changelog for v7.22.0 --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d140cf5561d8a..2d9de01e553d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ +## v7.22.0 (2021-09-02) + +### BUG FIXES +* [`6f431fe23`](https://github.com/npm/cli/commit/6f431fe2325f77b4370f95848359a36fe7a011d1) + [#3690](https://github.com/npm/cli/issues/3690) + Fix one “see also” link + ([@tripu](https://github.com/tripu)) + +### DEPENDENCIES +* [`033e948c9`](https://github.com/npm/cli/commit/033e948c95b3455812e03a860ad1bd96a635e7eb) + `read-package-json@4.1.1`: + * feat: add types lookup + * fix(man): don't lose relative man path +* [`1fa549db0`](https://github.com/npm/cli/commit/1fa549db0955b55fd680a658809a6d97be306b06) + `@npmcli/config@2.3.0`: + * feat: export npm_config_local_prefix and npm_config_global_prefix to the environment +* [`e91578d10`](https://github.com/npm/cli/commit/e91578d10b1d5d930fec32e7070d975af4892140) + `minpass-fetch@1.4.1`: + * Made rejectUnauthorized depend on NODE_TLS_REJECT_UNAUTHORIZED +* [`6125db545`](https://github.com/npm/cli/commit/6125db545315da0217fe7b05062fd0a504c9a45b) + `are-we-there-yet@1.1.6` +* [`0dcda73b0`](https://github.com/npm/cli/commit/0dcda73b022083338c4cb755390a275757b9627b) + `string_decoder@1.3.0` +* [`4b913417c`](https://github.com/npm/cli/commit/4b913417c4e30980505a02eec50810f895dd52d7) + `npmlog@5.0.1` +* [`876c755eb`](https://github.com/npm/cli/commit/876c755eb0dfc215123682f798b5fca415f7c7d9) + `@npmcli/arborist@2.8.3`: + * fix: do not fail adding unresolvable optional dep + ## v7.21.1 (2021-08-26) ### BUG FIXES From d59e2eeb2e915214965eddd5443a255cb0646dab Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Thu, 2 Sep 2021 12:47:18 -0700 Subject: [PATCH 11/35] update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 0c66973b84d03..0c15af1db20cc 100644 --- a/AUTHORS +++ b/AUTHORS @@ -792,3 +792,4 @@ Demira Dimitrova AkiJoey austincho Nathan Fritz +tripu <1016538+tripu@users.noreply.github.com> From d6c651c050634a89f25846340a440dfb49755f82 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Thu, 2 Sep 2021 12:47:19 -0700 Subject: [PATCH 12/35] 7.22.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf0747bbaf470..9abe13a85d668 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "npm", - "version": "7.21.1", + "version": "7.22.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "npm", - "version": "7.21.1", + "version": "7.22.0", "bundleDependencies": [ "@npmcli/arborist", "@npmcli/ci-detect", diff --git a/package.json b/package.json index 7d411a7f86d12..e0363a49bf52e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "7.21.1", + "version": "7.22.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ From 64f7d1a55db99b1aaf8fb59557b3dedcdcd954a0 Mon Sep 17 00:00:00 2001 From: Darcy Clarke Date: Wed, 8 Sep 2021 12:08:03 -0400 Subject: [PATCH 13/35] docs(contributing): add note on changes to tooling PR-URL: https://github.com/npm/cli/pull/3727 Credit: @darcyclarke Close: #3727 Reviewed-by: @wraithgar --- CONTRIBUTING.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec1c513864c1b..5ee9b45608eab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,10 @@ All interactions in the **npm** organization on GitHub are considered to be covered by our standard [Code of Conduct](https://docs.npmjs.com/policies/conduct). +## Reporting Bugs + +When submitting a new bug report, please first [search](https://github.com/npm/cli/issues) for an existing or similar report & then use one of our existing [issue templates](https://github.com/npm/cli/issues/new/choose) if you believe you've come across a unique problem. Duplicate issues, or issues that don't use one of our templates may get closed without a response. + ## Development **1. Clone this repository...** @@ -33,7 +37,7 @@ $ npm run test ## Test Coverage -We expect that every new feature or bug fix comes with corresponding tests that validate the solutions. We strive to have as close to, if not exactly, 100% code coverage. +We use [`tap`](https://node-tap.org/) for testing & expect that every new feature or bug fix comes with corresponding tests that validate the solutions. We strive to have as close to, if not exactly, 100% code coverage. **You can find out what the current test coverage percentage is by running...** @@ -51,10 +55,12 @@ We've set up an automated [benchmark](https://github.com/npm/benchmarks) integra You can learn more about this tool, including how to run & configure it manually, [here](https://github.com/npm/benchmarks) -## Dependency Updates +## What _not_ to contribute? + +### Dependencies It should be noted that our team does not accept third-party dependency updates/PRs. We have a [release process](https://github.com/npm/cli/wiki/Release-Process) that includes checks to ensure dependencies are staying up-to-date & will ship security patches for CVEs as they occur. If you submit a PR trying to update our dependencies we will close it with or without a reference to these contribution guidelines. -## Reporting Bugs +### Tools/Automation -When submitting a new bug report, please first [search](https://github.com/npm/cli/issues) for an existing or similar report & then use one of our existing [issue templates](https://github.com/npm/cli/issues/new/choose) if you believe you've come across a unique problem. Duplicate issues, or issues that don't use one of our templates may get closed without a response. +Our core team is responsible for the maintaince of the tooling/automation in this project & we ask collaborators to kindle not make changes to these when contributing (ex. `.github/*`, `.eslintrc.json`, `.licensee.json` etc.) From eda9162f2db19b512d3af6b0d43201d54045c13a Mon Sep 17 00:00:00 2001 From: Matsuuu Date: Fri, 3 Sep 2021 09:01:08 +0300 Subject: [PATCH 14/35] docs: Add --if-present flag documentation to workspaces PR-URL: https://github.com/npm/cli/pull/3715 Credit: @Matsuuu Close: #3715 Reviewed-by: @wraithgar --- docs/content/using-npm/workspaces.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/content/using-npm/workspaces.md b/docs/content/using-npm/workspaces.md index 7cc125b3c7a7c..ae834c0cc7e22 100644 --- a/docs/content/using-npm/workspaces.md +++ b/docs/content/using-npm/workspaces.md @@ -176,6 +176,16 @@ npm run test --workspaces Will run the `test` script in both `./packages/a` and `./packages/b`. +### Ignoring missing scripts + +It is not required for all of the workspaces to implement scripts run with the `npm run` command. + +By running the command with the `--if-present` flag, npm will ignore workspaces missing target script. + +``` +npm run test --workspaces --if-present +``` + ### See also * [npm install](/commands/npm-install) From 1ad0938243110d983284e8763da41a57b561563d Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 11:14:04 -0700 Subject: [PATCH 15/35] fix(error-message): clean urls from 404 error If the package being installed is a url it needs to be cleaned before logging so passwords aren't potentially logged. PR-URL: https://github.com/npm/cli/pull/3732 Credit: @wraithgar Close: #3732 Reviewed-by: @nlf --- lib/utils/error-message.js | 2 +- .../test/lib/utils/error-message.js.test.cjs | 48 +++++++++++++++++-- test/lib/utils/error-message.js | 8 ++++ 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/lib/utils/error-message.js b/lib/utils/error-message.js index da97195dd04f0..6e12bcb918eef 100644 --- a/lib/utils/error-message.js +++ b/lib/utils/error-message.js @@ -181,7 +181,7 @@ module.exports = (er, npm) => { const pkg = er.pkgid.replace(/(?!^)@.*$/, '') detail.push(['404', '']) - detail.push(['404', '', "'" + er.pkgid + "' is not in the npm registry."]) + detail.push(['404', '', `'${replaceInfo(er.pkgid)}' is not in this registry.`]) const valResult = nameValidator(pkg) diff --git a/tap-snapshots/test/lib/utils/error-message.js.test.cjs b/tap-snapshots/test/lib/utils/error-message.js.test.cjs index e8f817cd15f00..1f73361c48589 100644 --- a/tap-snapshots/test/lib/utils/error-message.js.test.cjs +++ b/tap-snapshots/test/lib/utils/error-message.js.test.cjs @@ -5,6 +5,48 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' +exports[`test/lib/utils/error-message.js TAP 404 cleans sensitive info from package id > must match snapshot 1`] = ` +Object { + "detail": Array [ + Array [ + "404", + "", + ], + Array [ + "404", + "", + "'http://evil:***@npmjs.org/not-found' is not in this registry.", + ], + Array [ + "404", + "This package name is not valid, because", + "", + ], + Array [ + "404", + " 1. name can only contain URL-friendly characters", + ], + Array [ + "404", + String( + + Note that you can also install from a + ), + ], + Array [ + "404", + "tarball, folder, http url, or git url.", + ], + ], + "summary": Array [ + Array [ + "404", + "not found", + ], + ], +} +` + exports[`test/lib/utils/error-message.js TAP 404 name with error > must match snapshot 1`] = ` Object { "detail": Array [ @@ -15,7 +57,7 @@ Object { Array [ "404", "", - "'node_modules' is not in the npm registry.", + "'node_modules' is not in this registry.", ], Array [ "404", @@ -57,7 +99,7 @@ Object { Array [ "404", "", - "'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' is not in the npm registry.", + "'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' is not in this registry.", ], Array [ "404", @@ -111,7 +153,7 @@ Object { Array [ "404", "", - "'yolo' is not in the npm registry.", + "'yolo' is not in this registry.", ], Array [ "404", diff --git a/test/lib/utils/error-message.js b/test/lib/utils/error-message.js index 07328d588759b..d1c67a95137c4 100644 --- a/test/lib/utils/error-message.js +++ b/test/lib/utils/error-message.js @@ -423,6 +423,14 @@ t.test('404', t => { t.matchSnapshot(errorMessage(er, npm)) t.end() }) + t.test('cleans sensitive info from package id', t => { + const er = Object.assign(new Error('404 not found'), { + pkgid: 'http://evil:password@npmjs.org/not-found', + code: 'E404', + }) + t.matchSnapshot(errorMessage(er, npm)) + t.end() + }) t.end() }) From 6c12500ae14a6f8b78e3ab091ee6cc8e2ea9fd23 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 08:21:56 -0700 Subject: [PATCH 16/35] feat(install): very strict global npm engines This will do an engines check when installing npm globally and fail if the new npm is known not to work in the current node version. It will not work for older npm versions because they don't have an engines field (it wasn't added till npm@6.14.0). It will at least prevent npm@7 from being installed in node@8. PR-URL: https://github.com/npm/cli/pull/3731 Credit: @wraithgar Close: #3731 Reviewed-by: @nlf --- lib/install.js | 22 ++++++- package-lock.json | 1 + package.json | 1 + test/lib/install.js | 140 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 2 deletions(-) diff --git a/lib/install.js b/lib/install.js index 6611763978e61..1589ff589c38e 100644 --- a/lib/install.js +++ b/lib/install.js @@ -8,6 +8,8 @@ const log = require('npmlog') const { resolve, join } = require('path') const Arborist = require('@npmcli/arborist') const runScript = require('@npmcli/run-script') +const pacote = require('pacote') +const checks = require('npm-install-checks') const ArboristWorkspaceCmd = require('./workspaces/arborist-cmd.js') class Install extends ArboristWorkspaceCmd { @@ -126,6 +128,23 @@ class Install extends ArboristWorkspaceCmd { const ignoreScripts = this.npm.config.get('ignore-scripts') const isGlobalInstall = this.npm.config.get('global') const where = isGlobalInstall ? globalTop : this.npm.prefix + const forced = this.npm.config.get('force') + const isDev = this.npm.config.get('dev') + const scriptShell = this.npm.config.get('script-shell') || undefined + + // be very strict about engines when trying to update npm itself + const npmInstall = args.find(arg => arg.startsWith('npm@') || arg === 'npm') + if (isGlobalInstall && npmInstall) { + const npmManifest = await pacote.manifest(npmInstall) + try { + checks.checkEngine(npmManifest, npmManifest.version, process.version) + } catch (e) { + if (forced) + this.npm.log.warn('install', `Forcing global npm install with incompatible version ${npmManifest.version} into node ${process.version}`) + else + throw e + } + } // don't try to install the prefix into itself args = args.filter(a => resolve(a) !== this.npm.prefix) @@ -135,7 +154,7 @@ class Install extends ArboristWorkspaceCmd { args = ['.'] // TODO: Add warnings for other deprecated flags? or remove this one? - if (this.npm.config.get('dev')) + if (isDev) log.warn('install', 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.') const opts = { @@ -150,7 +169,6 @@ class Install extends ArboristWorkspaceCmd { await arb.reify(opts) if (!args.length && !isGlobalInstall && !ignoreScripts) { - const scriptShell = this.npm.config.get('script-shell') || undefined const scripts = [ 'preinstall', 'install', diff --git a/package-lock.json b/package-lock.json index 9abe13a85d668..8546bd714d204 100644 --- a/package-lock.json +++ b/package-lock.json @@ -127,6 +127,7 @@ "node-gyp": "^7.1.2", "nopt": "^5.0.0", "npm-audit-report": "^2.1.5", + "npm-install-checks": "^4.0.0", "npm-package-arg": "^8.1.5", "npm-pick-manifest": "^6.1.1", "npm-profile": "^5.0.3", diff --git a/package.json b/package.json index e0363a49bf52e..4531d1508fbe0 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "node-gyp": "^7.1.2", "nopt": "^5.0.0", "npm-audit-report": "^2.1.5", + "npm-install-checks": "^4.0.0", "npm-package-arg": "^8.1.5", "npm-pick-manifest": "^6.1.1", "npm-profile": "^5.0.3", diff --git a/test/lib/install.js b/test/lib/install.js index 6412b34c16f25..2cbee02e67b28 100644 --- a/test/lib/install.js +++ b/test/lib/install.js @@ -126,6 +126,146 @@ t.test('should install globally using Arborist', (t) => { }) }) +t.test('npm i -g npm engines check success', (t) => { + const Install = t.mock('../../lib/install.js', { + '../../lib/utils/reify-finish.js': async () => {}, + '@npmcli/arborist': function () { + this.reify = () => {} + }, + pacote: { + manifest: () => { + return { + version: '100.100.100', + engines: { + node: '>1', + }, + } + }, + }, + }) + const npm = mockNpm({ + globalDir: 'path/to/node_modules/', + config: { + global: true, + }, + }) + const install = new Install(npm) + install.exec(['npm'], er => { + if (er) + throw er + t.end() + }) +}) + +t.test('npm i -g npm engines check failure', (t) => { + const Install = t.mock('../../lib/install.js', { + pacote: { + manifest: () => { + return { + _id: 'npm@1.2.3', + version: '100.100.100', + engines: { + node: '>1000', + }, + } + }, + }, + }) + const npm = mockNpm({ + globalDir: 'path/to/node_modules/', + config: { + global: true, + }, + }) + const install = new Install(npm) + install.exec(['npm'], er => { + t.match(er, { + message: 'Unsupported engine', + pkgid: 'npm@1.2.3', + current: { + node: process.version, + npm: '100.100.100', + }, + required: { + node: '>1000', + }, + code: 'EBADENGINE', + }) + t.end() + }) +}) + +t.test('npm i -g npm engines check failure forced override', (t) => { + const Install = t.mock('../../lib/install.js', { + '../../lib/utils/reify-finish.js': async () => {}, + '@npmcli/arborist': function () { + this.reify = () => {} + }, + pacote: { + manifest: () => { + return { + _id: 'npm@1.2.3', + version: '100.100.100', + engines: { + node: '>1000', + }, + } + }, + }, + }) + const npm = mockNpm({ + globalDir: 'path/to/node_modules/', + config: { + force: true, + global: true, + }, + }) + const install = new Install(npm) + install.exec(['npm'], er => { + if (er) + throw er + t.end() + }) +}) + +t.test('npm i -g npm@version engines check failure', (t) => { + const Install = t.mock('../../lib/install.js', { + pacote: { + manifest: () => { + return { + _id: 'npm@1.2.3', + version: '100.100.100', + engines: { + node: '>1000', + }, + } + }, + }, + }) + const npm = mockNpm({ + globalDir: 'path/to/node_modules/', + config: { + global: true, + }, + }) + const install = new Install(npm) + install.exec(['npm@100'], er => { + t.match(er, { + message: 'Unsupported engine', + pkgid: 'npm@1.2.3', + current: { + node: process.version, + npm: '100.100.100', + }, + required: { + node: '>1000', + }, + code: 'EBADENGINE', + }) + t.end() + }) +}) + t.test('completion to folder', async t => { const Install = t.mock('../../lib/install.js', { '../../lib/utils/reify-finish.js': async () => {}, From 91a5181d432ed20a9884e3f3ec6602fe8c1fb61d Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 12:43:23 -0700 Subject: [PATCH 17/35] docs: changelog for v7.23.0 --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d9de01e553d7..c591cd2ac559b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +## v7.23.0 (2021-09-09) + +### FEATURES + +* [`6c12500ae`](https://github.com/npm/cli/commit/6c12500ae14a6f8b78e3ab091ee6cc8e2ea9fd23) + [#3731](https://github.com/npm/cli/issues/3731) + feat(install): very strict global npm engines + ([@wraithgar](https://github.com/wraithgar)) + +### BUG FIXES + +* [`1ad093824`](https://github.com/npm/cli/commit/1ad0938243110d983284e8763da41a57b561563d) + [#3732](https://github.com/npm/cli/issues/3732) + fix(error-message): clean urls from 404 error + ([@wraithgar](https://github.com/wraithgar)) + +### DOCUMENTATION + +* [`64f7d1a55`](https://github.com/npm/cli/commit/64f7d1a55db99b1aaf8fb59557b3dedcdcd954a0) + [#3727](https://github.com/npm/cli/issues/3727) + docs(contributing): add note on changes to tooling + ([@darcyclarke](https://github.com/darcyclarke)) +* [`eda9162f2`](https://github.com/npm/cli/commit/eda9162f2db19b512d3af6b0d43201d54045c13a) + [#3715](https://github.com/npm/cli/issues/3715) + Add --if-present flag documentation to workspaces + ([@Matsuuu](https://github.com/Matsuuu)) + ## v7.22.0 (2021-09-02) ### BUG FIXES From e962020ebe8063ba6af41ee7602427ec95ab5361 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 12:43:33 -0700 Subject: [PATCH 18/35] update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 0c15af1db20cc..c204352764831 100644 --- a/AUTHORS +++ b/AUTHORS @@ -793,3 +793,4 @@ AkiJoey austincho Nathan Fritz tripu <1016538+tripu@users.noreply.github.com> +Matsuuu From d57b43db38211c6e37ed4482d81ca75ad9654cf0 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 12:43:33 -0700 Subject: [PATCH 19/35] 7.23.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8546bd714d204..ed4ce37cde425 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "npm", - "version": "7.22.0", + "version": "7.23.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "npm", - "version": "7.22.0", + "version": "7.23.0", "bundleDependencies": [ "@npmcli/arborist", "@npmcli/ci-detect", diff --git a/package.json b/package.json index 4531d1508fbe0..3459c81ccf190 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "7.22.0", + "version": "7.23.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ From c7787b3fb7630aab84aae83ebf9a7117c7173b6b Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 12:56:36 -0700 Subject: [PATCH 20/35] chore: bundle npm-install-checks This is already part of the published npm, just not in git --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 3459c81ccf190..20b80c7ebe21c 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,7 @@ "node-gyp", "nopt", "npm-audit-report", + "npm-install-checks", "npm-package-arg", "npm-pick-manifest", "npm-profile", From 1fbbe1e04be5d79c7b49910324e64c19ed599eeb Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 13:14:21 -0700 Subject: [PATCH 21/35] chore: bundled npm-install-checks in lockfile too --- package-lock.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package-lock.json b/package-lock.json index ed4ce37cde425..852dc51752ea5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,7 @@ "node-gyp", "nopt", "npm-audit-report", + "npm-install-checks", "npm-package-arg", "npm-pick-manifest", "npm-profile", From ac8e4ad18a6b726dd2c3abcb0f605701cca0ae2c Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 9 Sep 2021 14:05:14 -0700 Subject: [PATCH 22/35] deps: init-package-json@2.0.5 * fix: bin script path --- node_modules/init-package-json/LICENSE | 15 -- node_modules/init-package-json/LICENSE.md | 18 ++ .../{ => lib}/default-input.js | 177 ++++++++++++------ .../{ => lib}/init-package-json.js | 66 ++++--- node_modules/init-package-json/package.json | 34 ++-- package-lock.json | 24 ++- package.json | 2 +- 7 files changed, 207 insertions(+), 129 deletions(-) delete mode 100644 node_modules/init-package-json/LICENSE create mode 100644 node_modules/init-package-json/LICENSE.md rename node_modules/init-package-json/{ => lib}/default-input.js (64%) rename node_modules/init-package-json/{ => lib}/init-package-json.js (79%) diff --git a/node_modules/init-package-json/LICENSE b/node_modules/init-package-json/LICENSE deleted file mode 100644 index 05eeeb88c2ef4..0000000000000 --- a/node_modules/init-package-json/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/init-package-json/LICENSE.md b/node_modules/init-package-json/LICENSE.md new file mode 100644 index 0000000000000..845be76f64e78 --- /dev/null +++ b/node_modules/init-package-json/LICENSE.md @@ -0,0 +1,18 @@ +ISC License + +Copyright npm, Inc. + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/init-package-json/default-input.js b/node_modules/init-package-json/lib/default-input.js similarity index 64% rename from node_modules/init-package-json/default-input.js rename to node_modules/init-package-json/lib/default-input.js index d1f65841d6c5a..0003472975760 100644 --- a/node_modules/init-package-json/default-input.js +++ b/node_modules/init-package-json/lib/default-input.js @@ -1,5 +1,5 @@ +/* eslint-disable no-undef */ var fs = require('fs') -var glob = require('glob') var path = require('path') var validateLicense = require('validate-npm-package-license') var validateName = require('validate-npm-package-name') @@ -15,35 +15,57 @@ function niceName (n) { return n.replace(/^node-|[.-]js$/g, '').replace(/\s+/g, ' ').replace(/ /g, '-').toLowerCase() } -function readDeps (test, excluded) { return function (cb) { - fs.readdir('node_modules', function (er, dir) { - if (er) return cb() - var deps = {} - var n = dir.length - if (n === 0) return cb(null, deps) - dir.forEach(function (d) { - if (d.match(/^\./)) return next() - if (test !== isTestPkg(d) || excluded[d]) - return next() - - var dp = path.join(dirname, 'node_modules', d, 'package.json') - fs.readFile(dp, 'utf8', function (er, p) { - if (er) return next() - try { p = JSON.parse(p) } - catch (e) { return next() } - if (!p.version) return next() - if (p._requiredBy) { - if (!p._requiredBy.some(function (req) { return req === '#USER' })) return next() +function readDeps (test, excluded) { + return function (cb) { + fs.readdir('node_modules', function (er, dir) { + if (er) { + return cb() + } + var deps = {} + var n = dir.length + if (n === 0) { + return cb(null, deps) + } + dir.forEach(function (d) { + if (d.match(/^\./)) { + return next() + } + if (test !== isTestPkg(d) || excluded[d]) { + return next() } - deps[d] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version - return next() + + var dp = path.join(dirname, 'node_modules', d, 'package.json') + fs.readFile(dp, 'utf8', function (er, p) { + if (er) { + return next() + } + try { + p = JSON.parse(p) + } catch (e) { + return next() + } + if (!p.version) { + return next() + } + if (p._requiredBy) { + if (!p._requiredBy.some(function (req) { + return req === '#USER' + })) { + return next() + } + } + deps[d] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version + return next() + }) }) + function next () { + if (--n === 0) { + return cb(null, deps) + } + } }) - function next () { - if (--n === 0) return cb(null, deps) - } - }) -}} + } +} var name = niceName(package.name || basename) var spec @@ -54,16 +76,20 @@ try { } var scope = config.get('scope') if (scope) { - if (scope.charAt(0) !== '@') scope = '@' + scope + if (scope.charAt(0) !== '@') { + scope = '@' + scope + } if (spec.scope) { name = scope + '/' + spec.name.split('/')[1] } else { name = scope + '/' + name } } -exports.name = yes ? name : prompt('package name', name, function (data) { +exports.name = yes ? name : prompt('package name', name, function (data) { var its = validateName(data) - if (its.validForNewPackages) return data + if (its.validForNewPackages) { + return data + } var errors = (its.errors || []).concat(its.warnings || []) var er = new Error('Sorry, ' + errors.join(' and ') + '.') er.notValid = true @@ -83,7 +109,9 @@ var version = package.version || exports.version = yes ? version : prompt('version', version, function (version) { - if (semver.valid(version)) return version + if (semver.valid(version)) { + return version + } var er = new Error('Invalid version: "' + version + '"') er.notValid = true return er @@ -96,22 +124,25 @@ if (!package.description) { if (!package.main) { exports.main = function (cb) { fs.readdir(dirname, function (er, f) { - if (er) f = [] + if (er) { + f = [] + } f = f.filter(function (f) { return f.match(/\.js$/) }) - if (f.indexOf('index.js') !== -1) + if (f.indexOf('index.js') !== -1) { f = 'index.js' - else if (f.indexOf('main.js') !== -1) + } else if (f.indexOf('main.js') !== -1) { f = 'main.js' - else if (f.indexOf(basename + '.js') !== -1) + } else if (f.indexOf(basename + '.js') !== -1) { f = basename + '.js' - else + } else { f = f[0] + } - var index = f || 'index.js' + var index = f || 'index.js' return cb(null, yes ? index : prompt('entry point', index)) }) } @@ -121,18 +152,24 @@ if (!package.bin) { exports.bin = function (cb) { fs.readdir(path.resolve(dirname, 'bin'), function (er, d) { // no bins - if (er) return cb() + if (er) { + return cb() + } // just take the first js file we find there, or nada - return cb(null, d.filter(function (f) { - return f.match(/\.js$/) - })[0]) + let r = d.find(f => f.match(/\.js$/)) + if (r) { + r = `bin/${r}` + } + return cb(null, r) }) } } exports.directories = function (cb) { fs.readdir(dirname, function (er, dirs) { - if (er) return cb(er) + if (er) { + return cb(er) + } var res = {} dirs.forEach(function (d) { switch (d) { @@ -143,7 +180,9 @@ exports.directories = function (cb) { case 'lib': return res.lib = d } }) - if (Object.keys(res).length === 0) res = undefined + if (Object.keys(res).length === 0) { + res = undefined + } return cb(null, res) }) } @@ -173,13 +212,15 @@ function setupScripts (d, cb) { } if (!s.test || s.test === notest) { var commands = { - 'tap':'tap test/*.js' - , 'expresso':'expresso test' - , 'mocha':'mocha' + tap: 'tap test/*.js', + expresso: 'expresso test', + mocha: 'mocha', } var command Object.keys(commands).forEach(function (k) { - if (d.indexOf(k) !== -1) command = commands[k] + if (d.indexOf(k) !== -1) { + command = commands[k] + } }) var ps = 'test command' if (yes) { @@ -201,12 +242,18 @@ if (!package.repository) { var i = gconf.indexOf('[remote "origin"]') if (i !== -1) { var u = gconf[i + 1] - if (!u.match(/^\s*url =/)) u = gconf[i + 2] - if (!u.match(/^\s*url =/)) u = null - else u = u.replace(/^\s*url = /, '') + if (!u.match(/^\s*url =/)) { + u = gconf[i + 2] + } + if (!u.match(/^\s*url =/)) { + u = null + } else { + u = u.replace(/^\s*url = /, '') + } } - if (u && u.match(/^git@github.com:/)) + if (u && u.match(/^git@github.com:/)) { u = u.replace(/^git@github.com:/, 'https://github.com/') + } return cb(null, yes ? u : prompt('git repository', u)) }) @@ -215,9 +262,15 @@ if (!package.repository) { if (!package.keywords) { exports.keywords = yes ? '' : prompt('keywords', function (s) { - if (!s) return undefined - if (Array.isArray(s)) s = s.join(' ') - if (typeof s !== 'string') return s + if (!s) { + return undefined + } + if (Array.isArray(s)) { + s = s.join(' ') + } + if (typeof s !== 'string') { + return s + } return s.split(/[\s,]+/) }) } @@ -225,15 +278,15 @@ if (!package.keywords) { if (!package.author) { exports.author = config.get('init.author.name') || config.get('init-author-name') - ? { - "name" : config.get('init.author.name') || + ? { + name: config.get('init.author.name') || config.get('init-author-name'), - "email" : config.get('init.author.email') || + email: config.get('init.author.email') || config.get('init-author-email'), - "url" : config.get('init.author.url') || - config.get('init-author-url') + url: config.get('init.author.url') || + config.get('init-author-url'), } - : yes ? '' : prompt('author') + : yes ? '' : prompt('author') } const defaultDottedInitLicense = config && @@ -248,7 +301,9 @@ var license = package.license || 'ISC' exports.license = yes ? license : prompt('license', license, function (data) { var its = validateLicense(data) - if (its.validForNewPackages) return data + if (its.validForNewPackages) { + return data + } var errors = (its.errors || []).concat(its.warnings || []) var er = new Error('Sorry, ' + errors.join(' and ') + '.') er.notValid = true diff --git a/node_modules/init-package-json/init-package-json.js b/node_modules/init-package-json/lib/init-package-json.js similarity index 79% rename from node_modules/init-package-json/init-package-json.js rename to node_modules/init-package-json/lib/init-package-json.js index 83e7342d0aa4f..bee79351caab3 100644 --- a/node_modules/init-package-json/init-package-json.js +++ b/node_modules/init-package-json/lib/init-package-json.js @@ -12,7 +12,6 @@ var read = require('read') // to validate the data object at the end as a worthwhile package // and assign default values for things. -// readJson.extras(file, data, cb) var readJson = require('read-package-json') function yes (conf) { @@ -23,8 +22,10 @@ function yes (conf) { } function init (dir, input, config, cb) { - if (typeof config === 'function') - cb = config, config = {} + if (typeof config === 'function') { + cb = config + config = {} + } // accept either a plain-jane object, or a config object // with a "get" method. @@ -36,7 +37,7 @@ function init (dir, input, config, cb) { }, toJSON: function () { return data - } + }, } } @@ -52,14 +53,18 @@ function init (dir, input, config, cb) { readJson(packageFile, function (er, d) { readJson.extraSet = es - if (er) pkg = {} - else pkg = d + if (er) { + pkg = {} + } else { + pkg = d + } ctx.filename = packageFile ctx.dirname = path.dirname(packageFile) ctx.basename = path.basename(ctx.dirname) - if (!pkg.version || !semver.valid(pkg.version)) + if (!pkg.version || !semver.valid(pkg.version)) { delete pkg.version + } ctx.package = pkg ctx.config = config || {} @@ -71,7 +76,9 @@ function init (dir, input, config, cb) { pz.on('error', cb) pz.on('data', function (data) { Object.keys(data).forEach(function (k) { - if (data[k] !== undefined && data[k] !== null) pkg[k] = data[k] + if (data[k] !== undefined && data[k] !== null) { + pkg[k] = data[k] + } }) // only do a few of these. @@ -81,8 +88,10 @@ function init (dir, input, config, cb) { return fn.name !== 'authors' && fn.name !== 'mans' }) readJson.extras(packageFile, pkg, function (er, pkg) { + if (er) { + return cb(er, pkg) + } readJson.extraSet = es - if (er) return cb(er, pkg) pkg = unParsePeople(pkg) // no need for the readme now. delete pkg.readme @@ -95,13 +104,15 @@ function init (dir, input, config, cb) { delete pkg.gitHead // if the repo is empty, remove it. - if (!pkg.repository) + if (!pkg.repository) { delete pkg.repository + } // readJson filters out empty descriptions, but init-package-json // traditionally leaves them alone - if (!pkg.description) + if (!pkg.description) { pkg.description = data.description + } var d = JSON.stringify(updateDeps(pkg), null, 2) + '\n' function write (yes) { @@ -116,7 +127,7 @@ function init (dir, input, config, cb) { return write(true) } console.log('About to write to %s:\n\n%s\n', packageFile, d) - read({prompt:'Is this OK? ', default: 'yes'}, function (er, ok) { + read({prompt: 'Is this OK? ', default: 'yes'}, function (er, ok) { if (er) { return cb(er) } @@ -129,18 +140,19 @@ function init (dir, input, config, cb) { }) }) }) - } -function updateDeps(depsData) { +function updateDeps (depsData) { // optionalDependencies don't need to be repeated in two places if (depsData.dependencies) { if (depsData.optionalDependencies) { - for (const name of Object.keys(depsData.optionalDependencies)) + for (const name of Object.keys(depsData.optionalDependencies)) { delete depsData.dependencies[name] + } } - if (Object.keys(depsData.dependencies).length === 0) + if (Object.keys(depsData.dependencies).length === 0) { delete depsData.dependencies + } } return depsData @@ -148,21 +160,25 @@ function updateDeps(depsData) { // turn the objects into somewhat more humane strings. function unParsePeople (data) { - if (data.author) data.author = unParsePerson(data.author) - ;["maintainers", "contributors"].forEach(function (set) { - if (!Array.isArray(data[set])) return; + if (data.author) { + data.author = unParsePerson(data.author) + }['maintainers', 'contributors'].forEach(function (set) { + if (!Array.isArray(data[set])) { + return + } data[set] = data[set].map(unParsePerson) }) return data } function unParsePerson (person) { - if (typeof person === "string") return person - var name = person.name || "" + if (typeof person === 'string') { + return person + } + var name = person.name || '' var u = person.url || person.web - var url = u ? (" ("+u+")") : "" + var url = u ? (' (' + u + ')') : '' var e = person.email || person.mail - var email = e ? (" <"+e+">") : "" - return name+email+url + var email = e ? (' <' + e + '>') : '' + return name + email + url } - diff --git a/node_modules/init-package-json/package.json b/node_modules/init-package-json/package.json index 0e07f48f49746..6d642f6cf6879 100644 --- a/node_modules/init-package-json/package.json +++ b/node_modules/init-package-json/package.json @@ -1,41 +1,46 @@ { "name": "init-package-json", - "version": "2.0.4", - "main": "init-package-json.js", + "version": "2.0.5", + "main": "lib/init-package-json.js", "scripts": { "test": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "prepublishOnly": "git push origin --follow-tags", + "lint": "eslint '**/*.js'", + "postlint": "npm-template-check", + "lintfix": "npm run lint -- --fix", + "snap": "tap", + "posttest": "npm run lint" }, "repository": { "type": "git", "url": "https://github.com/npm/init-package-json.git" }, - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "author": "GitHub Inc.", "license": "ISC", "description": "A node module to get your node module started", "dependencies": { - "glob": "^7.1.1", - "npm-package-arg": "^8.1.2", + "npm-package-arg": "^8.1.5", "promzard": "^0.3.0", "read": "~1.0.1", - "read-package-json": "^4.0.0", + "read-package-json": "^4.1.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^3.0.0" }, "devDependencies": { "@npmcli/config": "^2.1.0", - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2", - "tap": "^14.11.0" + "@npmcli/template-oss": "^1.0.3", + "tap": "^15.0.9" }, "engines": { "node": ">=10" }, "tap": { - "jobs": "1" + "statements": "94", + "branches": "83", + "lines": "94" }, "keywords": [ "init", @@ -48,7 +53,8 @@ "start" ], "files": [ - "default-input.js", - "init-package-json.js" - ] + "bin", + "lib" + ], + "templateVersion": "1.0.3" } diff --git a/package-lock.json b/package-lock.json index 852dc51752ea5..8f4a37801185a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -105,7 +105,7 @@ "graceful-fs": "^4.2.8", "hosted-git-info": "^4.0.2", "ini": "^2.0.0", - "init-package-json": "^2.0.4", + "init-package-json": "^2.0.5", "is-cidr": "^4.0.2", "json-parse-even-better-errors": "^2.3.1", "libnpmaccess": "^4.0.2", @@ -3877,16 +3877,15 @@ } }, "node_modules/init-package-json": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.4.tgz", - "integrity": "sha512-gUACSdZYka+VvnF90TsQorC+1joAVWNI724vBNj3RD0LLMeDss2IuzaeiQs0T4YzKs76BPHtrp/z3sn2p+KDTw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.5.tgz", + "integrity": "sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA==", "inBundle": true, "dependencies": { - "glob": "^7.1.1", - "npm-package-arg": "^8.1.2", + "npm-package-arg": "^8.1.5", "promzard": "^0.3.0", "read": "~1.0.1", - "read-package-json": "^4.0.0", + "read-package-json": "^4.1.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^3.0.0" @@ -13318,15 +13317,14 @@ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" }, "init-package-json": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.4.tgz", - "integrity": "sha512-gUACSdZYka+VvnF90TsQorC+1joAVWNI724vBNj3RD0LLMeDss2IuzaeiQs0T4YzKs76BPHtrp/z3sn2p+KDTw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.5.tgz", + "integrity": "sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA==", "requires": { - "glob": "^7.1.1", - "npm-package-arg": "^8.1.2", + "npm-package-arg": "^8.1.5", "promzard": "^0.3.0", "read": "~1.0.1", - "read-package-json": "^4.0.0", + "read-package-json": "^4.1.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^3.0.0" diff --git a/package.json b/package.json index 20b80c7ebe21c..8011f238ac2ff 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "graceful-fs": "^4.2.8", "hosted-git-info": "^4.0.2", "ini": "^2.0.0", - "init-package-json": "^2.0.4", + "init-package-json": "^2.0.5", "is-cidr": "^4.0.2", "json-parse-even-better-errors": "^2.3.1", "libnpmaccess": "^4.0.2", From 59743972c2ae1d2dd601aaa6c59974c686b1cb29 Mon Sep 17 00:00:00 2001 From: Gar Date: Mon, 13 Sep 2021 10:31:02 -0700 Subject: [PATCH 23/35] fix(did-you-mean): succeed if cwd is not a package The did-you-mean code was trying to parse a local package.json to suggest scripts and bins, which was causing an exception if you ran npm outside of a directory with a valid package.json. This fixes that. PR-URL: https://github.com/npm/cli/pull/3747 Credit: @wraithgar Close: #3747 Reviewed-by: @nlf --- lib/utils/did-you-mean.js | 29 +++++++------- test/lib/utils/did-you-mean.js | 71 ++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 39 deletions(-) diff --git a/lib/utils/did-you-mean.js b/lib/utils/did-you-mean.js index 0cfdd035255eb..c324253af2406 100644 --- a/lib/utils/did-you-mean.js +++ b/lib/utils/did-you-mean.js @@ -3,25 +3,26 @@ const readJson = require('read-package-json-fast') const { cmdList } = require('./cmd-list.js') const didYouMean = async (npm, path, scmd) => { - const bestCmd = cmdList + let best = cmdList .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && scmd !== cmd) .map(str => ` npm ${str} # ${npm.commands[str].description}`) - const pkg = await readJson(`${path}/package.json`) - const { scripts } = pkg // We would already be suggesting this in `npm x` so omit them here const runScripts = ['stop', 'start', 'test', 'restart'] - const bestRun = Object.keys(scripts || {}) - .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && - !runScripts.includes(cmd)) - .map(str => ` npm run ${str} # run the "${str}" package script`) - - const { bin } = pkg - const bestBin = Object.keys(bin || {}) - .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4) - .map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`) - - const best = [...bestCmd, ...bestRun, ...bestBin] + try { + const { bin, scripts } = await readJson(`${path}/package.json`) + best = best.concat( + Object.keys(scripts || {}) + .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && + !runScripts.includes(cmd)) + .map(str => ` npm run ${str} # run the "${str}" package script`), + Object.keys(bin || {}) + .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4) + .map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`) + ) + } catch (_) { + // gracefully ignore not being in a folder w/ a package.json + } if (best.length === 0) return '' diff --git a/test/lib/utils/did-you-mean.js b/test/lib/utils/did-you-mean.js index 15712b665be6e..1285d5300853b 100644 --- a/test/lib/utils/did-you-mean.js +++ b/test/lib/utils/did-you-mean.js @@ -5,34 +5,55 @@ const dym = require('../../../lib/utils/did-you-mean.js') t.test('did-you-mean', t => { npm.load(err => { t.notOk(err) - t.test('nistall', async t => { - const result = await dym(npm, npm.localPrefix, 'nistall') - t.match(result, 'npm install') - }) - t.test('sttest', async t => { - const result = await dym(npm, npm.localPrefix, 'sttest') - t.match(result, 'npm test') - t.match(result, 'npm run posttest') + t.test('with package.json', t => { + const testdir = t.testdir({ + 'package.json': JSON.stringify({ + bin: { + npx: 'exists', + }, + scripts: { + install: 'exists', + posttest: 'exists', + }, + }), + }) + t.test('nistall', async t => { + const result = await dym(npm, testdir, 'nistall') + t.match(result, 'npm install') + }) + t.test('sttest', async t => { + const result = await dym(npm, testdir, 'sttest') + t.match(result, 'npm test') + t.match(result, 'npm run posttest') + }) + t.test('npz', async t => { + const result = await dym(npm, testdir, 'npxx') + t.match(result, 'npm exec npx') + }) + t.test('qwuijbo', async t => { + const result = await dym(npm, testdir, 'qwuijbo') + t.match(result, '') + }) + t.end() }) - t.test('npz', async t => { - const result = await dym(npm, npm.localPrefix, 'npxx') - t.match(result, 'npm exec npx') + t.test('with no package.json', t => { + const testdir = t.testdir({}) + t.test('nistall', async t => { + const result = await dym(npm, testdir, 'nistall') + t.match(result, 'npm install') + }) + t.end() }) - t.test('qwuijbo', async t => { - const result = await dym(npm, npm.localPrefix, 'qwuijbo') - t.match(result, '') + t.test('missing bin and script properties', async t => { + const testdir = t.testdir({ + 'package.json': JSON.stringify({ + name: 'missing-bin', + }), + }) + + const result = await dym(npm, testdir, 'nistall') + t.match(result, 'npm install') }) t.end() }) }) - -t.test('missing bin and script properties', async t => { - const path = t.testdir({ - 'package.json': JSON.stringify({ - name: 'missing-bin', - }), - }) - - const result = await dym(npm, path, 'nistall') - t.match(result, 'npm install') -}) From 0320bd77e2a38f48a88e377df4b122fd21043a83 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Mon, 13 Sep 2021 10:53:13 -0700 Subject: [PATCH 24/35] fix(view): Show the correct publish date for versions selected by range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before, `npm view npm@^6` would incorrectly report “published over a year from now” for every entry. Now it reports the correct dates. PR-URL: https://github.com/npm/cli/pull/3739 Credit: @andersk Close: #3739 Reviewed-by: @wraithgar --- lib/view.js | 2 +- tap-snapshots/test/lib/view.js.test.cjs | 23 ++++++++++++++++++++--- test/lib/view.js | 12 +++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/lib/view.js b/lib/view.js index f4fc5974eeeca..0124bfb7d3543 100644 --- a/lib/view.js +++ b/lib/view.js @@ -336,7 +336,7 @@ class View extends BaseCommand { email: color.cyan(manifest._npmUser.email), }), modified: !packument.time ? undefined - : color.yellow(relativeDate(packument.time[packument.version])), + : color.yellow(relativeDate(packument.time[manifest.version])), maintainers: (packument.maintainers || []).map((u) => unparsePerson({ name: color.yellow(u.name), email: color.cyan(u.email), diff --git a/tap-snapshots/test/lib/view.js.test.cjs b/tap-snapshots/test/lib/view.js.test.cjs index 27ba7b1eb6927..9ed8334138cf8 100644 --- a/tap-snapshots/test/lib/view.js.test.cjs +++ b/tap-snapshots/test/lib/view.js.test.cjs @@ -82,7 +82,7 @@ dist dist-tags: latest: 1.0.0 -published {TIME} ago +published yesterday ` exports[`test/lib/view.js TAP should log info of package in current working dir specific version > must match snapshot 1`] = ` @@ -99,7 +99,7 @@ dist dist-tags: latest: 1.0.0 -published {TIME} ago +published yesterday ` exports[`test/lib/view.js TAP should log package info package from git > must match snapshot 1`] = ` @@ -302,7 +302,24 @@ dist dist-tags: latest: 1.0.0 -published {TIME} ago +published yesterday +` + +exports[`test/lib/view.js TAP should log package info package with semver range > must match snapshot 1`] = ` + + +blue@1.0.0 | Proprietary | deps: none | versions: 2 + +dist +.tarball:http://hm.blue.com/1.0.0.tgz +.shasum:123 +.integrity:--- +.unpackedSize:1 B + +dist-tags: +latest: 1.0.0 + +published yesterday ` exports[`test/lib/view.js TAP workspaces all workspaces --json > must match snapshot 1`] = ` diff --git a/test/lib/view.js b/test/lib/view.js index 793917adc6476..096ababb29ae8 100644 --- a/test/lib/view.js +++ b/test/lib/view.js @@ -17,6 +17,9 @@ const cleanLogs = () => { console.log = fn } +// 25 hours ago +const yesterday = new Date(Date.now() - 1000 * 60 * 60 * 25) + const packument = (nv, opts) => { if (!opts.fullMetadata) throw new Error('must fetch fullMetadata') @@ -40,7 +43,7 @@ const packument = (nv, opts) => { latest: '1.0.0', }, time: { - '1.0.0': '2019-08-06T16:21:09.842Z', + '1.0.0': yesterday, }, versions: { '1.0.0': { @@ -332,6 +335,13 @@ t.test('should log package info', t => { }) }) + t.test('package with semver range', t => { + view.exec(['blue@^1.0.0'], () => { + t.matchSnapshot(logs) + t.end() + }) + }) + t.test('package with no modified time', t => { viewUnicode.exec(['cyan@1.0.0'], () => { t.matchSnapshot(logs) From e4a5218573583149af795982a39fa64a4116cdab Mon Sep 17 00:00:00 2001 From: Gar Date: Mon, 13 Sep 2021 11:34:24 -0700 Subject: [PATCH 25/35] fix(install.sh): don't remove old npm first The install script will gracefully fail if things don't work. This is especially important for versions of npm that won't work in your current node version. PR-URL: https://github.com/npm/cli/pull/3748 Credit: @wraithgar Close: #3748 Reviewed-by: @isaacs --- scripts/install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 8c0ba3de72f12..cd6ea391cea5d 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -162,8 +162,6 @@ cd "$TMP" \ && curl -qSsL -o npm.tgz "$url" \ && $tar -xzf npm.tgz \ && cd "$TMP"/package \ - && echo "removing existing npm" \ - && "$node" bin/npm-cli.js rm npm -gf --loglevel=silent \ && echo "installing npm@$t" \ && "$node" bin/npm-cli.js install -gf ../npm.tgz \ && cd "$BACK" \ From 291d977e09f5c17fa2ef8fccda6a61a24cb6d590 Mon Sep 17 00:00:00 2001 From: John Gee Date: Tue, 14 Sep 2021 17:56:53 +1200 Subject: [PATCH 26/35] chore: Fix typos in CONTRIBUTING PR-URL: https://github.com/npm/cli/pull/3753 Credit: @shadowspawn Close: #3753 Reviewed-by: @wraithgar --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5ee9b45608eab..33dff2e8e8b9c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,4 +63,4 @@ It should be noted that our team does not accept third-party dependency updates/ ### Tools/Automation -Our core team is responsible for the maintaince of the tooling/automation in this project & we ask collaborators to kindle not make changes to these when contributing (ex. `.github/*`, `.eslintrc.json`, `.licensee.json` etc.) +Our core team is responsible for the maintenance of the tooling/automation in this project & we ask collaborators to kindly not make changes to these when contributing (ex. `.github/*`, `.eslintrc.json`, `.licensee.json` etc.) From b4aac345b0a7cdec4d713c5be4daea37330b2b26 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 14 Sep 2021 07:27:36 -0700 Subject: [PATCH 27/35] fix(config): user-agent properly shows ci The way we were flattening user-agent back into itself meant that any values that were dependent on other config items would never be seen, since we have to re-flatten the item for each one it depends on. We also weren't re-flattening the user-agent when setting workspaces or workspace, which were things that affected the final result. This does change the main config value of `user-agent` but not the flattened one. We are not using the main config value anywhere (which is correct). PR-URL: https://github.com/npm/cli/pull/3754 Credit: @wraithgar Close: #3754 Reviewed-by: @nlf --- lib/utils/config/definitions.js | 12 ++++++- smoke-tests/index.js | 40 ++++++++++++++++++++++- smoke-tests/server.js | 8 ++++- tap-snapshots/test/lib/config.js.test.cjs | 4 +-- test/lib/utils/config/definitions.js | 30 ++++++++++++++--- 5 files changed, 85 insertions(+), 9 deletions(-) diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index 092e0fc435cb4..009f60a7bce61 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -2053,10 +2053,14 @@ define('user-agent', { .replace(/\{workspaces\}/gi, inWorkspaces) .replace(/\{ci\}/gi, ciName ? `ci/${ciName}` : '') .trim() + + // We can't clobber the original or else subsequent flattening will fail + // (i.e. when we change the underlying config values) + // obj[key] = flatOptions.userAgent + // user-agent is a unique kind of config item that gets set from a template // and ends up translated. Because of this, the normal "should we set this // to process.env also doesn't work - obj[key] = flatOptions.userAgent process.env.npm_config_user_agent = flatOptions.userAgent }, }) @@ -2140,6 +2144,9 @@ define('workspace', { a workspace which does not yet exist, to create the folder and set it up as a brand new workspace within the project. `, + flatten: (key, obj, flatOptions) => { + definitions['user-agent'].flatten('user-agent', obj, flatOptions) + }, }) define('workspaces', { @@ -2151,6 +2158,9 @@ define('workspaces', { Enable running a command in the context of **all** the configured workspaces. `, + flatten: (key, obj, flatOptions) => { + definitions['user-agent'].flatten('user-agent', obj, flatOptions) + }, }) define('yes', { diff --git a/smoke-tests/index.js b/smoke-tests/index.js index 9235c8960a26a..5e2d5e071ae12 100644 --- a/smoke-tests/index.js +++ b/smoke-tests/index.js @@ -1,8 +1,9 @@ const fs = require('fs') const { promisify } = require('util') const execAsync = promisify(require('child_process').exec) -const { resolve } = require('path') +const { join, resolve } = require('path') const t = require('tap') +const rimraf = promisify(require('rimraf')) const normalizePath = path => path.replace(/[A-Z]:/, '').replace(/\\/g, '/') const cwd = normalizePath(process.cwd()) @@ -47,6 +48,43 @@ const exec = async cmd => { const readFile = filename => String(fs.readFileSync(resolve(localPrefix, filename))) +// this test must come first, its package.json will be destroyed and the one +// created in the next test (npm init) will create a new one that must be +// present for later tests +t.test('npm install sends correct user-agent', async t => { + const pkgPath = join(localPrefix, 'package.json') + const pkgContent = JSON.stringify({ + name: 'smoke-test-workspaces', + workspaces: ['packages/*'], + }) + fs.writeFileSync(pkgPath, pkgContent, { encoding: 'utf8' }) + + const wsRoot = join(localPrefix, 'packages') + fs.mkdirSync(wsRoot) + + const wsPath = join(wsRoot, 'foo') + fs.mkdirSync(wsPath) + + const wsPkgPath = join(wsPath, 'package.json') + const wsContent = JSON.stringify({ + name: 'foo', + }) + fs.writeFileSync(wsPkgPath, wsContent, { encoding: 'utf8' }) + t.teardown(async () => { + await rimraf(`${localPrefix}/*`) + }) + + const cmd = `${npmBin} install fail_reflect_user_agent` + await t.rejects(exec(cmd), { + stderr: /workspaces\/false/, + }, 'workspaces/false is present in output') + + const wsCmd = `${npmBin} install fail_reflect_user_agent --workspaces` + await t.rejects(exec(wsCmd), { + stderr: /workspaces\/true/, + }, 'workspaces/true is present in output') +}) + t.test('npm init', async t => { const cmd = `${npmBin} init -y` const cmdRes = await exec(cmd) diff --git a/smoke-tests/server.js b/smoke-tests/server.js index b864114af64a8..e0ac0c94eb5ab 100644 --- a/smoke-tests/server.js +++ b/smoke-tests/server.js @@ -1,5 +1,5 @@ /* istanbul ignore file */ -const {join, dirname} = require('path') +const {join, dirname, basename} = require('path') const {existsSync, readFileSync, writeFileSync} = require('fs') const PORT = 12345 + (+process.env.TAP_CHILD_ID || 0) const http = require('http') @@ -150,6 +150,12 @@ const startServer = () => new Promise((res, rej) => { } const f = join(__dirname, 'content', join('/', req.url.replace(/@/, '').replace(/%2f/i, '/'))) + // a magic package that causes us to return an error that will be logged + if (basename(f) === 'fail_reflect_user_agent') { + res.setHeader('npm-notice', req.headers['user-agent']) + res.writeHead(404) + return res.end() + } const isCorgi = req.headers.accept.includes('application/vnd.npm.install-v1+json') const file = f + ( isCorgi && existsSync(`${f}.min.json`) ? '.min.json' diff --git a/tap-snapshots/test/lib/config.js.test.cjs b/tap-snapshots/test/lib/config.js.test.cjs index 817f3c173f19e..b21b75cd25e11 100644 --- a/tap-snapshots/test/lib/config.js.test.cjs +++ b/tap-snapshots/test/lib/config.js.test.cjs @@ -146,7 +146,7 @@ exports[`test/lib/config.js TAP config list --json > output matches snapshot 1`] "unicode": false, "update-notifier": true, "usage": false, - "user-agent": "npm/{NPM-VERSION} node/{NODE-VERSION} {PLATFORM} {ARCH} workspaces/false", + "user-agent": "npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}", "version": false, "versions": false, "viewer": "{VIEWER}", @@ -296,7 +296,7 @@ umask = 0 unicode = false update-notifier = true usage = false -user-agent = "npm/{NPM-VERSION} node/{NODE-VERSION} {PLATFORM} {ARCH} workspaces/false" +user-agent = "npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}" ; userconfig = "{HOME}/.npmrc" ; overridden by cli version = false versions = false diff --git a/test/lib/utils/config/definitions.js b/test/lib/utils/config/definitions.js index 65193020d050c..88993303b539c 100644 --- a/test/lib/utils/config/definitions.js +++ b/test/lib/utils/config/definitions.js @@ -747,7 +747,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectNoCI) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') obj['ci-name'] = 'foo' obj['user-agent'] = definitions['user-agent'].default @@ -755,7 +755,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectCI) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') delete obj['ci-name'] obj.workspaces = true @@ -764,7 +764,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectWorkspaces) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') delete obj.workspaces obj.workspace = ['foo'] @@ -772,7 +772,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectWorkspaces) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') t.end() }) @@ -853,3 +853,25 @@ t.test('package-lock-only', t => { t.strictSame(flat, { packageLock: false, packageLockOnly: false }) t.end() }) + +t.test('workspaces', t => { + const obj = { + workspaces: true, + 'user-agent': definitions['user-agent'].default, + } + const flat = {} + definitions.workspaces.flatten('workspaces', obj, flat) + t.match(flat.userAgent, /workspaces\/true/) + t.end() +}) + +t.test('workspace', t => { + const obj = { + workspace: ['workspace-a'], + 'user-agent': definitions['user-agent'].default, + } + const flat = {} + definitions.workspace.flatten('workspaces', obj, flat) + t.match(flat.userAgent, /workspaces\/true/) + t.end() +}) From b807cd62eabe337e3243415c9870ea36d9289e12 Mon Sep 17 00:00:00 2001 From: Ayush Rawal Date: Sat, 11 Sep 2021 13:36:09 +0530 Subject: [PATCH 28/35] fix(search): return valid json for no results PR-URL: https://github.com/npm/cli/pull/3738 Credit: @AyushRawal Close: #3738 Reviewed-by: @wraithgar --- lib/search/format-package-stream.js | 2 +- test/lib/search.js | 31 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/search/format-package-stream.js b/lib/search/format-package-stream.js index c88df5eb4be04..fb7d81856d63f 100644 --- a/lib/search/format-package-stream.js +++ b/lib/search/format-package-stream.js @@ -42,7 +42,7 @@ class JSONOutputStream extends Minipass { } end () { - super.write(this._didFirst ? ']\n' : '\n]\n') + super.write(this._didFirst ? ']\n' : '\n[]\n') super.end() } } diff --git a/test/lib/search.js b/test/lib/search.js index 510a470f48088..55b584b8aa7dc 100644 --- a/test/lib/search.js +++ b/test/lib/search.js @@ -130,6 +130,37 @@ t.test('search --json', (t) => { src.end() }) +t.test('search --json', (t) => { + const src = new Minipass() + src.objectMode = true + + npm.flatOptions.json = true + config.json = true + const libnpmsearch = { + stream () { + return src + }, + } + + const Search = t.mock('../../lib/search.js', { + ...mocks, + libnpmsearch, + }) + const search = new Search(npm) + + search.exec(['foo'], (err) => { + if (err) + throw err + + t.equal(result, '\n[]\n', 'should have expected empty square brackets') + + config.json = false + t.end() + }) + + src.end() +}) + t.test('search --searchexclude --searchopts', t => { npm.flatOptions.search = { ...flatOptions.search, From 4d93b484abb50e3704fb436db572b93fb36c7ac3 Mon Sep 17 00:00:00 2001 From: Nate Green Date: Wed, 15 Sep 2021 09:58:13 -0400 Subject: [PATCH 29/35] fix(docs): use correct hyperlink to package-json See npm/documentation#36 PR-URL: https://github.com/npm/cli/pull/3759 Credit: @nategreen Close: #3759 Reviewed-by: @wraithgar --- docs/content/using-npm/scripts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/using-npm/scripts.md b/docs/content/using-npm/scripts.md index e033afd30188a..ad32ca6eb234c 100644 --- a/docs/content/using-npm/scripts.md +++ b/docs/content/using-npm/scripts.md @@ -259,7 +259,7 @@ package.json file, then your package scripts would have the in your code with `process.env.npm_package_name` and `process.env.npm_package_version`, and so on for other fields. -See [`package-json.md`](/using-npm/package-json) for more on package configs. +See [`package-json.md`](/configuring-npm/package-json) for more on package configs. #### current lifecycle event From 2def17a3b625b92b40c6185ff4b47e8ed006492c Mon Sep 17 00:00:00 2001 From: Jacob Yacovelli Date: Wed, 15 Sep 2021 10:42:35 -0400 Subject: [PATCH 30/35] fix(install): use configured registry when checking manifest PR-URL: https://github.com/npm/cli/pull/3760 Credit: @yacoman89 Close: #3760 Reviewed-by: @wraithgar --- lib/install.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/install.js b/lib/install.js index 1589ff589c38e..99f75b71384fa 100644 --- a/lib/install.js +++ b/lib/install.js @@ -135,7 +135,8 @@ class Install extends ArboristWorkspaceCmd { // be very strict about engines when trying to update npm itself const npmInstall = args.find(arg => arg.startsWith('npm@') || arg === 'npm') if (isGlobalInstall && npmInstall) { - const npmManifest = await pacote.manifest(npmInstall) + const npmOptions = this.npm.flatOptions + const npmManifest = await pacote.manifest(npmInstall, npmOptions) try { checks.checkEngine(npmManifest, npmManifest.version, process.version) } catch (e) { From 371655a6b0e6664fec67f16cb247cc9f174a5197 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 15 Sep 2021 13:04:16 -0700 Subject: [PATCH 31/35] deps: minipass@3.1.5 * fix: re-emit 'error' event if missed and new listener added * fix: do not blow up if process is missing --- node_modules/minipass/index.js | 14 ++++++++++++-- node_modules/minipass/package.json | 4 ++-- package-lock.json | 12 ++++++------ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/node_modules/minipass/index.js b/node_modules/minipass/index.js index 56cbd665d2526..ae134a066d77f 100644 --- a/node_modules/minipass/index.js +++ b/node_modules/minipass/index.js @@ -1,4 +1,8 @@ 'use strict' +const proc = typeof process === 'object' && process ? process : { + stdout: null, + stderr: null, +} const EE = require('events') const Stream = require('stream') const Yallist = require('yallist') @@ -8,6 +12,7 @@ const EOF = Symbol('EOF') const MAYBE_EMIT_END = Symbol('maybeEmitEnd') const EMITTED_END = Symbol('emittedEnd') const EMITTING_END = Symbol('emittingEnd') +const EMITTED_ERROR = Symbol('emittedError') const CLOSED = Symbol('closed') const READ = Symbol('read') const FLUSH = Symbol('flush') @@ -66,6 +71,7 @@ module.exports = class Minipass extends Stream { this[EMITTED_END] = false this[EMITTING_END] = false this[CLOSED] = false + this[EMITTED_ERROR] = null this.writable = true this.readable = true this[BUFFERLENGTH] = 0 @@ -310,7 +316,7 @@ module.exports = class Minipass extends Stream { const ended = this[EMITTED_END] opts = opts || {} - if (dest === process.stdout || dest === process.stderr) + if (dest === proc.stdout || dest === proc.stderr) opts.end = false else opts.end = opts.end !== false @@ -339,6 +345,8 @@ module.exports = class Minipass extends Stream { else if (isEndish(ev) && this[EMITTED_END]) { super.emit(ev) this.removeAllListeners(ev) + } else if (ev === 'error' && this[EMITTED_ERROR]) { + fn.call(this, this[EMITTED_ERROR]) } } } @@ -400,6 +408,8 @@ module.exports = class Minipass extends Stream { // don't emit close before 'end' and 'finish' if (!this[EMITTED_END] && !this[DESTROYED]) return + } else if (ev === 'error') { + this[EMITTED_ERROR] = data } // TODO: replace with a spread operator when Node v4 support drops @@ -452,8 +462,8 @@ module.exports = class Minipass extends Stream { promise () { return new Promise((resolve, reject) => { this.on(DESTROYED, () => reject(new Error('stream destroyed'))) - this.on('end', () => resolve()) this.on('error', er => reject(er)) + this.on('end', () => resolve()) }) } diff --git a/node_modules/minipass/package.json b/node_modules/minipass/package.json index 54f62d56d46d8..165fa662ab4a7 100644 --- a/node_modules/minipass/package.json +++ b/node_modules/minipass/package.json @@ -1,6 +1,6 @@ { "name": "minipass", - "version": "3.1.3", + "version": "3.1.5", "description": "minimal implementation of a PassThrough stream", "main": "index.js", "dependencies": { @@ -8,7 +8,7 @@ }, "devDependencies": { "end-of-stream": "^1.4.0", - "tap": "^14.6.5", + "tap": "^15.0.9", "through2": "^2.0.3" }, "scripts": { diff --git a/package-lock.json b/package-lock.json index 8f4a37801185a..be697701ff43b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5114,9 +5114,9 @@ "dev": true }, "node_modules/minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", + "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", "inBundle": true, "dependencies": { "yallist": "^4.0.0" @@ -14232,9 +14232,9 @@ "dev": true }, "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", + "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", "requires": { "yallist": "^4.0.0" } From ca792acdd4ba683d8415c88188ec6739033fb4fd Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 15 Sep 2021 11:12:49 -0700 Subject: [PATCH 32/35] fix(logs): clean args for failed commands PR-URL: https://github.com/npm/cli/pull/3761 Credit: @wraithgar Close: #3761 Reviewed-by: @lukekarrys --- lib/utils/error-message.js | 2 +- .../test/lib/utils/error-message.js.test.cjs | 34 +++++++++++++++++++ test/lib/utils/error-message.js | 11 ++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/utils/error-message.js b/lib/utils/error-message.js index 6e12bcb918eef..9343d37d54149 100644 --- a/lib/utils/error-message.js +++ b/lib/utils/error-message.js @@ -367,7 +367,7 @@ module.exports = (er, npm) => { detail.push(['signal', er.signal]) if (er.cmd && Array.isArray(er.args)) - detail.push(['command', ...[er.cmd, ...er.args]]) + detail.push(['command', ...[er.cmd, ...er.args.map(replaceInfo)]]) if (er.stdout) detail.push(['', er.stdout.trim()]) diff --git a/tap-snapshots/test/lib/utils/error-message.js.test.cjs b/tap-snapshots/test/lib/utils/error-message.js.test.cjs index 1f73361c48589..79301bfaa0cf0 100644 --- a/tap-snapshots/test/lib/utils/error-message.js.test.cjs +++ b/tap-snapshots/test/lib/utils/error-message.js.test.cjs @@ -180,6 +180,40 @@ Object { } ` +exports[`test/lib/utils/error-message.js TAP args are cleaned > must match snapshot 1`] = ` +Object { + "detail": Array [ + Array [ + "signal", + "SIGYOLO", + ], + Array [ + "command", + "some command", + "a", + "r", + "g", + "s", + "https://evil:***@npmjs.org", + ], + Array [ + "", + "stdout", + ], + Array [ + "", + "stderr", + ], + ], + "summary": Array [ + Array [ + "", + "cmd err", + ], + ], +} +` + exports[`test/lib/utils/error-message.js TAP bad engine with config loaded > must match snapshot 1`] = ` Object { "detail": Array [ diff --git a/test/lib/utils/error-message.js b/test/lib/utils/error-message.js index d1c67a95137c4..6b2b5c9222e77 100644 --- a/test/lib/utils/error-message.js +++ b/test/lib/utils/error-message.js @@ -201,6 +201,17 @@ t.test('default message', t => { t.end() }) +t.test('args are cleaned', t => { + t.matchSnapshot(errorMessage(Object.assign(new Error('cmd err'), { + cmd: 'some command', + signal: 'SIGYOLO', + args: ['a', 'r', 'g', 's', 'https://evil:password@npmjs.org'], + stdout: 'stdout', + stderr: 'stderr', + }), npm)) + t.end() +}) + t.test('eacces/eperm', t => { const runTest = (windows, loaded, cachePath, cacheDest) => t => { if (windows) From a3bb2a988ea524f5df61bf1db7156a4daa855b4d Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Thu, 16 Sep 2021 14:37:32 -0700 Subject: [PATCH 33/35] docs: changelog for v7.24.0 --- CHANGELOG.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c591cd2ac559b..77a926d47c274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,58 @@ +## v7.24.0 (2021-09-16) + +### FEATURES + +* [`c7787b3fb`](https://github.com/npm/cli/commit/c7787b3fb7630aab84aae83ebf9a7117c7173b6b) + [`1fbbe1e04`](https://github.com/npm/cli/commit/1fbbe1e04be5d79c7b49910324e64c19ed599eeb) + bundled npm-install-checks ([@wraithgar](https://github.com/wraithgar)) + +### BUG FIXES + +* [`0320bd77e`](https://github.com/npm/cli/commit/0320bd77e2a38f48a88e377df4b122fd21043a83) + [#3739](https://github.com/npm/cli/issues/3739) + fix(view): Show the correct publish date for versions selected by range ([@andersk](https://github.com/andersk)) +* [`e4a521857`](https://github.com/npm/cli/commit/e4a5218573583149af795982a39fa64a4116cdab) + [#3748](https://github.com/npm/cli/issues/3748) + fix(install.sh): don't remove old npm first + ([@wraithgar](https://github.com/wraithgar)) +* [`b4aac345b`](https://github.com/npm/cli/commit/b4aac345b0a7cdec4d713c5be4daea37330b2b26) + [#3754](https://github.com/npm/cli/issues/3754) + fix(config): user-agent properly shows ci + ([@wraithgar](https://github.com/wraithgar)) +* [`b807cd62e`](https://github.com/npm/cli/commit/b807cd62eabe337e3243415c9870ea36d9289e12) + [#3738](https://github.com/npm/cli/issues/3738) + fix(search): return valid json for no results + ([@AyushRawal](https://github.com/AyushRawal)) +* [`2def17a3b`](https://github.com/npm/cli/commit/2def17a3b625b92b40c6185ff4b47e8ed006492c) + [#3760](https://github.com/npm/cli/issues/3760) + fix(install): use configured registry when checking manifest + ([@yacoman89](https://github.com/yacoman89)) +* [`ca792acdd`](https://github.com/npm/cli/commit/ca792acdd4ba683d8415c88188ec6739033fb4fd) + [#3761](https://github.com/npm/cli/issues/3761) + fix(logs): clean args for failed commands + ([@wraithgar](https://github.com/wraithgar)) + +### DEPENDENCIES + +* [`59743972c`](https://github.com/npm/cli/commit/59743972c2ae1d2dd601aaa6c59974c686b1cb29) + [#3747](https://github.com/npm/cli/issues/3747) + fix(did-you-mean): succeed if cwd is not a package + ([@wraithgar](https://github.com/wraithgar)) +* [`ac8e4ad18`](https://github.com/npm/cli/commit/ac8e4ad18a6b726dd2c3abcb0f605701cca0ae2c) + `init-package-json@2.0.5`: + * fix: bin script path +* [`371655a6b`](https://github.com/npm/cli/commit/371655a6b0e6664fec67f16cb247cc9f174a5197) + `minipass@3.1.5`: + * fix: re-emit 'error' event if missed and new listener added + * fix: do not blow up if process is missing + +### DOCUMENTATION + +* [`4d93b484a`](https://github.com/npm/cli/commit/4d93b484abb50e3704fb436db572b93fb36c7ac3) + [#3759](https://github.com/npm/cli/issues/3759) + fix(docs): use correct hyperlink to package-json + ([@nategreen](https://github.com/nategreen)) + ## v7.23.0 (2021-09-09) ### FEATURES From 21dd300933c770d44e2123ef673628ffce4de7d3 Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Thu, 16 Sep 2021 14:37:47 -0700 Subject: [PATCH 34/35] update AUTHORS --- AUTHORS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AUTHORS b/AUTHORS index c204352764831..fb4e46210eac5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -794,3 +794,8 @@ austincho Nathan Fritz tripu <1016538+tripu@users.noreply.github.com> Matsuuu +Anders Kaseorg +John Gee +Ayush Rawal +Nate Green +Jacob Yacovelli From 2c741900f560fd3ad0d5fa8afe583fbd83c5dbbe Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Thu, 16 Sep 2021 14:37:48 -0700 Subject: [PATCH 35/35] 7.24.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index be697701ff43b..38b7892aa4bf8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "npm", - "version": "7.23.0", + "version": "7.24.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "npm", - "version": "7.23.0", + "version": "7.24.0", "bundleDependencies": [ "@npmcli/arborist", "@npmcli/ci-detect", diff --git a/package.json b/package.json index 8011f238ac2ff..38b45947706dc 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "7.23.0", + "version": "7.24.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [