From ff93b065a82790285c97d22f5a4cefd4f82a09d5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:20:53 +0000 Subject: [PATCH 001/406] chore(latest): release libnpmfund 3.0.2 --- workspaces/libnpmfund/CHANGELOG.md | 13 +++++++++++++ workspaces/libnpmfund/package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmfund/CHANGELOG.md b/workspaces/libnpmfund/CHANGELOG.md index 070a6d44c9a3b..2e6fce8a8d890 100644 --- a/workspaces/libnpmfund/CHANGELOG.md +++ b/workspaces/libnpmfund/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +### [3.0.2](https://github.com/npm/cli/compare/libnpmfund-v3.0.1...libnpmfund-v3.0.2) (2022-04-06) + + +### Bug Fixes + +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) + ### [3.0.1](https://www.github.com/npm/cli/compare/libnpmfund-vlibnpmfund@3.0.0...libnpmfund-v3.0.1) (2022-03-03) diff --git a/workspaces/libnpmfund/package.json b/workspaces/libnpmfund/package.json index e5e3f7349ee15..438984fe29204 100644 --- a/workspaces/libnpmfund/package.json +++ b/workspaces/libnpmfund/package.json @@ -1,6 +1,6 @@ { "name": "libnpmfund", - "version": "3.0.1", + "version": "3.0.2", "main": "lib/index.js", "files": [ "bin/", From 3516f61e415d9ce6e9b00378c45791e33bb99fc9 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:21:23 +0000 Subject: [PATCH 002/406] deps: libnpmfund@3.0.2 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 7e9ce34a8c063..d82dbe866a166 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9867,7 +9867,7 @@ } }, "workspaces/libnpmfund": { - "version": "3.0.1", + "version": "3.0.2", "license": "ISC", "dependencies": { "@npmcli/arborist": "^5.0.0" From efc6eb6479b2dc97babcfccb64988a86b5371af1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:20:35 +0000 Subject: [PATCH 003/406] chore(latest): release libnpmversion 3.0.2 --- workspaces/libnpmversion/CHANGELOG.md | 13 +++++++++++++ workspaces/libnpmversion/package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmversion/CHANGELOG.md b/workspaces/libnpmversion/CHANGELOG.md index e251ad4e13a75..83134e27efea9 100644 --- a/workspaces/libnpmversion/CHANGELOG.md +++ b/workspaces/libnpmversion/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +### [3.0.2](https://github.com/npm/cli/compare/libnpmversion-v3.0.1...libnpmversion-v3.0.2) (2022-04-06) + + +### Bug Fixes + +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) + ### [3.0.1](https://www.github.com/npm/cli/compare/libnpmversion-vlibnpmversion@3.0.0...libnpmversion-v3.0.1) (2022-03-03) diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index 2702dd16df2c8..e59957f63c230 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -1,6 +1,6 @@ { "name": "libnpmversion", - "version": "3.0.1", + "version": "3.0.2", "main": "lib/index.js", "files": [ "bin/", From ecd22b07af515d86b77248e6a4cc2dec57bafd50 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:21:14 +0000 Subject: [PATCH 004/406] deps: libnpmversion@3.0.2 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index d82dbe866a166..796bc6d8c6bb5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9990,7 +9990,7 @@ } }, "workspaces/libnpmversion": { - "version": "3.0.1", + "version": "3.0.2", "license": "ISC", "dependencies": { "@npmcli/git": "^3.0.0", From fb9874a7becfc899133dd0d82da2a17be9c3a1c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:20:18 +0000 Subject: [PATCH 005/406] chore(latest): release libnpmhook 8.0.3 --- workspaces/libnpmhook/CHANGELOG.md | 14 ++++++++++++++ workspaces/libnpmhook/package.json | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmhook/CHANGELOG.md b/workspaces/libnpmhook/CHANGELOG.md index 4aaf534b81437..f344283b35ef5 100644 --- a/workspaces/libnpmhook/CHANGELOG.md +++ b/workspaces/libnpmhook/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +### [8.0.3](https://github.com/npm/cli/compare/libnpmhook-v8.0.2...libnpmhook-v8.0.3) (2022-04-06) + + +### Bug Fixes + +* replace deprecated String.prototype.substr() ([#4667](https://github.com/npm/cli/issues/4667)) ([e3da5df](https://github.com/npm/cli/commit/e3da5df4152fbe547f7871547165328e1bf06262)) +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) + ### [8.0.2](https://www.github.com/npm/cli/compare/libnpmhook-v8.0.1...libnpmhook-v8.0.2) (2022-03-10) diff --git a/workspaces/libnpmhook/package.json b/workspaces/libnpmhook/package.json index e6200a97fe585..fad458183d186 100644 --- a/workspaces/libnpmhook/package.json +++ b/workspaces/libnpmhook/package.json @@ -1,6 +1,6 @@ { "name": "libnpmhook", - "version": "8.0.2", + "version": "8.0.3", "description": "programmatic API for managing npm registry hooks", "main": "lib/index.js", "files": [ From 7ed9fafaa951071a7988a3ec4ca3a5e01756b11d Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:20:55 +0000 Subject: [PATCH 006/406] deps: libnpmhook@8.0.3 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 796bc6d8c6bb5..aa9779e9f2289 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9882,7 +9882,7 @@ } }, "workspaces/libnpmhook": { - "version": "8.0.2", + "version": "8.0.3", "license": "ISC", "dependencies": { "aproba": "^2.0.0", From 19789c718b8cc183f54c6b1ab2ce9a267aff175b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:20:05 +0000 Subject: [PATCH 007/406] chore(latest): release libnpmexec 4.0.3 --- workspaces/libnpmexec/CHANGELOG.md | 13 +++++++++++++ workspaces/libnpmexec/package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmexec/CHANGELOG.md b/workspaces/libnpmexec/CHANGELOG.md index 9f41bb7df013f..7e31757ac1bfb 100644 --- a/workspaces/libnpmexec/CHANGELOG.md +++ b/workspaces/libnpmexec/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +### [4.0.3](https://github.com/npm/cli/compare/libnpmexec-v4.0.2...libnpmexec-v4.0.3) (2022-04-06) + + +### Bug Fixes + +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) + ### [4.0.2](https://www.github.com/npm/cli/compare/libnpmexec-v4.0.1...libnpmexec-v4.0.2) (2022-03-15) diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index 0c945e1558f61..2807f924e9fad 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -1,6 +1,6 @@ { "name": "libnpmexec", - "version": "4.0.2", + "version": "4.0.3", "files": [ "bin/", "lib/" From df92e23af63ca07bb4c261abd7365530529d3fd2 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:20:35 +0000 Subject: [PATCH 008/406] deps: libnpmexec@4.0.3 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index aa9779e9f2289..332ae82824db1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9840,7 +9840,7 @@ } }, "workspaces/libnpmexec": { - "version": "4.0.2", + "version": "4.0.3", "license": "ISC", "dependencies": { "@npmcli/arborist": "^5.0.0", From 0d37604a693733de08883f69a469dfd5f69af837 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:20:03 +0000 Subject: [PATCH 009/406] chore(latest): release libnpmsearch 5.0.3 --- workspaces/libnpmsearch/CHANGELOG.md | 13 +++++++++++++ workspaces/libnpmsearch/package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmsearch/CHANGELOG.md b/workspaces/libnpmsearch/CHANGELOG.md index 05c053b98364f..ec86dbf623e57 100644 --- a/workspaces/libnpmsearch/CHANGELOG.md +++ b/workspaces/libnpmsearch/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +### [5.0.3](https://github.com/npm/cli/compare/libnpmsearch-v5.0.2...libnpmsearch-v5.0.3) (2022-04-06) + + +### Bug Fixes + +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) + ### [5.0.2](https://www.github.com/npm/cli/compare/libnpmsearch-v5.0.1...libnpmsearch-v5.0.2) (2022-03-10) diff --git a/workspaces/libnpmsearch/package.json b/workspaces/libnpmsearch/package.json index 2e5af3eaa60de..d0e5d8900dc06 100644 --- a/workspaces/libnpmsearch/package.json +++ b/workspaces/libnpmsearch/package.json @@ -1,6 +1,6 @@ { "name": "libnpmsearch", - "version": "5.0.2", + "version": "5.0.3", "description": "Programmatic API for searching in npm and compatible registries.", "author": "GitHub Inc.", "main": "lib/index.js", From 5074adc5e17d1b0ec753cde3b7efd96c2fc7c4a3 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:20:31 +0000 Subject: [PATCH 010/406] deps: libnpmsearch@5.0.3 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 332ae82824db1..ade3192329a6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9957,7 +9957,7 @@ } }, "workspaces/libnpmsearch": { - "version": "5.0.2", + "version": "5.0.3", "license": "ISC", "dependencies": { "npm-registry-fetch": "^13.0.0" From edc9ef6b90e4b6f9767a44943844204a8ba5180c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:19:57 +0000 Subject: [PATCH 011/406] chore(latest): release libnpmteam 4.0.3 --- workspaces/libnpmteam/CHANGELOG.md | 13 +++++++++++++ workspaces/libnpmteam/package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmteam/CHANGELOG.md b/workspaces/libnpmteam/CHANGELOG.md index 88b6fc5788073..b203fe7d6dea7 100644 --- a/workspaces/libnpmteam/CHANGELOG.md +++ b/workspaces/libnpmteam/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +### [4.0.3](https://github.com/npm/cli/compare/libnpmteam-v4.0.2...libnpmteam-v4.0.3) (2022-04-06) + + +### Bug Fixes + +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) + ### [4.0.2](https://www.github.com/npm/cli/compare/libnpmteam-v4.0.1...libnpmteam-v4.0.2) (2022-03-10) diff --git a/workspaces/libnpmteam/package.json b/workspaces/libnpmteam/package.json index f92c875fe0897..25868135d3be0 100644 --- a/workspaces/libnpmteam/package.json +++ b/workspaces/libnpmteam/package.json @@ -1,7 +1,7 @@ { "name": "libnpmteam", "description": "npm Team management APIs", - "version": "4.0.2", + "version": "4.0.3", "author": "GitHub Inc.", "license": "ISC", "main": "lib/index.js", From 35e5100e287925d19df4aab98de96cf70a6ff5a6 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:20:25 +0000 Subject: [PATCH 012/406] deps: libnpmteam@4.0.3 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index ade3192329a6f..0f02c24c02882 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9973,7 +9973,7 @@ } }, "workspaces/libnpmteam": { - "version": "4.0.2", + "version": "4.0.3", "license": "ISC", "dependencies": { "aproba": "^2.0.0", From 2a575a78d4ba38cb07e6f690db24e7f8307832b4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:19:51 +0000 Subject: [PATCH 013/406] chore(latest): release libnpmpack 4.0.3 --- workspaces/libnpmpack/CHANGELOG.md | 13 +++++++++++++ workspaces/libnpmpack/package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmpack/CHANGELOG.md b/workspaces/libnpmpack/CHANGELOG.md index 592ed7c6e0f37..13b68cb11725f 100644 --- a/workspaces/libnpmpack/CHANGELOG.md +++ b/workspaces/libnpmpack/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +### [4.0.3](https://github.com/npm/cli/compare/libnpmpack-v4.0.2...libnpmpack-v4.0.3) (2022-04-06) + + +### Bug Fixes + +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) + ### [4.0.2](https://www.github.com/npm/cli/compare/libnpmpack-v4.0.1...libnpmpack-v4.0.2) (2022-03-15) diff --git a/workspaces/libnpmpack/package.json b/workspaces/libnpmpack/package.json index ccb99e3c94fb2..53b6e8479fd05 100644 --- a/workspaces/libnpmpack/package.json +++ b/workspaces/libnpmpack/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpack", - "version": "4.0.2", + "version": "4.0.3", "description": "Programmatic API for the bits behind npm pack", "author": "GitHub Inc.", "main": "lib/index.js", From 86f5b273fc57118b8b1a5e53ec3ca49d94d81601 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:20:19 +0000 Subject: [PATCH 014/406] deps: libnpmpack@4.0.3 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 0f02c24c02882..4c9fd58278806 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9917,7 +9917,7 @@ } }, "workspaces/libnpmpack": { - "version": "4.0.2", + "version": "4.0.3", "license": "ISC", "dependencies": { "@npmcli/run-script": "^3.0.0", From ce7d794e4420f07d691e65f4246b7ffccac7d010 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 22:19:49 +0000 Subject: [PATCH 015/406] chore(latest): release libnpmpublish 6.0.3 --- workspaces/libnpmpublish/CHANGELOG.md | 15 +++++++++++++++ workspaces/libnpmpublish/package.json | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmpublish/CHANGELOG.md b/workspaces/libnpmpublish/CHANGELOG.md index 0948c1c2776ab..a93a930f1f2f8 100644 --- a/workspaces/libnpmpublish/CHANGELOG.md +++ b/workspaces/libnpmpublish/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +### [6.0.3](https://github.com/npm/cli/compare/libnpmpublish-v6.0.2...libnpmpublish-v6.0.3) (2022-04-06) + + +### Bug Fixes + +* replace deprecated String.prototype.substr() ([#4667](https://github.com/npm/cli/issues/4667)) ([e3da5df](https://github.com/npm/cli/commit/e3da5df4152fbe547f7871547165328e1bf06262)) +* update readme badges ([#4658](https://github.com/npm/cli/issues/4658)) ([2829cb2](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d)) + + +### Dependencies + +* @npmcli/template-oss@3.2.1 ([aac01b8](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08)) +* @npmcli/template-oss@3.2.2 ([#4639](https://github.com/npm/cli/issues/4639)) ([a59fd2c](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f)) +* ssri@9.0.0 ([a2781a3](https://github.com/npm/cli/commit/a2781a367d62328d7f870de878f1b63d66593f4f)) + ### [6.0.2](https://www.github.com/npm/cli/compare/libnpmpublish-v6.0.1...libnpmpublish-v6.0.2) (2022-03-15) diff --git a/workspaces/libnpmpublish/package.json b/workspaces/libnpmpublish/package.json index 389a4083d44d0..ea52240a76a5f 100644 --- a/workspaces/libnpmpublish/package.json +++ b/workspaces/libnpmpublish/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpublish", - "version": "6.0.2", + "version": "6.0.3", "description": "Programmatic API for the bits behind npm publish and unpublish", "author": "GitHub Inc.", "main": "lib/index.js", From 1617bce61663a743435d162b003d3b99376d426f Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 6 Apr 2022 22:20:29 +0000 Subject: [PATCH 016/406] deps: libnpmpublish@6.0.3 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 4c9fd58278806..341037cc39065 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9935,7 +9935,7 @@ } }, "workspaces/libnpmpublish": { - "version": "6.0.2", + "version": "6.0.3", "license": "ISC", "dependencies": { "normalize-package-data": "^4.0.0", From fe4a3d052a7be70e68ce3a519f0e03d22f1b97f7 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 11 Apr 2022 17:14:03 -0700 Subject: [PATCH 017/406] chore: remove unnecessary check-coverage tap options (#4707) --- workspaces/libnpmaccess/package.json | 3 --- workspaces/libnpmdiff/package.json | 3 --- workspaces/libnpmexec/package.json | 1 - workspaces/libnpmfund/package.json | 3 --- workspaces/libnpmhook/package.json | 3 --- workspaces/libnpmorg/package.json | 3 --- workspaces/libnpmpack/package.json | 3 --- workspaces/libnpmpublish/package.json | 3 --- workspaces/libnpmsearch/package.json | 3 --- workspaces/libnpmteam/package.json | 3 --- workspaces/libnpmversion/package.json | 3 +-- 11 files changed, 1 insertion(+), 30 deletions(-) diff --git a/workspaces/libnpmaccess/package.json b/workspaces/libnpmaccess/package.json index 1eadb2b817d3b..bb6837309821c 100644 --- a/workspaces/libnpmaccess/package.json +++ b/workspaces/libnpmaccess/package.json @@ -40,9 +40,6 @@ "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, - "tap": { - "check-coverage": true - }, "files": [ "bin/", "lib/" diff --git a/workspaces/libnpmdiff/package.json b/workspaces/libnpmdiff/package.json index e350678c668ad..88968216f54ba 100644 --- a/workspaces/libnpmdiff/package.json +++ b/workspaces/libnpmdiff/package.json @@ -44,9 +44,6 @@ "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force" }, - "tap": { - "check-coverage": true - }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/template-oss": "3.3.2", diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index 2807f924e9fad..72a1ee983520e 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -46,7 +46,6 @@ }, "tap": { "color": true, - "check-coverage": true, "files": "test/*.js" }, "devDependencies": { diff --git a/workspaces/libnpmfund/package.json b/workspaces/libnpmfund/package.json index 438984fe29204..fe8e8d8e37056 100644 --- a/workspaces/libnpmfund/package.json +++ b/workspaces/libnpmfund/package.json @@ -43,9 +43,6 @@ "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force" }, - "tap": { - "check-coverage": true - }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/template-oss": "3.3.2", diff --git a/workspaces/libnpmhook/package.json b/workspaces/libnpmhook/package.json index fad458183d186..99efed490b3c4 100644 --- a/workspaces/libnpmhook/package.json +++ b/workspaces/libnpmhook/package.json @@ -21,9 +21,6 @@ "posttest": "npm run lint", "template-oss-apply": "template-oss-apply --force" }, - "tap": { - "check-coverage": true - }, "repository": { "type": "git", "url": "https://github.com/npm/cli.git", diff --git a/workspaces/libnpmorg/package.json b/workspaces/libnpmorg/package.json index bf756e1cd60ea..be6086c115cf0 100644 --- a/workspaces/libnpmorg/package.json +++ b/workspaces/libnpmorg/package.json @@ -29,9 +29,6 @@ "bin/", "lib/" ], - "tap": { - "check-coverage": true - }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/template-oss": "3.3.2", diff --git a/workspaces/libnpmpack/package.json b/workspaces/libnpmpack/package.json index 53b6e8479fd05..1aa1d306a412d 100644 --- a/workspaces/libnpmpack/package.json +++ b/workspaces/libnpmpack/package.json @@ -24,9 +24,6 @@ "snap": "tap", "template-oss-apply": "template-oss-apply --force" }, - "tap": { - "check-coverage": true - }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/template-oss": "3.3.2", diff --git a/workspaces/libnpmpublish/package.json b/workspaces/libnpmpublish/package.json index ea52240a76a5f..ba6e72297074f 100644 --- a/workspaces/libnpmpublish/package.json +++ b/workspaces/libnpmpublish/package.json @@ -26,9 +26,6 @@ "snap": "tap", "template-oss-apply": "template-oss-apply --force" }, - "tap": { - "check-coverage": true - }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/template-oss": "3.3.2", diff --git a/workspaces/libnpmsearch/package.json b/workspaces/libnpmsearch/package.json index d0e5d8900dc06..85918e2543a75 100644 --- a/workspaces/libnpmsearch/package.json +++ b/workspaces/libnpmsearch/package.json @@ -27,9 +27,6 @@ "snap": "tap", "template-oss-apply": "template-oss-apply --force" }, - "tap": { - "check-coverage": true - }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/template-oss": "3.3.2", diff --git a/workspaces/libnpmteam/package.json b/workspaces/libnpmteam/package.json index 25868135d3be0..52309e1646dd0 100644 --- a/workspaces/libnpmteam/package.json +++ b/workspaces/libnpmteam/package.json @@ -40,9 +40,6 @@ "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, - "tap": { - "check-coverage": true - }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", "version": "3.3.2" diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index e59957f63c230..f39a84cbf1a17 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -27,8 +27,7 @@ "template-oss-apply": "template-oss-apply --force" }, "tap": { - "coverage-map": "map.js", - "check-coverage": true + "coverage-map": "map.js" }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", From 0c7648756a1aff643d5054b77429c04055ae8961 Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 7 Apr 2022 14:37:28 -0700 Subject: [PATCH 018/406] chore(arborist): update printable tree test to be a valid tree --- .../tap-snapshots/test/printable.js.test.cjs | 16 ++++++++-------- workspaces/arborist/test/printable.js | 4 +--- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/workspaces/arborist/tap-snapshots/test/printable.js.test.cjs b/workspaces/arborist/tap-snapshots/test/printable.js.test.cjs index 3a9a283d03346..ce2396d1c5c6a 100644 --- a/workspaces/arborist/tap-snapshots/test/printable.js.test.cjs +++ b/workspaces/arborist/tap-snapshots/test/printable.js.test.cjs @@ -564,24 +564,24 @@ version:'1.0.0', location:'', path:'/some/path', isProjectRoot:true, -overrides:Map{'foo@1' => '2.0.0', 'bar' => '2.0.0'}, -edgesOut:Map{ -'bar' =>{prod bar@^1.0.0 overridden:2.0.0 -> node_modules/bar}, -'foo' =>{prod foo@^1.0.0 overridden:2.0.0 -> node_modules/foo}}, +overrides:Map{'bar' => '2.0.0'}, +edgesOut:Map{'foo' =>{prod foo@^1.0.0 -> node_modules/foo}}, children:Map{ 'bar' =>{ name:'bar', version:'2.0.0', location:'node_modules/bar', path:'/some/path/node_modules/bar', -overrides:Map{'bar' => '2.0.0', 'foo@1' => '2.0.0'}, -edgesIn:Set{{"" prod bar@^1.0.0}}}, +overrides:Map{'bar' => '2.0.0'}, +edgesIn:Set{{node_modules/foo prod bar@^1.0.0}}}, 'foo' =>{ name:'foo', -version:'2.0.0', +version:'1.0.0', location:'node_modules/foo', path:'/some/path/node_modules/foo', -overrides:Map{'foo@1' => '2.0.0', 'bar' => '2.0.0'}, +overrides:Map{'bar' => '2.0.0'}, +edgesOut:Map{ +'bar' =>{prod bar@^1.0.0 overridden:2.0.0 -> node_modules/bar}}, edgesIn:Set{{"" prod foo@^1.0.0}}}}} ` diff --git a/workspaces/arborist/test/printable.js b/workspaces/arborist/test/printable.js index be2a6043d8ba9..8d06059d5a221 100644 --- a/workspaces/arborist/test/printable.js +++ b/workspaces/arborist/test/printable.js @@ -421,15 +421,13 @@ t.test('show overrides', (t) => { version: '1.0.0', dependencies: { foo: '^1.0.0', - bar: '^1.0.0', }, overrides: { - 'foo@1': '2.0.0', bar: '2.0.0', }, }, children: [ - { pkg: { name: 'foo', version: '2.0.0' }, ...flags }, + { pkg: { name: 'foo', version: '1.0.0', dependencies: { bar: '^1.0.0' } }, ...flags }, { pkg: { name: 'bar', version: '2.0.0' }, ...flags }, ], ...flags, From 4d676e31a68f081b8553eff4e79db1f29acf47e1 Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 7 Apr 2022 14:37:51 -0700 Subject: [PATCH 019/406] fix(arborist): when reloading an edge, also refresh overrides this fixes some scenarios where overrides were not being properly applied, especially those where a node_modules or package-lock.json already exists --- workspaces/arborist/lib/edge.js | 5 +++ workspaces/arborist/lib/node.js | 3 ++ workspaces/arborist/test/edge.js | 62 +++++++++++++++++++------------- workspaces/arborist/test/node.js | 56 +++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 25 deletions(-) diff --git a/workspaces/arborist/lib/edge.js b/workspaces/arborist/lib/edge.js index 87439e7645366..d72f312569466 100644 --- a/workspaces/arborist/lib/edge.js +++ b/workspaces/arborist/lib/edge.js @@ -215,6 +215,11 @@ class Edge { reload (hard = false) { this[_explanation] = null + if (this[_from].overrides) { + this.overrides = this[_from].overrides.getEdgeRule(this) + } else { + delete this.overrides + } const newTo = this[_from].resolve(this.name) if (newTo !== this[_to]) { if (this[_to]) { diff --git a/workspaces/arborist/lib/node.js b/workspaces/arborist/lib/node.js index 45c288bcf6cf7..c79bc0bd3a00b 100644 --- a/workspaces/arborist/lib/node.js +++ b/workspaces/arborist/lib/node.js @@ -792,6 +792,9 @@ class Node { target.root = root } + if (!this.overrides && this.parent && this.parent.overrides) { + this.overrides = this.parent.overrides.getNodeRule(this) + } // tree should always be valid upon root setter completion. treeCheck(this) treeCheck(root) diff --git a/workspaces/arborist/test/edge.js b/workspaces/arborist/test/edge.js index c90b202786d0d..2df989eb82f89 100644 --- a/workspaces/arborist/test/edge.js +++ b/workspaces/arborist/test/edge.js @@ -244,16 +244,19 @@ t.not(new Edge({ }).satisfiedBy(b), 'b does not satisfy edge for c') reset(a) +const overrideSet = new OverrideSet({ + overrides: { + c: '2.x', + }, +}) + +a.overrides = overrideSet t.matchSnapshot(new Edge({ from: a, type: 'prod', name: 'c', spec: '1.x', - overrides: new OverrideSet({ - overrides: { - c: '2.x', - }, - }).getEdgeRule({ name: 'c', spec: '1.x' }), + overrides: overrideSet.getEdgeRule({ name: 'c', spec: '1.x' }), }).toJSON(), 'printableEdge shows overrides') reset(a) @@ -262,11 +265,7 @@ const overriddenExplanation = new Edge({ type: 'prod', name: 'c', spec: '1.x', - overrides: new OverrideSet({ - overrides: { - c: '2.x', - }, - }).getEdgeRule({ name: 'c', spec: '1.x' }), + overrides: overrideSet.getEdgeRule({ name: 'c', spec: '1.x' }), }).explain() t.equal(overriddenExplanation.rawSpec, '1.x', 'rawSpec has original spec') t.equal(overriddenExplanation.spec, '2.x', 'spec has override spec') @@ -278,24 +277,22 @@ t.ok(new Edge({ type: 'prod', name: 'c', spec: '1.x', - overrides: new OverrideSet({ - overrides: { - c: '2.x', - }, - }).getEdgeRule({ name: 'c', spec: '1.x' }), + overrides: overrideSet.getEdgeRule({ name: 'c', spec: '1.x' }), }).satisfiedBy(c), 'c@2 satisfies spec:1.x, override:2.x') reset(a) +const overrideSetB = new OverrideSet({ + overrides: { + b: '1.x', + }, +}) +a.overrides = overrideSetB t.matchSnapshot(new Edge({ from: a, type: 'prod', name: 'c', spec: '2.x', - overrides: new OverrideSet({ - overrides: { - b: '1.x', - }, - }).getEdgeRule({ name: 'c', spec: '2.x' }), + overrides: overrideSetB.getEdgeRule({ name: 'c', spec: '2.x' }), }).toJSON(), 'printableEdge does not show non-applicable override') t.ok(new Edge({ @@ -303,13 +300,26 @@ t.ok(new Edge({ type: 'prod', name: 'c', spec: '2.x', - overrides: new OverrideSet({ - overrides: { - b: '1.x', - }, - }).getEdgeRule({ name: 'c', spec: '2.x' }), + overrides: overrideSetB.getEdgeRule({ name: 'c', spec: '2.x' }), }).satisfiedBy(c), 'c@2 satisfies spec:1.x, no matching override') reset(a) +delete a.overrides + +const overrideEdge = new Edge({ + from: a, + type: 'prod', + name: 'c', + spec: '2.x', +}) +t.notOk(overrideEdge.overrides, 'edge has no overrides') +a.overrides = new OverrideSet({ overrides: { b: '1.x' } }) +t.notOk(overrideEdge.overrides, 'edge has no overrides') +overrideEdge.reload() +t.ok(overrideEdge.overrides, 'edge has overrides after reload') +delete a.overrides +overrideEdge.reload() +t.notOk(overrideEdge.overrides, 'edge has no overrides after reload') +reset(a) const referenceTop = { name: 'referenceTop', @@ -494,6 +504,7 @@ const overrides = new OverrideSet({ c: '1.x', }, }) +a.overrides = overrides const overriddenEdge = new Edge({ from: a, type: 'prod', @@ -504,6 +515,7 @@ const overriddenEdge = new Edge({ t.equal(overriddenEdge.spec, '1.x', 'override spec takes priority') t.equal(overriddenEdge.rawSpec, '2.x', 'rawSpec holds original spec') reset(a) +delete a.overrides const old = new Edge({ from: a, diff --git a/workspaces/arborist/test/node.js b/workspaces/arborist/test/node.js index ecdf72c22a6dc..80bc21559569b 100644 --- a/workspaces/arborist/test/node.js +++ b/workspaces/arborist/test/node.js @@ -2781,6 +2781,62 @@ t.test('overrides', (t) => { t.end() }) + t.test('setting root replaces overrides', async (t) => { + const root = new Node({ + path: '/some/path', + loadOverrides: true, + pkg: { + name: 'root', + version: '1.0.0', + dependencies: { + foo: '^1.0.0', + }, + overrides: { + bar: '^2.0.0', + }, + }, + }) + + const foo = new Node({ + path: '/some/path/node_modules/foo', + pkg: { + name: 'foo', + version: '1.0.0', + dependencies: { + bar: '^1.0.0', + }, + }, + }) + + const bar = new Node({ + path: '/some/path/node_modules/bar', + pkg: { + name: 'bar', + version: '2.0.0', + }, + }) + + t.ok(root.overrides, 'root has overrides') + t.notOk(foo.overrides, 'foo does not have overrides') + t.notOk(bar.overrides, 'bar does not have overrides') + t.notOk(root.edgesOut.get('foo').valid, 'foo edge is not valid') + t.notOk(foo.edgesOut.get('bar').valid, 'bar edge is not valid') + + // we add bar to the root first, this is deliberate so that we don't have a simple + // linear inheritance. we'll add foo later and make sure that both edges and nodes + // become valid after that + + bar.root = root + t.ok(bar.overrides, 'bar now has overrides') + t.notOk(foo.edgesOut.get('bar').valid, 'bar edge is not valid yet') + + foo.root = root + t.ok(foo.overrides, 'foo now has overrides') + t.ok(root.edgesOut.get('foo').valid, 'foo edge is now valid') + t.ok(bar.overrides, 'bar still has overrides') + t.ok(foo.edgesOut.get('bar').valid, 'bar edge is now valid') + }) + t.test('canReplaceWith requires the same overrides', async (t) => { const original = new Node({ loadOverrides: true, From e33aa0f94f87ae4f9d2a73781e84832ef61d1855 Mon Sep 17 00:00:00 2001 From: Gar Date: Mon, 11 Apr 2022 17:26:21 -0700 Subject: [PATCH 020/406] deps: remove stringify-package (#4714) It was not being used --- node_modules/stringify-package/LICENSE | 13 ------- node_modules/stringify-package/index.js | 18 ---------- node_modules/stringify-package/package.json | 38 --------------------- package-lock.json | 11 +----- workspaces/libnpmversion/package.json | 3 +- 5 files changed, 2 insertions(+), 81 deletions(-) delete mode 100644 node_modules/stringify-package/LICENSE delete mode 100644 node_modules/stringify-package/index.js delete mode 100644 node_modules/stringify-package/package.json diff --git a/node_modules/stringify-package/LICENSE b/node_modules/stringify-package/LICENSE deleted file mode 100644 index 209e4477f39c1..0000000000000 --- a/node_modules/stringify-package/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -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 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/stringify-package/index.js b/node_modules/stringify-package/index.js deleted file mode 100644 index cd291f295a59c..0000000000000 --- a/node_modules/stringify-package/index.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -module.exports = stringifyPackage - -const DEFAULT_INDENT = 2 -const CRLF = '\r\n' -const LF = '\n' - -function stringifyPackage (data, indent, newline) { - indent = indent || (indent === 0 ? 0 : DEFAULT_INDENT) - const json = JSON.stringify(data, null, indent) - - if (newline === CRLF) { - return json.replace(/\n/g, CRLF) + CRLF - } - - return json + LF -} diff --git a/node_modules/stringify-package/package.json b/node_modules/stringify-package/package.json deleted file mode 100644 index c0e5622b47562..0000000000000 --- a/node_modules/stringify-package/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "stringify-package", - "version": "1.0.1", - "description": "stringifies npm-written json files", - "main": "index.js", - "files": [ - "index.js" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/npm/stringify-package.git" - }, - "keywords": [ - "npm", - "json", - "stringify", - "package.json" - ], - "author": "Kat Marchán ", - "license": "ISC", - "bugs": { - "url": "https://github.com/npm/stringify-package/issues" - }, - "homepage": "https://github.com/npm/stringify-package", - "scripts": { - "prerelease": "npm t", - "release": "standard-version -s", - "postrelease": "npm publish", - "postpublish": "git push --follow-tags", - "pretest": "standard", - "test": "tap -J --coverage --100 test/*.js" - }, - "devDependencies": { - "standard": "11", - "standard-version": "4", - "tap": "12" - } -} diff --git a/package-lock.json b/package-lock.json index 341037cc39065..9222c5f4ebd5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6712,10 +6712,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/stringify-package": { - "version": "1.0.1", - "license": "ISC" - }, "node_modules/strip-ansi": { "version": "6.0.1", "inBundle": true, @@ -9997,8 +9993,7 @@ "@npmcli/run-script": "^3.0.0", "json-parse-even-better-errors": "^2.3.1", "proc-log": "^2.0.0", - "semver": "^7.3.5", - "stringify-package": "^1.0.1" + "semver": "^7.3.5" }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", @@ -12928,7 +12923,6 @@ "proc-log": "^2.0.0", "require-inject": "^1.4.4", "semver": "^7.3.5", - "stringify-package": "^1.0.1", "tap": "^16.0.1" } }, @@ -14379,9 +14373,6 @@ "define-properties": "^1.1.3" } }, - "stringify-package": { - "version": "1.0.1" - }, "strip-ansi": { "version": "6.0.1", "requires": { diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index f39a84cbf1a17..f75d73c3ee6f3 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -40,8 +40,7 @@ "@npmcli/run-script": "^3.0.0", "json-parse-even-better-errors": "^2.3.1", "proc-log": "^2.0.0", - "semver": "^7.3.5", - "stringify-package": "^1.0.1" + "semver": "^7.3.5" }, "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" From 1f2d89a4c90b94b02f233b334144ff3551c87726 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 12 Apr 2022 13:18:24 -0700 Subject: [PATCH 021/406] chore: fix npm access tests (#4730) Tests the actual network calls now --- test/fixtures/mock-registry.js | 63 ++++++- test/lib/commands/access.js | 296 ++++++++++++++++----------------- 2 files changed, 205 insertions(+), 154 deletions(-) diff --git a/test/fixtures/mock-registry.js b/test/fixtures/mock-registry.js index 1cbe7b52dbe4e..b08ede6672972 100644 --- a/test/fixtures/mock-registry.js +++ b/test/fixtures/mock-registry.js @@ -40,10 +40,71 @@ class MockRegistry { this.#nock = nock } - async whoami ({ username }) { + whoami ({ username }) { this.nock.get('/-/whoami').reply(200, { username }) } + access ({ spec, access, publishRequires2fa }) { + const body = {} + if (access !== undefined) { + body.access = access + } + if (publishRequires2fa !== undefined) { + body.publish_requires_tfa = publishRequires2fa + } + this.nock.post( + `/-/package/${encodeURIComponent(spec)}/access`, + body + ).reply(200) + } + + grant ({ spec, team, permissions }) { + if (team.startsWith('@')) { + team = team.slice(1) + } + const [scope, teamName] = team.split(':') + this.nock.put( + `/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package`, + { package: spec, permissions } + ).reply(200) + } + + revoke ({ spec, team }) { + if (team.startsWith('@')) { + team = team.slice(1) + } + const [scope, teamName] = team.split(':') + this.nock.delete( + `/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package`, + { package: spec } + ).reply(200) + } + + // team can be a team or a username + lsPackages ({ team, packages = {} }) { + if (team.startsWith('@')) { + team = team.slice(1) + } + const [scope, teamName] = team.split(':') + let uri + if (teamName) { + uri = `/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package` + } else { + uri = `/-/org/${encodeURIComponent(scope)}/package` + } + this.nock.get(uri).query({ format: 'cli' }).reply(200, packages) + } + + lsCollaborators ({ spec, user, collaborators = {} }) { + const query = { format: 'cli' } + if (user) { + query.user = user + } + this.nock.get(`/-/package/${encodeURIComponent(spec)}/collaborators`) + .query(query) + .reply(200, collaborators) + } + advisory (advisory = {}) { const id = advisory.id || parseInt(Math.random() * 1000000) return { diff --git a/test/lib/commands/access.js b/test/lib/commands/access.js index f89b53e969071..130522b3be3e4 100644 --- a/test/lib/commands/access.js +++ b/test/lib/commands/access.js @@ -1,6 +1,9 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') +const MockRegistry = require('../../fixtures/mock-registry.js') + +const auth = { '//registry.npmjs.org/:_authToken': 'test-auth-token' } t.test('completion', async t => { const { npm } = await loadMockNpm(t) @@ -75,27 +78,23 @@ t.test('access public on unscoped package', async t => { }) t.test('access public on scoped package', async t => { - t.plan(2) const name = '@scoped/npm-access-public-pkg' - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - public: (pkg, { registry }) => { - t.equal(pkg, name, 'should use pkg name ref') - t.equal( - registry, - 'https://registry.npmjs.org/', - 'should forward correct options' - ) - return true - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, prefixDir: { 'package.json': JSON.stringify({ name }), }, }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.access({ spec: name, access: 'public' }) await npm.exec('access', ['public']) + t.equal(joinedOutput(), '') }) t.test('access public on missing package.json', async t => { @@ -137,27 +136,23 @@ t.test('access restricted on unscoped package', async t => { }) t.test('access restricted on scoped package', async t => { - t.plan(2) const name = '@scoped/npm-access-restricted-pkg' - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - restricted: (pkg, { registry }) => { - t.equal(pkg, name, 'should use pkg name ref') - t.equal( - registry, - 'https://registry.npmjs.org/', - 'should forward correct options' - ) - return true - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, prefixDir: { 'package.json': JSON.stringify({ name }), }, }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.access({ spec: name, access: 'restricted' }) await npm.exec('access', ['restricted']) + t.equal(joinedOutput(), '') }) t.test('access restricted on missing package.json', async t => { @@ -184,61 +179,41 @@ t.test('access restricted on invalid package.json', async t => { }) t.test('access grant read-only', async t => { - t.plan(3) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - grant: (spec, team, permissions) => { - t.equal(spec, '@scoped/another', 'should use expected spec') - t.equal(team, 'myorg:myteam', 'should use expected team') - t.equal(permissions, 'read-only', 'should forward permissions') - return true - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, }) - await npm.exec('access', [ - 'grant', - 'read-only', - 'myorg:myteam', - '@scoped/another', - ]) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.grant({ spec: '@scoped/another', team: 'myorg:myteam', permissions: 'read-only' }) + await npm.exec('access', ['grant', 'read-only', 'myorg:myteam', '@scoped/another']) + t.equal(joinedOutput(), '') }) t.test('access grant read-write', async t => { - t.plan(3) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - grant: (spec, team, permissions) => { - t.equal(spec, '@scoped/another', 'should use expected spec') - t.equal(team, 'myorg:myteam', 'should use expected team') - t.equal(permissions, 'read-write', 'should forward permissions') - return true - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, }) - await npm.exec('access', [ - 'grant', - 'read-write', - 'myorg:myteam', - '@scoped/another', - ]) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.grant({ spec: '@scoped/another', team: 'myorg:myteam', permissions: 'read-write' }) + await npm.exec('access', ['grant', 'read-write', 'myorg:myteam', '@scoped/another']) + t.equal(joinedOutput(), '') }) t.test('access grant current cwd', async t => { - t.plan(3) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - grant: (spec, team, permissions) => { - t.equal(spec, 'yargs', 'should use expected spec') - t.equal(team, 'myorg:myteam', 'should use expected team') - t.equal(permissions, 'read-write', 'should forward permissions') - return true - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, prefixDir: { 'package.json': JSON.stringify({ @@ -246,11 +221,14 @@ t.test('access grant current cwd', async t => { }), }, }) - await npm.exec('access', [ - 'grant', - 'read-write', - 'myorg:myteam', - ]) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.grant({ spec: 'yargs', team: 'myorg:myteam', permissions: 'read-write' }) + await npm.exec('access', ['grant', 'read-write', 'myorg:myteam']) + t.equal(joinedOutput(), '') }) t.test('access grant others', async t => { @@ -295,44 +273,52 @@ t.test('access grant malformed team arg', async t => { ) }) -t.test('access 2fa-required/2fa-not-required', async t => { - t.plan(2) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - tfaRequired: (spec) => { - t.equal(spec, '@scope/pkg', 'should use expected spec') - return true - }, - tfaNotRequired: (spec) => { - t.equal(spec, 'unscoped-pkg', 'should use expected spec') - return true - }, - }, +t.test('access 2fa-required', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.access({ spec: '@scope/pkg', publishRequires2fa: true }) await npm.exec('access', ['2fa-required', '@scope/pkg']) - await npm.exec('access', ['2fa-not-required', 'unscoped-pkg']) + t.equal(joinedOutput(), '') +}) + +t.test('access 2fa-not-required', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.access({ spec: '@scope/pkg', publishRequires2fa: false }) + await npm.exec('access', ['2fa-not-required', '@scope/pkg']) + t.equal(joinedOutput(), '') }) t.test('access revoke', async t => { - t.plan(2) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - revoke: (spec, team) => { - t.equal(spec, '@scoped/another', 'should use expected spec') - t.equal(team, 'myorg:myteam', 'should use expected team') - return true - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, }) - await npm.exec('access', [ - 'revoke', - 'myorg:myteam', - '@scoped/another', - ]) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + registry.revoke({ spec: '@scoped/another', team: 'myorg:myteam' }) + await npm.exec('access', ['revoke', 'myorg:myteam', '@scoped/another']) + t.equal(joinedOutput(), '') }) t.test('access revoke missing team args', async t => { @@ -362,49 +348,46 @@ t.test('access revoke malformed team arg', async t => { }) t.test('npm access ls-packages with no team', async t => { - t.plan(1) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - lsPackages: (entity) => { - t.equal(entity, 'foo', 'should use expected entity') - return {} - }, - }, - '../../lib/utils/get-identity.js': () => Promise.resolve('foo'), + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + const team = 'foo' + const packages = { 'test-package': 'read-write' } + registry.whoami({ username: team }) + registry.lsPackages({ team, packages }) await npm.exec('access', ['ls-packages']) + t.match(JSON.parse(joinedOutput()), packages) }) t.test('access ls-packages on team', async t => { - t.plan(1) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - lsPackages: (entity) => { - t.equal(entity, 'myorg:myteam', 'should use expected entity') - return {} - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, }) - await npm.exec('access', [ - 'ls-packages', - 'myorg:myteam', - ]) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + const team = 'myorg:myteam' + const packages = { 'test-package': 'read-write' } + registry.lsPackages({ team, packages }) + await npm.exec('access', ['ls-packages', 'myorg:myteam']) + t.match(JSON.parse(joinedOutput()), packages) }) t.test('access ls-collaborators on current', async t => { - t.plan(1) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - lsCollaborators: (spec) => { - t.equal(spec, 'yargs', 'should use expected spec') - return {} - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, prefixDir: { 'package.json': JSON.stringify({ @@ -412,23 +395,30 @@ t.test('access ls-collaborators on current', async t => { }), }, }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + const collaborators = { 'test-user': 'read-write' } + registry.lsCollaborators({ spec: 'yargs', collaborators }) await npm.exec('access', ['ls-collaborators']) + t.match(JSON.parse(joinedOutput()), collaborators) }) t.test('access ls-collaborators on spec', async t => { - t.plan(1) - const { npm } = await loadMockNpm(t, { - mocks: { - libnpmaccess: { - lsCollaborators: (spec) => { - t.equal(spec, 'yargs', 'should use expected spec') - return {} - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, }, }) - await npm.exec('access', [ - 'ls-collaborators', - 'yargs', - ]) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: 'test-auth-token', + }) + const collaborators = { 'test-user': 'read-write' } + registry.lsCollaborators({ spec: 'yargs', collaborators }) + await npm.exec('access', ['ls-collaborators', 'yargs']) + t.match(JSON.parse(joinedOutput()), collaborators) }) From 877138eb4d1c4470c4164fc6e057d082b120fb05 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 13 Apr 2022 14:18:02 -0700 Subject: [PATCH 022/406] chore: add DEPENDENCIES.md (#4710) This adds a script to generate dependency information for the npm cli. The dependency info shows all of the packages in npm that the npm-cli team themselves manage. --- .gitignore | 1 + DEPENDENCIES.md | 738 ++++++++++++++++++++++++++++++++++++ scripts/dependency-graph.js | 174 +++++++++ scripts/npm-cli-repos.txt | 88 +++++ 4 files changed, 1001 insertions(+) create mode 100644 DEPENDENCIES.md create mode 100644 scripts/dependency-graph.js create mode 100644 scripts/npm-cli-repos.txt diff --git a/.gitignore b/.gitignore index c42e815c421e4..8f054d246da48 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ !/package.json !/README.md !/SECURITY.md +!/DEPENDENCIES.md diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md new file mode 100644 index 0000000000000..61803e40853f8 --- /dev/null +++ b/DEPENDENCIES.md @@ -0,0 +1,738 @@ +# npm dependencies + +## `github.com/npm/` only +```mermaid +graph LR; + bin-links-->cmd-shim; + bin-links-->npm-normalize-package-bin; + bin-links-->read-cmd-shim; + bin-links-->write-file-atomic; + cacache-->fs-minipass; + cacache-->infer-owner; + cacache-->npmcli-fs["@npmcli/fs"]; + cacache-->npmcli-move-file["@npmcli/move-file"]; + cacache-->ssri; + cacache-->unique-filename; + dezalgo-->wrappy; + init-package-json-->npm-package-arg; + init-package-json-->promzard; + init-package-json-->read-package-json; + init-package-json-->read; + init-package-json-->semver; + init-package-json-->validate-npm-package-name; + libnpmaccess-->npm-package-arg; + libnpmaccess-->npm-registry-fetch; + libnpmaccess-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmaccess-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmdiff-->npm-package-arg; + libnpmdiff-->npmcli-disparity-colors["@npmcli/disparity-colors"]; + libnpmdiff-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmdiff-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + libnpmdiff-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmdiff-->pacote; + libnpmexec-->bin-links; + libnpmexec-->npm-package-arg; + libnpmexec-->npmcli-arborist["@npmcli/arborist"]; + libnpmexec-->npmcli-ci-detect["@npmcli/ci-detect"]; + libnpmexec-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmexec-->npmcli-run-script["@npmcli/run-script"]; + libnpmexec-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmexec-->npmlog; + libnpmexec-->pacote; + libnpmexec-->proc-log; + libnpmexec-->read-package-json-fast; + libnpmexec-->read; + libnpmfund-->npmcli-arborist["@npmcli/arborist"]; + libnpmfund-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmfund-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmhook-->npm-registry-fetch; + libnpmhook-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmhook-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmorg-->npm-registry-fetch; + libnpmorg-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmorg-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmpack-->npm-package-arg; + libnpmpack-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmpack-->npmcli-run-script["@npmcli/run-script"]; + libnpmpack-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmpack-->pacote; + libnpmpublish-->libnpmpack; + libnpmpublish-->normalize-package-data; + libnpmpublish-->npm-package-arg; + libnpmpublish-->npm-registry-fetch; + libnpmpublish-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmpublish-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmpublish-->semver; + libnpmpublish-->ssri; + libnpmsearch-->npm-registry-fetch; + libnpmsearch-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmsearch-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmteam-->npm-registry-fetch; + libnpmteam-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmteam-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmversion-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmversion-->npmcli-git["@npmcli/git"]; + libnpmversion-->npmcli-run-script["@npmcli/run-script"]; + libnpmversion-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmversion-->proc-log; + libnpmversion-->semver; + libnpmversion-->stringify-package; + make-fetch-happen-->cacache; + make-fetch-happen-->minipass-fetch; + make-fetch-happen-->ssri; + nopt-->abbrev; + normalize-package-data-->hosted-git-info; + normalize-package-data-->semver; + npm-->abbrev; + npm-->cacache; + npm-->hosted-git-info; + npm-->ini; + npm-->init-package-json; + npm-->libnpmaccess; + npm-->libnpmdiff; + npm-->libnpmexec; + npm-->libnpmfund; + npm-->libnpmhook; + npm-->libnpmorg; + npm-->libnpmpack; + npm-->libnpmpublish; + npm-->libnpmsearch; + npm-->libnpmteam; + npm-->libnpmversion; + npm-->make-fetch-happen; + npm-->nopt; + npm-->npm-audit-report; + npm-->npm-install-checks; + npm-->npm-package-arg; + npm-->npm-profile; + npm-->npm-registry-fetch; + npm-->npm-user-validate; + npm-->npmcli-arborist["@npmcli/arborist"]; + npm-->npmcli-ci-detect["@npmcli/ci-detect"]; + npm-->npmcli-config["@npmcli/config"]; + npm-->npmcli-eslint-config["@npmcli/eslint-config"]; + npm-->npmcli-fs["@npmcli/fs"]; + npm-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npm-->npmcli-package-json["@npmcli/package-json"]; + npm-->npmcli-run-script["@npmcli/run-script"]; + npm-->npmcli-template-oss["@npmcli/template-oss"]; + npm-->npmlog; + npm-->pacote; + npm-->parse-conflict-json; + npm-->proc-log; + npm-->read-package-json-fast; + npm-->read-package-json; + npm-->read; + npm-->readdir-scoped-modules; + npm-->semver; + npm-->ssri; + npm-->treeverse; + npm-->validate-npm-package-name; + npm-->write-file-atomic; + npm-bundled-->npm-normalize-package-bin; + npm-install-checks-->semver; + npm-package-arg-->hosted-git-info; + npm-package-arg-->semver; + npm-package-arg-->validate-npm-package-name; + npm-packlist-->ignore-walk; + npm-packlist-->npm-bundled; + npm-packlist-->npm-normalize-package-bin; + npm-profile-->npm-registry-fetch; + npm-profile-->proc-log; + npm-registry-fetch-->make-fetch-happen; + npm-registry-fetch-->minipass-fetch; + npm-registry-fetch-->npm-package-arg; + npm-registry-fetch-->proc-log; + npmcli-arborist-->bin-links; + npmcli-arborist-->cacache; + npmcli-arborist-->nopt; + npmcli-arborist-->npm-install-checks; + npmcli-arborist-->npm-package-arg; + npmcli-arborist-->npm-registry-fetch; + npmcli-arborist-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-arborist-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + npmcli-arborist-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npmcli-arborist-->npmcli-metavuln-calculator["@npmcli/metavuln-calculator"]; + npmcli-arborist-->npmcli-move-file["@npmcli/move-file"]; + npmcli-arborist-->npmcli-name-from-folder["@npmcli/name-from-folder"]; + npmcli-arborist-->npmcli-node-gyp["@npmcli/node-gyp"]; + npmcli-arborist-->npmcli-package-json["@npmcli/package-json"]; + npmcli-arborist-->npmcli-run-script["@npmcli/run-script"]; + npmcli-arborist-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-arborist-->npmlog; + npmcli-arborist-->pacote; + npmcli-arborist-->parse-conflict-json; + npmcli-arborist-->proc-log; + npmcli-arborist-->read-package-json-fast; + npmcli-arborist-->readdir-scoped-modules; + npmcli-arborist-->semver; + npmcli-arborist-->ssri; + npmcli-arborist-->treeverse; + npmcli-config-->ini; + npmcli-config-->nopt; + npmcli-config-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npmcli-config-->proc-log; + npmcli-config-->read-package-json-fast; + npmcli-config-->semver; + npmcli-fs-->semver; + npmcli-git-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-git-->proc-log; + npmcli-git-->semver; + npmcli-installed-package-contents-->npm-bundled; + npmcli-installed-package-contents-->npm-normalize-package-bin; + npmcli-map-workspaces-->npmcli-name-from-folder["@npmcli/name-from-folder"]; + npmcli-map-workspaces-->read-package-json-fast; + npmcli-metavuln-calculator-->cacache; + npmcli-metavuln-calculator-->pacote; + npmcli-metavuln-calculator-->semver; + npmcli-promise-spawn-->infer-owner; + npmcli-run-script-->npmcli-node-gyp["@npmcli/node-gyp"]; + npmcli-run-script-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-run-script-->read-package-json-fast; + npmlog-->are-we-there-yet; + npmlog-->gauge; + pacote-->cacache; + pacote-->fs-minipass; + pacote-->infer-owner; + pacote-->npm-package-arg; + pacote-->npm-packlist; + pacote-->npm-registry-fetch; + pacote-->npmcli-git["@npmcli/git"]; + pacote-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + pacote-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + pacote-->npmcli-run-script["@npmcli/run-script"]; + pacote-->proc-log; + pacote-->read-package-json-fast; + pacote-->read-package-json; + pacote-->ssri; + promzard-->read; + read-->mute-stream; + read-package-json-->normalize-package-data; + read-package-json-->npm-normalize-package-bin; + read-package-json-fast-->npm-normalize-package-bin; + readdir-scoped-modules-->dezalgo; + unique-filename-->unique-slug; +``` + +## all dependencies +```mermaid +graph LR; + agent-base-->debug; + agentkeepalive-->debug; + agentkeepalive-->depd; + agentkeepalive-->humanize-ms; + aggregate-error-->clean-stack; + aggregate-error-->indent-string; + ansi-styles-->color-convert; + are-we-there-yet-->delegates; + are-we-there-yet-->readable-stream; + bin-links-->cmd-shim; + bin-links-->mkdirp-infer-owner; + bin-links-->npm-normalize-package-bin; + bin-links-->read-cmd-shim; + bin-links-->rimraf; + bin-links-->write-file-atomic; + brace-expansion-->balanced-match; + brace-expansion-->concat-map; + builtins-->semver; + cacache-->chownr; + cacache-->fs-minipass; + cacache-->glob; + cacache-->infer-owner; + cacache-->lru-cache; + cacache-->minipass-collect; + cacache-->minipass-flush; + cacache-->minipass-pipeline; + cacache-->minipass; + cacache-->mkdirp; + cacache-->npmcli-fs["@npmcli/fs"]; + cacache-->npmcli-move-file["@npmcli/move-file"]; + cacache-->p-map; + cacache-->promise-inflight; + cacache-->rimraf; + cacache-->ssri; + cacache-->tar; + cacache-->unique-filename; + chalk-->ansi-styles; + chalk-->supports-color; + cidr-regex-->ip-regex; + cli-columns-->string-width; + cli-columns-->strip-ansi; + cli-table3-->colors; + cli-table3-->string-width; + cmd-shim-->mkdirp-infer-owner; + color-convert-->color-name; + columnify-->strip-ansi; + columnify-->wcwidth; + debug-->ms; + defaults-->clone; + dezalgo-->asap; + dezalgo-->wrappy; + docs-->cmark-gfm; + docs-->jsdom; + docs-->marked-man; + docs-->mdx-js-mdx["@mdx-js/mdx"]; + docs-->npmcli-eslint-config["@npmcli/eslint-config"]; + docs-->npmcli-fs["@npmcli/fs"]; + docs-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + docs-->npmcli-template-oss["@npmcli/template-oss"]; + docs-->tap; + docs-->which; + docs-->yaml; + encoding-->iconv-lite; + fs-minipass-->minipass; + gauge-->aproba; + gauge-->color-support; + gauge-->console-control-strings; + gauge-->has-unicode; + gauge-->signal-exit; + gauge-->string-width; + gauge-->strip-ansi; + gauge-->wide-align; + glob-->fs.realpath; + glob-->inflight; + glob-->inherits; + glob-->minimatch; + glob-->once; + glob-->path-is-absolute; + has-->function-bind; + hosted-git-info-->lru-cache; + http-proxy-agent-->agent-base; + http-proxy-agent-->debug; + http-proxy-agent-->tootallnate-once["@tootallnate/once"]; + https-proxy-agent-->agent-base; + https-proxy-agent-->debug; + humanize-ms-->ms; + iconv-lite-->safer-buffer; + ignore-walk-->minimatch; + inflight-->once; + inflight-->wrappy; + init-package-json-->npm-package-arg; + init-package-json-->promzard; + init-package-json-->read-package-json; + init-package-json-->read; + init-package-json-->semver; + init-package-json-->validate-npm-package-license; + init-package-json-->validate-npm-package-name; + is-cidr-->cidr-regex; + is-core-module-->has; + libnpmaccess-->aproba; + libnpmaccess-->minipass; + libnpmaccess-->nock; + libnpmaccess-->npm-package-arg; + libnpmaccess-->npm-registry-fetch; + libnpmaccess-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmaccess-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmaccess-->tap; + libnpmdiff-->binary-extensions; + libnpmdiff-->diff; + libnpmdiff-->minimatch; + libnpmdiff-->npm-package-arg; + libnpmdiff-->npmcli-disparity-colors["@npmcli/disparity-colors"]; + libnpmdiff-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmdiff-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + libnpmdiff-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmdiff-->pacote; + libnpmdiff-->tap; + libnpmdiff-->tar; + libnpmexec-->bin-links; + libnpmexec-->chalk; + libnpmexec-->mkdirp-infer-owner; + libnpmexec-->npm-package-arg; + libnpmexec-->npmcli-arborist["@npmcli/arborist"]; + libnpmexec-->npmcli-ci-detect["@npmcli/ci-detect"]; + libnpmexec-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmexec-->npmcli-run-script["@npmcli/run-script"]; + libnpmexec-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmexec-->npmlog; + libnpmexec-->pacote; + libnpmexec-->proc-log; + libnpmexec-->read-package-json-fast; + libnpmexec-->read; + libnpmexec-->tap; + libnpmexec-->walk-up-path; + libnpmfund-->npmcli-arborist["@npmcli/arborist"]; + libnpmfund-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmfund-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmfund-->tap; + libnpmhook-->aproba; + libnpmhook-->nock; + libnpmhook-->npm-registry-fetch; + libnpmhook-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmhook-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmhook-->tap; + libnpmorg-->aproba; + libnpmorg-->minipass; + libnpmorg-->nock; + libnpmorg-->npm-registry-fetch; + libnpmorg-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmorg-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmorg-->tap; + libnpmpack-->nock; + libnpmpack-->npm-package-arg; + libnpmpack-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmpack-->npmcli-run-script["@npmcli/run-script"]; + libnpmpack-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmpack-->pacote; + libnpmpack-->tap; + libnpmpublish-->libnpmpack; + libnpmpublish-->lodash.clonedeep; + libnpmpublish-->nock; + libnpmpublish-->normalize-package-data; + libnpmpublish-->npm-package-arg; + libnpmpublish-->npm-registry-fetch; + libnpmpublish-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmpublish-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmpublish-->semver; + libnpmpublish-->ssri; + libnpmpublish-->tap; + libnpmsearch-->nock; + libnpmsearch-->npm-registry-fetch; + libnpmsearch-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmsearch-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmsearch-->tap; + libnpmteam-->aproba; + libnpmteam-->nock; + libnpmteam-->npm-registry-fetch; + libnpmteam-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmteam-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmteam-->tap; + libnpmversion-->json-parse-even-better-errors; + libnpmversion-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmversion-->npmcli-git["@npmcli/git"]; + libnpmversion-->npmcli-run-script["@npmcli/run-script"]; + libnpmversion-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmversion-->proc-log; + libnpmversion-->require-inject; + libnpmversion-->semver; + libnpmversion-->stringify-package; + libnpmversion-->tap; + make-fetch-happen-->agentkeepalive; + make-fetch-happen-->cacache; + make-fetch-happen-->http-cache-semantics; + make-fetch-happen-->http-proxy-agent; + make-fetch-happen-->https-proxy-agent; + make-fetch-happen-->is-lambda; + make-fetch-happen-->lru-cache; + make-fetch-happen-->minipass-collect; + make-fetch-happen-->minipass-fetch; + make-fetch-happen-->minipass-flush; + make-fetch-happen-->minipass-pipeline; + make-fetch-happen-->minipass; + make-fetch-happen-->negotiator; + make-fetch-happen-->promise-retry; + make-fetch-happen-->socks-proxy-agent; + make-fetch-happen-->ssri; + minimatch-->brace-expansion; + minipass-->yallist; + minipass-collect-->minipass; + minipass-fetch-->encoding; + minipass-fetch-->minipass-sized; + minipass-fetch-->minipass; + minipass-fetch-->minizlib; + minipass-flush-->minipass; + minipass-json-stream-->jsonparse; + minipass-json-stream-->minipass; + minipass-pipeline-->minipass; + minipass-sized-->minipass; + minizlib-->minipass; + minizlib-->yallist; + mkdirp-infer-owner-->chownr; + mkdirp-infer-owner-->infer-owner; + mkdirp-infer-owner-->mkdirp; + node-gyp-->env-paths; + node-gyp-->glob; + node-gyp-->graceful-fs; + node-gyp-->make-fetch-happen; + node-gyp-->nopt; + node-gyp-->npmlog; + node-gyp-->rimraf; + node-gyp-->semver; + node-gyp-->tar; + node-gyp-->which; + nopt-->abbrev; + normalize-package-data-->hosted-git-info; + normalize-package-data-->is-core-module; + normalize-package-data-->semver; + normalize-package-data-->validate-npm-package-license; + npm-->abbrev; + npm-->ansicolors; + npm-->ansistyles; + npm-->archy; + npm-->cacache; + npm-->chalk; + npm-->chownr; + npm-->cli-columns; + npm-->cli-table3; + npm-->columnify; + npm-->docs; + npm-->fastest-levenshtein; + npm-->glob; + npm-->graceful-fs; + npm-->hosted-git-info; + npm-->ini; + npm-->init-package-json; + npm-->is-cidr; + npm-->isaacs-string-locale-compare["@isaacs/string-locale-compare"]; + npm-->json-parse-even-better-errors; + npm-->libnpmaccess; + npm-->libnpmdiff; + npm-->libnpmexec; + npm-->libnpmfund; + npm-->libnpmhook; + npm-->libnpmorg; + npm-->libnpmpack; + npm-->libnpmpublish; + npm-->libnpmsearch; + npm-->libnpmteam; + npm-->libnpmversion; + npm-->licensee; + npm-->make-fetch-happen; + npm-->minipass-pipeline; + npm-->minipass; + npm-->mkdirp-infer-owner; + npm-->mkdirp; + npm-->ms; + npm-->nock; + npm-->node-gyp; + npm-->nopt; + npm-->npm-audit-report; + npm-->npm-install-checks; + npm-->npm-package-arg; + npm-->npm-pick-manifest; + npm-->npm-profile; + npm-->npm-registry-fetch; + npm-->npm-user-validate; + npm-->npmcli-arborist["@npmcli/arborist"]; + npm-->npmcli-ci-detect["@npmcli/ci-detect"]; + npm-->npmcli-config["@npmcli/config"]; + npm-->npmcli-eslint-config["@npmcli/eslint-config"]; + npm-->npmcli-fs["@npmcli/fs"]; + npm-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npm-->npmcli-package-json["@npmcli/package-json"]; + npm-->npmcli-run-script["@npmcli/run-script"]; + npm-->npmcli-template-oss["@npmcli/template-oss"]; + npm-->npmlog; + npm-->opener; + npm-->pacote; + npm-->parse-conflict-json; + npm-->proc-log; + npm-->qrcode-terminal; + npm-->read-package-json-fast; + npm-->read-package-json; + npm-->read; + npm-->readdir-scoped-modules; + npm-->rimraf; + npm-->semver; + npm-->spawk; + npm-->ssri; + npm-->tap; + npm-->tar; + npm-->text-table; + npm-->tiny-relative-date; + npm-->treeverse; + npm-->validate-npm-package-name; + npm-->which; + npm-->write-file-atomic; + npm-audit-report-->chalk; + npm-bundled-->npm-normalize-package-bin; + npm-install-checks-->semver; + npm-package-arg-->hosted-git-info; + npm-package-arg-->semver; + npm-package-arg-->validate-npm-package-name; + npm-packlist-->glob; + npm-packlist-->ignore-walk; + npm-packlist-->npm-bundled; + npm-packlist-->npm-normalize-package-bin; + npm-pick-manifest-->npm-install-checks; + npm-pick-manifest-->npm-normalize-package-bin; + npm-pick-manifest-->npm-package-arg; + npm-pick-manifest-->semver; + npm-profile-->npm-registry-fetch; + npm-profile-->proc-log; + npm-registry-fetch-->make-fetch-happen; + npm-registry-fetch-->minipass-fetch; + npm-registry-fetch-->minipass-json-stream; + npm-registry-fetch-->minipass; + npm-registry-fetch-->minizlib; + npm-registry-fetch-->npm-package-arg; + npm-registry-fetch-->proc-log; + npmcli-arborist-->benchmark; + npmcli-arborist-->bin-links; + npmcli-arborist-->cacache; + npmcli-arborist-->chalk; + npmcli-arborist-->common-ancestor-path; + npmcli-arborist-->isaacs-string-locale-compare["@isaacs/string-locale-compare"]; + npmcli-arborist-->json-parse-even-better-errors; + npmcli-arborist-->json-stringify-nice; + npmcli-arborist-->minify-registry-metadata; + npmcli-arborist-->mkdirp-infer-owner; + npmcli-arborist-->mkdirp; + npmcli-arborist-->nock; + npmcli-arborist-->nopt; + npmcli-arborist-->npm-install-checks; + npmcli-arborist-->npm-package-arg; + npmcli-arborist-->npm-pick-manifest; + npmcli-arborist-->npm-registry-fetch; + npmcli-arborist-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-arborist-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + npmcli-arborist-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npmcli-arborist-->npmcli-metavuln-calculator["@npmcli/metavuln-calculator"]; + npmcli-arborist-->npmcli-move-file["@npmcli/move-file"]; + npmcli-arborist-->npmcli-name-from-folder["@npmcli/name-from-folder"]; + npmcli-arborist-->npmcli-node-gyp["@npmcli/node-gyp"]; + npmcli-arborist-->npmcli-package-json["@npmcli/package-json"]; + npmcli-arborist-->npmcli-run-script["@npmcli/run-script"]; + npmcli-arborist-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-arborist-->npmlog; + npmcli-arborist-->pacote; + npmcli-arborist-->parse-conflict-json; + npmcli-arborist-->proc-log; + npmcli-arborist-->promise-all-reject-late; + npmcli-arborist-->promise-call-limit; + npmcli-arborist-->read-package-json-fast; + npmcli-arborist-->readdir-scoped-modules; + npmcli-arborist-->rimraf; + npmcli-arborist-->semver; + npmcli-arborist-->ssri; + npmcli-arborist-->tap; + npmcli-arborist-->tcompare; + npmcli-arborist-->treeverse; + npmcli-arborist-->walk-up-path; + npmcli-config-->ini; + npmcli-config-->mkdirp-infer-owner; + npmcli-config-->nopt; + npmcli-config-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npmcli-config-->proc-log; + npmcli-config-->read-package-json-fast; + npmcli-config-->semver; + npmcli-config-->walk-up-path; + npmcli-disparity-colors-->ansi-styles; + npmcli-fs-->gar-promisify["@gar/promisify"]; + npmcli-fs-->semver; + npmcli-git-->lru-cache; + npmcli-git-->mkdirp; + npmcli-git-->npm-pick-manifest; + npmcli-git-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-git-->proc-log; + npmcli-git-->promise-inflight; + npmcli-git-->promise-retry; + npmcli-git-->semver; + npmcli-git-->which; + npmcli-installed-package-contents-->npm-bundled; + npmcli-installed-package-contents-->npm-normalize-package-bin; + npmcli-map-workspaces-->glob; + npmcli-map-workspaces-->minimatch; + npmcli-map-workspaces-->npmcli-name-from-folder["@npmcli/name-from-folder"]; + npmcli-map-workspaces-->read-package-json-fast; + npmcli-metavuln-calculator-->cacache; + npmcli-metavuln-calculator-->json-parse-even-better-errors; + npmcli-metavuln-calculator-->pacote; + npmcli-metavuln-calculator-->semver; + npmcli-move-file-->mkdirp; + npmcli-move-file-->rimraf; + npmcli-package-json-->json-parse-even-better-errors; + npmcli-promise-spawn-->infer-owner; + npmcli-run-script-->node-gyp; + npmcli-run-script-->npmcli-node-gyp["@npmcli/node-gyp"]; + npmcli-run-script-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-run-script-->read-package-json-fast; + npmlog-->are-we-there-yet; + npmlog-->console-control-strings; + npmlog-->gauge; + npmlog-->set-blocking; + once-->wrappy; + p-map-->aggregate-error; + pacote-->cacache; + pacote-->chownr; + pacote-->fs-minipass; + pacote-->infer-owner; + pacote-->minipass; + pacote-->mkdirp; + pacote-->npm-package-arg; + pacote-->npm-packlist; + pacote-->npm-pick-manifest; + pacote-->npm-registry-fetch; + pacote-->npmcli-git["@npmcli/git"]; + pacote-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + pacote-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + pacote-->npmcli-run-script["@npmcli/run-script"]; + pacote-->proc-log; + pacote-->promise-retry; + pacote-->read-package-json-fast; + pacote-->read-package-json; + pacote-->rimraf; + pacote-->ssri; + pacote-->tar; + parse-conflict-json-->json-parse-even-better-errors; + parse-conflict-json-->just-diff-apply; + parse-conflict-json-->just-diff; + promise-retry-->err-code; + promise-retry-->retry; + promzard-->read; + read-->mute-stream; + read-package-json-->glob; + read-package-json-->json-parse-even-better-errors; + read-package-json-->normalize-package-data; + read-package-json-->npm-normalize-package-bin; + read-package-json-fast-->json-parse-even-better-errors; + read-package-json-fast-->npm-normalize-package-bin; + readable-stream-->inherits; + readable-stream-->string_decoder; + readable-stream-->util-deprecate; + readdir-scoped-modules-->debuglog; + readdir-scoped-modules-->dezalgo; + readdir-scoped-modules-->graceful-fs; + readdir-scoped-modules-->once; + rimraf-->glob; + semver-->lru-cache; + socks-->ip; + socks-->smart-buffer; + socks-proxy-agent-->agent-base; + socks-proxy-agent-->debug; + socks-proxy-agent-->socks; + spdx-correct-->spdx-expression-parse; + spdx-correct-->spdx-license-ids; + spdx-expression-parse-->spdx-exceptions; + spdx-expression-parse-->spdx-license-ids; + ssri-->minipass; + string-width-->emoji-regex; + string-width-->is-fullwidth-code-point; + string-width-->strip-ansi; + string_decoder-->safe-buffer; + strip-ansi-->ansi-regex; + supports-color-->has-flag; + tar-->chownr; + tar-->fs-minipass; + tar-->minipass; + tar-->minizlib; + tar-->mkdirp; + tar-->yallist; + unique-filename-->unique-slug; + unique-slug-->imurmurhash; + validate-npm-package-license-->spdx-correct; + validate-npm-package-license-->spdx-expression-parse; + validate-npm-package-name-->builtins; + wcwidth-->defaults; + which-->isexe; + wide-align-->string-width; + write-file-atomic-->imurmurhash; + write-file-atomic-->signal-exit; +``` + +## npm dependency heirarchy + +These are the groups of dependencies in npm that depend on each other. +Each group depends on packages lower down the chain, nothing depends on +packages higher up the chain. + + - npm + - libnpmexec, libnpmfund + - @npmcli/arborist, libnpmpublish + - @npmcli/metavuln-calculator, libnpmdiff, libnpmpack + - pacote, libnpmaccess, libnpmhook, libnpmorg, libnpmsearch, libnpmteam, npm-profile + - npm-registry-fetch + - make-fetch-happen, libnpmversion, @npmcli/config, init-package-json + - @npmcli/installed-package-contents, @npmcli/map-workspaces, cacache, @npmcli/git, @npmcli/run-script, npm-packlist, read-package-json, readdir-scoped-modules, promzard + - npm-bundled, read-package-json-fast, @npmcli/fs, unique-filename, @npmcli/promise-spawn, npm-package-arg, normalize-package-data, bin-links, nopt, npm-install-checks, npmlog, dezalgo, read + - npm-normalize-package-bin, @npmcli/name-from-folder, semver, @npmcli/move-file, fs-minipass, infer-owner, ssri, unique-slug, proc-log, @npmcli/node-gyp, hosted-git-info, validate-npm-package-name, ignore-walk, minipass-fetch, @npmcli/package-json, cmd-shim, read-cmd-shim, write-file-atomic, abbrev, are-we-there-yet, gauge, parse-conflict-json, wrappy, treeverse, @npmcli/eslint-config, @npmcli/template-oss, @npmcli/disparity-colors, @npmcli/ci-detect, mute-stream, stringify-package, ini, npm-audit-report, npm-user-validate \ No newline at end of file diff --git a/scripts/dependency-graph.js b/scripts/dependency-graph.js new file mode 100644 index 0000000000000..318b9f39b4292 --- /dev/null +++ b/scripts/dependency-graph.js @@ -0,0 +1,174 @@ +'use strict' + +// Generates our dependency graph documents in DEPENDENCIES.md. + +const Arborist = require('@npmcli/arborist') +const fs = require('fs') + +// To re-create npm-cli-repos.txt run: +/* eslint-disable-next-line max-len */ +// gh api "/graphql" -F query='query { search (query: "org:npm topic:npm-cli", type: REPOSITORY, first:100) { nodes { ... on Repository { name } } } }' --jq '.data.search.nodes[].name'|sort +const repos = fs.readFileSync('./scripts/npm-cli-repos.txt', 'utf8').trim().split('\n') + +// these have a different package name than the repo name, and are ours. +const aliases = { + semver: 'node-semver', + abbrev: 'abbrev-js', +} + +// These are entries in npm-cli-repos.txt that correlate to namespaced repos. +// If we see a bare package with just this name, it's NOT ours +const namespaced = [ + 'arborist', + 'ci-detect', + 'config', + 'disparity-colors', + 'eslint-config', + 'exec', + 'fs', + 'git', + 'installed-package-contents', + 'lint', + 'map-workspaces', + 'metavuln-calculator', + 'move-file', + 'name-from-folder', + 'node-gyp', + 'package-json', + 'promise-spawn', + 'run-script', + 'template-oss', +] + +function isOurs (name) { + if (name.startsWith('libnpm')) { + return true + } + if (name.startsWith('@npmcli')) { + return true + } + if (aliases[name]) { + return true + } + // this will prevent e.g. `fs` from being mistaken as ours + if (namespaced.includes(name)) { + return false + } + if (repos.includes(name)) { + return true + } + return false +} + +function escapeName (name) { + if (name.startsWith('@')) { + return `${stripName(name)}["${name}"]` + } + return name +} +function stripName (name) { + if (name.startsWith('@')) { + const parts = name.slice(1).split('/') + return `${parts[0]}-${parts[1]}` + } + return name +} + +const main = async function () { + const arborist = new Arborist({ + prefix: process.cwd(), + path: process.cwd(), + }) + const tree = await arborist.loadVirtual({ path: process.cwd(), name: 'npm' }) + tree.name = 'npm' + + const { + heirarchy: heirarchyOurs, + annotations: annotationsOurs, + } = walk(tree, true) + + const { + annotations: annotationsAll, + } = walk(tree, false) + + const out = [ + '# npm dependencies', + '', + '## `github.com/npm/` only', + '```mermaid', + 'graph LR;', + ...annotationsOurs.sort(), + '```', + '', + '## all dependencies', + '```mermaid', + 'graph LR;', + ...annotationsAll.sort(), + '```', + '', + '## npm dependency heirarchy', + '', + 'These are the groups of dependencies in npm that depend on each other.', + 'Each group depends on packages lower down the chain, nothing depends on', + 'packages higher up the chain.', + '', + ` - ${heirarchyOurs.reverse().join('\n - ')}`, + ] + fs.writeFileSync('DEPENDENCIES.md', out.join('\n')) + console.log('wrote to DEPENDENCIES.md') +} + +const walk = function (tree, onlyOurs) { + const annotations = [] // mermaid dependency annotations + const dependedBy = {} + iterate(tree, dependedBy, annotations, onlyOurs) + const allDeps = new Set(Object.keys(dependedBy)) + const foundDeps = new Set() + const heirarchy = [] + while (allDeps.size) { + const level = [] + for (const dep of allDeps) { + if (!dependedBy[dep].size) { + level.push(dep) + foundDeps.add(dep) + } + } + for (const dep of allDeps) { + for (const found of foundDeps) { + allDeps.delete(found) + dependedBy[dep].delete(found) + } + } + if (!level.length) { + throw new Error('Would do an infinite loop here, need to debug') + } + heirarchy.push(level.join(', ')) + } + + return { heirarchy, annotations } +} +const iterate = function (node, dependedBy, annotations, onlyOurs) { + if (!dependedBy[node.packageName]) { + dependedBy[node.packageName] = new Set() + } + for (const [name, edge] of node.edgesOut) { + if ( + (!onlyOurs || isOurs(name)) && !node.dev + ) { + if (!dependedBy[node.packageName].has(edge.name)) { + dependedBy[node.packageName].add(edge.name) + annotations.push(` ${stripName(node.packageName)}-->${escapeName(edge.name)};`) + if (edge.to) { + iterate(edge.to.target, dependedBy, annotations, onlyOurs) + } + } + } + } +} + +main().then(() => { + process.exit(0) +}).catch(err => { + console.error(err) + process.exit(1) +}) diff --git a/scripts/npm-cli-repos.txt b/scripts/npm-cli-repos.txt new file mode 100644 index 0000000000000..bbbf2e31c4923 --- /dev/null +++ b/scripts/npm-cli-repos.txt @@ -0,0 +1,88 @@ +abbrev-js +arborist +are-we-there-yet +benchmarks +bin-links +cacache +ci-detect +cli +cmd-shim +config +create-oss +dezalgo +disparity-colors +doctornpm +documentation +eslint-config +exec +fs +fs-minipass +gauge +git +hosted-git-info +ignore-walk +infer-owner +inflight +ini +init-package-json +installed-package-contents +libnpmaccess +libnpmfund +libnpmhook +libnpmorg +libnpmpack +libnpmpublish +libnpmsearch +libnpmteam +libnpmversion +lint +make-fetch-happen +map-workspaces +metavuln-calculator +minipass-fetch +move-file +mute-stream +name-from-folder +nock-registry +node-gyp +node-semver +node-tar +node-which +nopt +normalize-package-data +npm-audit-report +npm-birthday +npm-bundled +npm-install-checks +npm-install-script +npm-normalize-package-bin +npm-package-arg +npm-packlist +npm-profile +npm-registry-fetch +npm-user-validate +npmlog +package-json +pacote +parse-conflict-json +proc-log +proggy +promise-spawn +promzard +read +read-cmd-shim +read-package-json +read-package-json-fast +readdir-scoped-modules +rfcs +run-script +ssri +statusboard +stringify-package +template-oss +treeverse +unique-filename +unique-slug +validate-npm-package-name +wrappy +write-file-atomic From 3f7fe17d1ea743b3ce1f27b9156e9fa0e358a7df Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 8 Apr 2022 08:21:29 -0700 Subject: [PATCH 023/406] fix: skip update notifier file if not requested --- lib/utils/update-notifier.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/utils/update-notifier.js b/lib/utils/update-notifier.js index dde0202b76fe2..75e944407ffbd 100644 --- a/lib/utils/update-notifier.js +++ b/lib/utils/update-notifier.js @@ -11,6 +11,8 @@ const stat = promisify(require('fs').stat) const writeFile = promisify(require('fs').writeFile) const { resolve } = require('path') +const SKIP = Symbol('SKIP') + const isGlobalNpmUpdate = npm => { return npm.flatOptions.global && ['install', 'update'].includes(npm.command) && @@ -38,7 +40,7 @@ const updateNotifier = async (npm, spec = 'latest') => { if (!npm.config.get('update-notifier') || isGlobalNpmUpdate(npm) || ciDetect()) { - return null + return SKIP } // if we're on a prerelease train, then updates are coming fast @@ -118,6 +120,12 @@ const updateNotifier = async (npm, spec = 'latest') => { // only update the notification timeout if we actually finished checking module.exports = async npm => { const notification = await updateNotifier(npm) + + // dont write the file if we skipped checking altogether + if (notification === SKIP) { + return null + } + // intentional. do not await this. it's a best-effort update. if this // fails, it's ok. might be using /dev/null as the cache or something weird // like that. From 672fce84b25ecbe58d311acfae6c43e5ca2d778d Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 8 Apr 2022 08:24:56 -0700 Subject: [PATCH 024/406] chore: refactor smoke-tests --- .eslintrc.local.json | 1 - node_modules/.gitignore | 1 + package-lock.json | 45 ++- package.json | 4 +- scripts/resetdeps.sh | 1 + smoke-tests/.eslintrc.js | 15 + smoke-tests/.gitignore | 21 ++ smoke-tests/package.json | 49 +++ smoke-tests/server.js | 282 ------------------ .../tap-snapshots/test}/index.js.test.cjs | 70 ++--- .../{content => test/fixtures}/abbrev.json | 0 .../fixtures}/abbrev.min.json | 0 .../fixtures}/abbrev/-/abbrev-1.0.4.tgz | Bin .../fixtures}/abbrev/-/abbrev-1.1.1.tgz | Bin .../fixtures}/promise-all-reject-late.json | 0 .../promise-all-reject-late.min.json | 0 .../-/promise-all-reject-late-1.0.1.tgz | Bin smoke-tests/test/fixtures/server.js | 49 +++ smoke-tests/{ => test}/index.js | 249 ++++++++-------- 19 files changed, 344 insertions(+), 443 deletions(-) create mode 100644 smoke-tests/.eslintrc.js create mode 100644 smoke-tests/.gitignore create mode 100644 smoke-tests/package.json delete mode 100644 smoke-tests/server.js rename {tap-snapshots/smoke-tests => smoke-tests/tap-snapshots/test}/index.js.test.cjs (84%) rename smoke-tests/{content => test/fixtures}/abbrev.json (100%) rename smoke-tests/{content => test/fixtures}/abbrev.min.json (100%) rename smoke-tests/{content => test/fixtures}/abbrev/-/abbrev-1.0.4.tgz (100%) rename smoke-tests/{content => test/fixtures}/abbrev/-/abbrev-1.1.1.tgz (100%) rename smoke-tests/{content => test/fixtures}/promise-all-reject-late.json (100%) rename smoke-tests/{content => test/fixtures}/promise-all-reject-late.min.json (100%) rename smoke-tests/{content => test/fixtures}/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz (100%) create mode 100644 smoke-tests/test/fixtures/server.js rename smoke-tests/{ => test}/index.js (57%) diff --git a/.eslintrc.local.json b/.eslintrc.local.json index 16c85e07d0159..beb4581f41d82 100644 --- a/.eslintrc.local.json +++ b/.eslintrc.local.json @@ -10,7 +10,6 @@ "overrides": [{ "files": [ "scripts/**", - "smoke-tests/**", "bin/**", "test/**" ], diff --git a/node_modules/.gitignore b/node_modules/.gitignore index 508199997cadc..9b34c08077c99 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -351,6 +351,7 @@ readme* /side-channel /simple-concat /simple-get +/smoke-tests /source-map /source-map-support /space-separated-tokens diff --git a/package-lock.json b/package-lock.json index 9222c5f4ebd5c..43cb34ccea27f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,6 +84,7 @@ "license": "Artistic-2.0", "workspaces": [ "docs", + "smoke-tests", "workspaces/*" ], "dependencies": { @@ -5795,7 +5796,8 @@ }, "node_modules/promise-all-reject-late": { "version": "1.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -6282,8 +6284,9 @@ }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "inBundle": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -6447,6 +6450,10 @@ "npm": ">= 3.0.0" } }, + "node_modules/smoke-tests": { + "resolved": "smoke-tests", + "link": true + }, "node_modules/socks": { "version": "2.6.2", "inBundle": true, @@ -9737,6 +9744,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "smoke-tests": { + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/template-oss": "3.3.2", + "minify-registry-metadata": "^2.2.0", + "rimraf": "^3.0.2", + "tap": "^16.0.1", + "which": "^2.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "workspaces/arborist": { "name": "@npmcli/arborist", "version": "5.0.5", @@ -13792,7 +13815,9 @@ } }, "promise-all-reject-late": { - "version": "1.0.1" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==" }, "promise-call-limit": { "version": "1.0.1" @@ -14117,6 +14142,8 @@ }, "rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } @@ -14192,6 +14219,18 @@ "smart-buffer": { "version": "4.2.0" }, + "smoke-tests": { + "version": "file:smoke-tests", + "requires": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/template-oss": "3.3.2", + "minify-registry-metadata": "^2.2.0", + "rimraf": "^3.0.2", + "tap": "^16.0.1", + "which": "^2.0.2" + } + }, "socks": { "version": "2.6.2", "requires": { diff --git a/package.json b/package.json index 277320d11feeb..3989e8e7227fa 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "a package manager for JavaScript", "workspaces": [ "docs", + "smoke-tests", "workspaces/*" ], "files": [ @@ -225,8 +226,7 @@ "lintfix": "npm run lint -- --fix", "lint-all": "npm run lint --if-present --workspaces --include-workspace-root", "prelint": "rimraf test/npm_cache*", - "resetdeps": "bash scripts/resetdeps.sh", - "smoke-tests": "tap smoke-tests/index.js --no-coverage" + "resetdeps": "bash scripts/resetdeps.sh" }, "tap": { "test-env": [ diff --git a/scripts/resetdeps.sh b/scripts/resetdeps.sh index a8527f8591aab..2362c2092a635 100755 --- a/scripts/resetdeps.sh +++ b/scripts/resetdeps.sh @@ -3,6 +3,7 @@ set -e set -x rm -rf node_modules rm -rf docs/node_modules +rm -rf smoke-tests/node_modules rm -rf "workspaces/*/node_modules" git checkout node_modules node . i --ignore-scripts --no-audit --no-fund diff --git a/smoke-tests/.eslintrc.js b/smoke-tests/.eslintrc.js new file mode 100644 index 0000000000000..0e8ad007113cd --- /dev/null +++ b/smoke-tests/.eslintrc.js @@ -0,0 +1,15 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +const { readdirSync: readdir } = require('fs') + +const localConfigs = readdir(__dirname) + .filter((file) => file.startsWith('.eslintrc.local.')) + .map((file) => `./${file}`) + +module.exports = { + root: true, + extends: [ + '@npmcli', + ...localConfigs, + ], +} diff --git a/smoke-tests/.gitignore b/smoke-tests/.gitignore new file mode 100644 index 0000000000000..617e50ca05288 --- /dev/null +++ b/smoke-tests/.gitignore @@ -0,0 +1,21 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +# ignore everything in the root +/* + +# keep these +!/.eslintrc.local.* +!**/.gitignore +!/docs/ +!/tap-snapshots/ +!/test/ +!/map.js +!/scripts/ +!/README* +!/LICENSE* +!/CHANGELOG* +!/.eslintrc.js +!/.gitignore +!/bin/ +!/lib/ +!/package.json diff --git a/smoke-tests/package.json b/smoke-tests/package.json new file mode 100644 index 0000000000000..f8d1ffd0b9de8 --- /dev/null +++ b/smoke-tests/package.json @@ -0,0 +1,49 @@ +{ + "name": "smoke-tests", + "description": "The npm cli smoke tests", + "version": "1.0.0", + "private": true, + "scripts": { + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run lint -- --fix", + "preversion": "npm test", + "postversion": "git push origin --follow-tags", + "snap": "tap", + "test": "tap", + "posttest": "npm run lint" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/cli.git", + "directory": "smoke-tests" + }, + "devDependencies": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/template-oss": "3.3.2", + "minify-registry-metadata": "^2.2.0", + "rimraf": "^3.0.2", + "tap": "^16.0.1", + "which": "^2.0.2" + }, + "author": "GitHub Inc.", + "license": "ISC", + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "3.3.2", + "workspaceRepo": false + }, + "tap": { + "no-coverage": true, + "files": "test/index.js" + }, + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } +} diff --git a/smoke-tests/server.js b/smoke-tests/server.js deleted file mode 100644 index 31ffebb2ad4e7..0000000000000 --- a/smoke-tests/server.js +++ /dev/null @@ -1,282 +0,0 @@ -/* istanbul ignore file */ -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') -const https = require('https') - -const mkdirp = require('mkdirp') -const doProxy = process.env.ARBORIST_TEST_PROXY -const missing = /\/@isaacs(\/|%2[fF])(this-does-not-exist-at-all|testing-missing-tgz\/-\/)/ -const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' -const { gzipSync, unzipSync } = require('zlib') - -let advisoryBulkResponse = null -let failAdvisoryBulk = false -let auditResponse = null -let failAudit = false -const startServer = () => new Promise((res, rej) => { - const server = exports.server = http.createServer((req, res) => { - res.setHeader('connection', 'close') - - if (req.url === '/-/npm/v1/security/advisories/bulk') { - const body = [] - req.on('data', c => body.push(c)) - req.on('end', () => { - res.setHeader('connection', 'close') - if (failAdvisoryBulk) { - res.statusCode = 503 - return res.end('no advisory bulk for you') - } - if (!advisoryBulkResponse) { - if (auditResponse && !failAudit) { - // simulate what the registry does when quick audits are allowed, - // but advisory bulk requests are not - res.statusCode = 405 - return res.end(JSON.stringify({ - code: 'MethodNotAllowedError', - message: 'POST is not allowed', - })) - } else { - res.statusCode = 404 - return res.end('not found') - } - } - if (doProxy && !existsSync(advisoryBulkResponse)) { - // hit the main registry, then fall back to staging for now - // XXX: remove this when bulk advisory endpoint pushed to production! - const opts = { - host: 'registry.npmjs.org', - method: req.method, - path: req.url, - headers: { - ...req.headers, - accept: '*', - host: 'registry.npmjs.org', - connection: 'close', - 'if-none-match': '', - }, - } - const handleUpstream = upstream => { - res.statusCode = upstream.statusCode - if (upstream.statusCode >= 300 || upstream.statusCode < 200) { - console.error('UPSTREAM ERROR', upstream.statusCode) - return upstream.pipe(res) - } - res.setHeader('content-encoding', upstream.headers['content-encoding']) - const file = advisoryBulkResponse - console.error('PROXY', `${req.url} -> ${file} ${upstream.statusCode}`) - mkdirp.sync(dirname(file)) - const data = [] - upstream.on('end', () => { - const out = Buffer.concat(data) - const obj = JSON.parse(unzipSync(out).toString()) - writeFileSync(file, JSON.stringify(obj, 0, 2) + '\n') - res.end(out) - }) - upstream.on('data', c => data.push(c)) - } - return https.request(opts).on('response', upstream => { - if (upstream.statusCode !== 200) { - console.error('ATTEMPTING TO PROXY FROM STAGING') - console.error('NOTE: THIS WILL FAIL WHEN NOT ON VPN!') - opts.host = 'security-microservice-3-west.npm.red' - opts.headers.host = opts.host - opts.path = '/v1/advisories/bulk' - https.request(opts) - .on('response', upstream => handleUpstream(upstream)) - .end(Buffer.concat(body)) - } else { - handleUpstream(upstream) - } - }).end(Buffer.concat(body)) - } else { - res.setHeader('content-encoding', 'gzip') - res.end(gzipSync(readFileSync(advisoryBulkResponse))) - } - }) - return - } else if (req.url === '/-/npm/v1/security/audits/quick') { - const body = [] - req.on('data', c => body.push(c)) - req.on('end', () => { - res.setHeader('connection', 'close') - if (failAudit) { - res.statusCode = 503 - return res.end('no audit for you') - } - if (!auditResponse) { - res.statusCode = 404 - return res.end('not found') - } - if (doProxy && !existsSync(auditResponse)) { - return https.request({ - host: 'registry.npmjs.org', - method: req.method, - path: req.url, - headers: { - ...req.headers, - accept: '*', - host: 'registry.npmjs.org', - connection: 'close', - 'if-none-match': '', - }, - }).on('response', upstream => { - res.statusCode = upstream.statusCode - if (upstream.statusCode >= 300 || upstream.statusCode < 200) { - console.error('UPSTREAM ERROR', upstream.statusCode) - // don't save if it's not a valid response - return upstream.pipe(res) - } - res.setHeader('content-encoding', upstream.headers['content-encoding']) - const file = auditResponse - console.error('PROXY', `${req.url} -> ${file} ${upstream.statusCode}`) - mkdirp.sync(dirname(file)) - const data = [] - upstream.on('end', () => { - const out = Buffer.concat(data) - // make it a bit prettier to read later - const obj = JSON.parse(unzipSync(out).toString()) - writeFileSync(file, JSON.stringify(obj, 0, 2) + '\n') - res.end(out) - }) - upstream.on('data', c => data.push(c)) - }).end(Buffer.concat(body)) - } else { - res.setHeader('content-encoding', 'gzip') - res.end(gzipSync(readFileSync(auditResponse))) - } - }) - return - } - - 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' - : existsSync(`${f}.json`) ? '.json' - : existsSync(`${f}/index.json`) ? 'index.json' - : '' - ) - - try { - const body = readFileSync(file) - res.setHeader('content-length', body.length) - res.setHeader('content-type', /\.min\.json$/.test(file) ? corgiDoc - : /\.json$/.test(file) ? 'application/json' - : 'application/octet-stream') - res.end(body) - } catch (er) { - // testing things going missing from the registry somehow - if (missing.test(req.url)) { - res.statusCode = 404 - res.end('{"error": "not found"}') - return - } - - if (doProxy) { - return https.get({ - host: 'registry.npmjs.org', - path: req.url, - headers: { - ...req.headers, - accept: '*', - 'accept-encoding': 'identity', - host: 'registry.npmjs.org', - connection: 'close', - 'if-none-match': '', - }, - }).on('response', upstream => { - const errorStatus = - upstream.statusCode >= 300 || upstream.statusCode < 200 - - if (errorStatus) { - console.error('UPSTREAM ERROR', upstream.statusCode) - } - - const ct = upstream.headers['content-type'] - const isJson = ct.includes('application/json') - const file = isJson ? f + '.json' : f - console.error('PROXY', `${req.url} -> ${file} ${ct}`) - mkdirp.sync(dirname(file)) - const data = [] - res.statusCode = upstream.statusCode - res.setHeader('content-type', ct) - upstream.on('end', () => { - console.error('ENDING', req.url) - const out = Buffer.concat(data) - if (!errorStatus) { - if (isJson) { - const obj = JSON.parse(out.toString()) - writeFileSync(file, JSON.stringify(obj, 0, 2) + '\n') - const mrm = require('minify-registry-metadata') - const minFile = file.replace(/\.json$/, '.min.json') - writeFileSync(minFile, JSON.stringify(mrm(obj), 0, 2) + '\n') - console.error('WROTE JSONS', [file, minFile]) - } else { - writeFileSync(file, out) - } - } - res.end(out) - }) - upstream.on('data', c => data.push(c)) - }).end() - } - - res.statusCode = er.code === 'ENOENT' ? 404 : 500 - if (res.method === 'GET') { - console.error(er) - } - res.setHeader('content-type', 'text/plain') - res.end(er.stack) - } - }) - server.listen(PORT, res) -}) - -exports.auditResponse = value => { - if (auditResponse && auditResponse !== value) { - throw new Error('setting audit response, but already set\n' + - '(did you forget to call the returned function on teardown?)') - } - auditResponse = value - return () => auditResponse = null -} -exports.failAudit = () => { - failAudit = true - return () => failAudit = false -} - -exports.advisoryBulkResponse = value => { - if (advisoryBulkResponse && advisoryBulkResponse !== value) { - throw new Error('setting advisory bulk response, but already set\n' + - '(did you forget to call the returned function on teardown?)') - } - advisoryBulkResponse = value - return () => advisoryBulkResponse = null -} -exports.failAdvisoryBulk = () => { - failAdvisoryBulk = true - return () => failAdvisoryBulk = false -} - -exports.registry = `http://localhost:${PORT}/` - -exports.start = startServer -exports.stop = () => exports.server.close() - -if (require.main === module) { - startServer().then(() => { - console.log(`Mock registry live at: - ${exports.registry} -Press ^D to close gracefully.`) - }) - process.openStdin() - process.stdin.on('end', () => exports.stop()) -} diff --git a/tap-snapshots/smoke-tests/index.js.test.cjs b/smoke-tests/tap-snapshots/test/index.js.test.cjs similarity index 84% rename from tap-snapshots/smoke-tests/index.js.test.cjs rename to smoke-tests/tap-snapshots/test/index.js.test.cjs index 5fa3977a8ab65..486849d6cbf54 100644 --- a/tap-snapshots/smoke-tests/index.js.test.cjs +++ b/smoke-tests/tap-snapshots/test/index.js.test.cjs @@ -5,7 +5,7 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`smoke-tests/index.js TAP npm (no args) > should have expected no args output 1`] = ` +exports[`test/index.js TAP npm (no args) > should have expected no args output 1`] = ` npm Usage: @@ -32,7 +32,7 @@ All commands: uninstall, unpublish, unstar, update, version, view, whoami Specify configs in the ini-formatted file: - {CWD}/smoke-tests/tap-testdir-index/.npmrc + {CWD}/smoke-tests/test/tap-testdir-index/.npmrc or on the command line via: npm --key=value More configuration info: npm help config @@ -42,7 +42,7 @@ npm {CWD} ` -exports[`smoke-tests/index.js TAP npm ci > should throw mismatch deps in lock file error 1`] = ` +exports[`test/index.js TAP npm ci > should throw mismatch deps in lock file error 1`] = ` npm ERR! \`npm ci\` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with \`npm install\` before continuing. npm ERR! npm ERR! Invalid: lock file's abbrev@1.0.4 does not satisfy abbrev@1.1.1 @@ -53,7 +53,7 @@ npm ERR! A complete log of this run can be found in: ` -exports[`smoke-tests/index.js TAP npm diff > should have expected diff output 1`] = ` +exports[`test/index.js TAP npm diff > should have expected diff output 1`] = ` diff --git a/package.json b/package.json index v1.0.4..v1.1.1 100644 --- a/package.json @@ -308,14 +308,14 @@ index v1.0.4..v1.1.1 ` -exports[`smoke-tests/index.js TAP npm explain > should have expected explain output 1`] = ` +exports[`test/index.js TAP npm explain > should have expected explain output 1`] = ` abbrev@1.0.4 node_modules/abbrev abbrev@"^1.0.4" from the root project ` -exports[`smoke-tests/index.js TAP npm fund > should have expected fund output 1`] = ` +exports[`test/index.js TAP npm fund > should have expected fund output 1`] = ` project@1.0.0 \`-- https://github.com/sponsors/isaacs \`-- promise-all-reject-late@1.0.1 @@ -323,8 +323,8 @@ project@1.0.0 ` -exports[`smoke-tests/index.js TAP npm init > should have successful npm init result 1`] = ` -Wrote to {CWD}/smoke-tests/tap-testdir-index/project/package.json: +exports[`test/index.js TAP npm init > should have successful npm init result 1`] = ` +Wrote to {CWD}/smoke-tests/test/tap-testdir-index/project/package.json: { "name": "project", @@ -343,7 +343,7 @@ Wrote to {CWD}/smoke-tests/tap-testdir-index/project/package.json: ` -exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added lockfile result 1`] = ` +exports[`test/index.js TAP npm install dev dep > should have expected dev dep added lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -393,7 +393,7 @@ exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev ` -exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added package.json result 1`] = ` +exports[`test/index.js TAP npm install dev dep > should have expected dev dep added package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -415,7 +415,7 @@ exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev ` -exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev dep added reify output 1`] = ` +exports[`test/index.js TAP npm install dev dep > should have expected dev dep added reify output 1`] = ` added 1 package @@ -424,13 +424,13 @@ added 1 package ` -exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expected install reify output 1`] = ` +exports[`test/index.js TAP npm install prodDep@version > should have expected install reify output 1`] = ` added 1 package ` -exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expected lockfile result 1`] = ` +exports[`test/index.js TAP npm install prodDep@version > should have expected lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -462,7 +462,7 @@ exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expe ` -exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expected package.json result 1`] = ` +exports[`test/index.js TAP npm install prodDep@version > should have expected package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -481,21 +481,21 @@ exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expe ` -exports[`smoke-tests/index.js TAP npm ls > should have expected ls output 1`] = ` -project@1.0.0 {CWD}/smoke-tests/tap-testdir-index/project +exports[`test/index.js TAP npm ls > should have expected ls output 1`] = ` +project@1.0.0 {CWD}/smoke-tests/test/tap-testdir-index/project +-- abbrev@1.0.4 \`-- promise-all-reject-late@1.0.1 ` -exports[`smoke-tests/index.js TAP npm outdated > should have expected outdated output 1`] = ` +exports[`test/index.js TAP npm outdated > should have expected outdated output 1`] = ` Package Current Wanted Latest Location Depended by abbrev 1.0.4 1.1.1 1.1.1 node_modules/abbrev project ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg delete modified package.json result 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected npm pkg delete modified package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -515,7 +515,7 @@ exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg delete ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg set modified package.json result 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected npm pkg set modified package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -540,20 +540,20 @@ exports[`smoke-tests/index.js TAP npm pkg > should have expected npm pkg set mod ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected pkg delete output 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected pkg delete output 1`] = ` ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected pkg get output 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected pkg get output 1`] = ` "ISC" ` -exports[`smoke-tests/index.js TAP npm pkg > should have expected pkg set output 1`] = ` +exports[`test/index.js TAP npm pkg > should have expected pkg set output 1`] = ` ` -exports[`smoke-tests/index.js TAP npm pkg > should print package.json contents 1`] = ` +exports[`test/index.js TAP npm pkg > should print package.json contents 1`] = ` { "name": "project", "version": "1.0.0", @@ -578,12 +578,12 @@ exports[`smoke-tests/index.js TAP npm pkg > should print package.json contents 1 ` -exports[`smoke-tests/index.js TAP npm prefix > should have expected prefix output 1`] = ` -{CWD}/smoke-tests/tap-testdir-index/project +exports[`test/index.js TAP npm prefix > should have expected prefix output 1`] = ` +{CWD}/smoke-tests/test/tap-testdir-index/project ` -exports[`smoke-tests/index.js TAP npm run-script > should have expected run-script output 1`] = ` +exports[`test/index.js TAP npm run-script > should have expected run-script output 1`] = ` > project@1.0.0 hello > echo Hello @@ -592,7 +592,7 @@ Hello ` -exports[`smoke-tests/index.js TAP npm set-script > should have expected script added package.json result 1`] = ` +exports[`test/index.js TAP npm set-script > should have expected script added package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -615,11 +615,11 @@ exports[`smoke-tests/index.js TAP npm set-script > should have expected script a ` -exports[`smoke-tests/index.js TAP npm set-script > should have expected set-script output 1`] = ` +exports[`test/index.js TAP npm set-script > should have expected set-script output 1`] = ` ` -exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall lockfile result 1`] = ` +exports[`test/index.js TAP npm uninstall > should have expected uninstall lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -651,7 +651,7 @@ exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall ` -exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall package.json result 1`] = ` +exports[`test/index.js TAP npm uninstall > should have expected uninstall package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -671,13 +671,13 @@ exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall ` -exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall reify output 1`] = ` +exports[`test/index.js TAP npm uninstall > should have expected uninstall reify output 1`] = ` removed 1 package ` -exports[`smoke-tests/index.js TAP npm update dep > should have expected update lockfile result 1`] = ` +exports[`test/index.js TAP npm update dep > should have expected update lockfile result 1`] = ` { "name": "project", "version": "1.0.0", @@ -727,7 +727,7 @@ exports[`smoke-tests/index.js TAP npm update dep > should have expected update l ` -exports[`smoke-tests/index.js TAP npm update dep > should have expected update package.json result 1`] = ` +exports[`test/index.js TAP npm update dep > should have expected update package.json result 1`] = ` { "name": "project", "version": "1.0.0", @@ -750,7 +750,7 @@ exports[`smoke-tests/index.js TAP npm update dep > should have expected update p ` -exports[`smoke-tests/index.js TAP npm update dep > should have expected update reify output 1`] = ` +exports[`test/index.js TAP npm update dep > should have expected update reify output 1`] = ` changed 1 package @@ -759,7 +759,7 @@ changed 1 package ` -exports[`smoke-tests/index.js TAP npm view > should have expected view output 1`] = ` +exports[`test/index.js TAP npm view > should have expected view output 1`] = ` abbrev@1.0.4 | MIT | deps: none | versions: 8 Like ruby's abbrev module, but in js diff --git a/smoke-tests/content/abbrev.json b/smoke-tests/test/fixtures/abbrev.json similarity index 100% rename from smoke-tests/content/abbrev.json rename to smoke-tests/test/fixtures/abbrev.json diff --git a/smoke-tests/content/abbrev.min.json b/smoke-tests/test/fixtures/abbrev.min.json similarity index 100% rename from smoke-tests/content/abbrev.min.json rename to smoke-tests/test/fixtures/abbrev.min.json diff --git a/smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz similarity index 100% rename from smoke-tests/content/abbrev/-/abbrev-1.0.4.tgz rename to smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz diff --git a/smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz similarity index 100% rename from smoke-tests/content/abbrev/-/abbrev-1.1.1.tgz rename to smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz diff --git a/smoke-tests/content/promise-all-reject-late.json b/smoke-tests/test/fixtures/promise-all-reject-late.json similarity index 100% rename from smoke-tests/content/promise-all-reject-late.json rename to smoke-tests/test/fixtures/promise-all-reject-late.json diff --git a/smoke-tests/content/promise-all-reject-late.min.json b/smoke-tests/test/fixtures/promise-all-reject-late.min.json similarity index 100% rename from smoke-tests/content/promise-all-reject-late.min.json rename to smoke-tests/test/fixtures/promise-all-reject-late.min.json diff --git a/smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz b/smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz similarity index 100% rename from smoke-tests/content/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz rename to smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz diff --git a/smoke-tests/test/fixtures/server.js b/smoke-tests/test/fixtures/server.js new file mode 100644 index 0000000000000..b1056a2219066 --- /dev/null +++ b/smoke-tests/test/fixtures/server.js @@ -0,0 +1,49 @@ +const { join, basename } = require('path') +const { existsSync, readFileSync } = require('fs') +const http = require('http') +const PORT = 12345 + (+process.env.TAP_CHILD_ID || 0) + +let server = null +const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' + +const start = () => new Promise((resolve) => { + server = http.createServer((req, res) => { + res.setHeader('connection', 'close') + + const f = join(__dirname, 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.statusCode = 404 + res.setHeader('npm-notice', req.headers['user-agent']) + 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' + : existsSync(`${f}.json`) ? '.json' + : existsSync(`${f}/index.json`) ? 'index.json' + : '' + ) + + try { + const body = readFileSync(file) + res.setHeader('content-length', body.length) + res.setHeader('content-type', /\.min\.json$/.test(file) ? corgiDoc + : /\.json$/.test(file) ? 'application/json' + : 'application/octet-stream') + res.end(body) + } catch { + res.statusCode = 500 + res.setHeader('content-type', 'text/plain') + res.end('bad') + } + }).listen(PORT, resolve) +}) + +module.exports = { + start, + stop: () => server.close(), + registry: `http://localhost:${PORT}/`, +} diff --git a/smoke-tests/index.js b/smoke-tests/test/index.js similarity index 57% rename from smoke-tests/index.js rename to smoke-tests/test/index.js index 464187da0e269..bbb833a5728c8 100644 --- a/smoke-tests/index.js +++ b/smoke-tests/test/index.js @@ -1,21 +1,47 @@ -const fs = require('fs') -const { promisify } = require('util') -const execAsync = promisify(require('child_process').exec) -const { join, resolve } = require('path') +const { readFileSync, realpathSync, mkdirSync, existsSync, writeFileSync } = require('fs') +const spawn = require('@npmcli/promise-spawn') +const { join, resolve, sep } = require('path') const t = require('tap') -const rimraf = promisify(require('rimraf')) +const rimraf = require('rimraf') +const which = require('which').sync +const { start, stop, registry } = require('./fixtures/server.js') +const { SMOKE_PUBLISH_NPM, CI, PATH } = process.env +const log = CI ? console.error : () => {} + +const cwd = resolve(__dirname, '..', '..') +const npmCli = join('bin', 'npm-cli.js') +const execArgv = SMOKE_PUBLISH_NPM ? ['npm'] : [process.execPath, join(cwd, npmCli)] +const npmDir = SMOKE_PUBLISH_NPM ? realpathSync(which('npm')).replace(sep + npmCli, '') : cwd + +// setup server +t.before(start) +t.teardown(stop) +// update notifier should never be written +t.afterEach((t) => { + const updateExists = existsSync(join(cacheLocation, '_update-notifier-last-checked')) + t.equal(updateExists, false) +}) + +const readFile = filename => readFileSync(resolve(localPrefix, filename), 'utf-8') const normalizePath = path => path.replace(/[A-Z]:/, '').replace(/\\/g, '/') -const cwd = normalizePath(process.cwd()) + t.cleanSnapshot = s => s - .split(cwd) + // sometimes we print normalized paths in snapshots regardless of + // platform so replace those first + .split(normalizePath(npmDir)) + .join('{CWD}') + .split(normalizePath(cwd)) .join('{CWD}') .split(registry) .join('https://registry.npmjs.org/') .split(normalizePath(process.execPath)) .join('node') - .split(process.cwd()) + // then replace platform style paths + .split(npmDir) + .join('{CWD}') + .split(cwd) .join('{CWD}') .replace(/\\+/g, '/') .replace(/\r\n/g, '\n') @@ -23,11 +49,6 @@ t.cleanSnapshot = s => .replace(/^npm@.* /gm, 'npm ') .replace(/^.*debug-[0-9]+.log$/gm, '') -// setup server -const { start, stop, registry } = require('./server.js') -t.before(start) -t.teardown(stop) - // setup fixtures const path = t.testdir({ '.npmrc': '', @@ -37,30 +58,49 @@ const path = t.testdir({ }) const localPrefix = resolve(path, 'project') const userconfigLocation = resolve(path, '.npmrc') -const npmLocation = resolve(__dirname, '../bin/npm-cli.js') const cacheLocation = resolve(path, 'cache') const binLocation = resolve(path, 'bin') -const env = { - HOME: path, - PATH: `${process.env.PATH}:${binLocation}`, -} -const npmOpts = [ - `--registry=${registry}`, - `--cache="${cacheLocation}"`, - `--userconfig="${userconfigLocation}"`, - '--no-audit', - '--no-update-notifier', - '--loglevel=silly', -].join(' ') -const npmBin = `"${process.execPath}" "${npmLocation}" ${npmOpts}` -const exec = async cmd => { - const res = await execAsync(cmd, { cwd: localPrefix, env }) - if (res.stderr) { - console.error(res.stderr) + +const exec = async (...args) => { + const cmd = [] + const opts = [ + `--registry=${registry}`, + `--cache=${cacheLocation}`, + `--userconfig=${userconfigLocation}`, + '--no-audit', + '--no-update-notifier', + '--loglevel=silly', + ] + for (const arg of args) { + if (arg.startsWith('--')) { + opts.push(arg) + } else { + cmd.push(arg) + } + } + + // XXX: not sure why outdated fails with no-workspaces but works without it + if (!opts.includes('--workspaces') && cmd[0] !== 'outdated') { + // This is required so we dont detect any workspace roots above the testdir + opts.push('--no-workspaces') } - return String(res.stdout) + + const spawnArgs = [execArgv[0], [...execArgv.slice(1), ...cmd, ...opts]] + log([spawnArgs[0], ...spawnArgs[1]].join(' ')) + + const res = await spawn(...spawnArgs, { + cwd: localPrefix, + env: { + HOME: path, + PATH: `${PATH}:${binLocation}`, + }, + stdioString: true, + encoding: 'utf-8', + }) + + log(res.stderr) + return res.stdout } -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 @@ -71,35 +111,31 @@ t.test('npm install sends correct user-agent', async t => { name: 'smoke-test-workspaces', workspaces: ['packages/*'], }) - fs.writeFileSync(pkgPath, pkgContent, { encoding: 'utf8' }) + writeFileSync(pkgPath, pkgContent, { encoding: 'utf8' }) const wsRoot = join(localPrefix, 'packages') - fs.mkdirSync(wsRoot) + mkdirSync(wsRoot) const wsPath = join(wsRoot, 'foo') - fs.mkdirSync(wsPath) + 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}/*`) - }) + writeFileSync(wsPkgPath, wsContent, { encoding: 'utf8' }) + t.teardown(() => rimraf.sync(`${localPrefix}/*`)) - const cmd = `${npmBin} install fail_reflect_user_agent` await t.rejects( - exec(cmd), + exec('install', 'fail_reflect_user_agent'), { stderr: /workspaces\/false/, }, 'workspaces/false is present in output' ) - const wsCmd = `${npmBin} install fail_reflect_user_agent --workspaces` await t.rejects( - exec(wsCmd), + exec('install', 'fail_reflect_user_agent', '--workspaces'), { stderr: /workspaces\/true/, }, @@ -108,29 +144,34 @@ t.test('npm install sends correct user-agent', async t => { }) t.test('npm init', async t => { - const cmd = `${npmBin} init -y` - const cmdRes = await exec(cmd) + const cmdRes = await exec('init', '-y') t.matchSnapshot(cmdRes, 'should have successful npm init result') - const pkg = JSON.parse(fs.readFileSync(resolve(localPrefix, 'package.json'))) + const pkg = JSON.parse(readFileSync(resolve(localPrefix, 'package.json'))) t.equal(pkg.name, 'project', 'should have expected generated name') t.equal(pkg.version, '1.0.0', 'should have expected generated version') }) +t.test('npm --version', async t => { + const v = await exec('--version') + + if (SMOKE_PUBLISH_NPM) { + t.match(v.trim(), /-[0-9a-f]{40}\.\d$/, 'must have a git version') + } else { + t.skip('not checking version') + } +}) + t.test('npm (no args)', async t => { - const cmd = `"${process.execPath}" "${npmLocation}" --no-audit --no-update-notifier` - const cmdRes = await execAsync(cmd, { cwd: localPrefix, env }).catch(err => { - t.equal(err.code, 1, 'should exit with error code') - return err - }) + const err = await exec('--loglevel=notice').catch(e => e) - t.equal(cmdRes.stderr, '', 'should have no stderr output') - t.matchSnapshot(String(cmdRes.stdout), 'should have expected no args output') + t.equal(err.code, 1, 'should exit with error code') + t.equal(err.stderr, '', 'should have no stderr output') + t.matchSnapshot(err.stdout, 'should have expected no args output') }) t.test('npm install prodDep@version', async t => { - const cmd = `${npmBin} install abbrev@1.0.4` - const cmdRes = await exec(cmd) + const cmdRes = await exec('install', 'abbrev@1.0.4') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected install reify output') t.matchSnapshot(readFile('package.json'), 'should have expected package.json result') @@ -138,8 +179,7 @@ t.test('npm install prodDep@version', async t => { }) t.test('npm install dev dep', async t => { - const cmd = `${npmBin} install -D promise-all-reject-late` - const cmdRes = await exec(cmd) + const cmdRes = await exec('install', 'promise-all-reject-late', '-D') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected dev dep added reify output') t.matchSnapshot( @@ -153,47 +193,39 @@ t.test('npm install dev dep', async t => { }) t.test('npm ls', async t => { - const cmd = `${npmBin} ls` - const cmdRes = await exec(cmd) + const cmdRes = await exec('ls') t.matchSnapshot(cmdRes, 'should have expected ls output') }) t.test('npm fund', async t => { - const cmd = `${npmBin} fund` - const cmdRes = await exec(cmd) + const cmdRes = await exec('fund') t.matchSnapshot(cmdRes, 'should have expected fund output') }) t.test('npm explain', async t => { - const cmd = `${npmBin} explain abbrev` - const cmdRes = await exec(cmd) + const cmdRes = await exec('explain', 'abbrev') t.matchSnapshot(cmdRes, 'should have expected explain output') }) t.test('npm diff', async t => { - const cmd = `${npmBin} diff --diff=abbrev@1.0.4 --diff=abbrev@1.1.1` - const cmdRes = await exec(cmd) + const cmdRes = await exec('diff', '--diff=abbrev@1.0.4', '--diff=abbrev@1.1.1') t.matchSnapshot(cmdRes, 'should have expected diff output') }) t.test('npm outdated', async t => { - const cmd = `${npmBin} outdated` - const cmdRes = await exec(cmd).catch(err => { - t.equal(err.code, 1, 'should exit with error code') - return err - }) + const err = await exec('outdated').catch(e => e) - t.not(cmdRes.stderr, '', 'should have stderr output') - t.matchSnapshot(String(cmdRes.stdout), 'should have expected outdated output') + t.equal(err.code, 1, 'should exit with error code') + t.not(err.stderr, '', 'should have stderr output') + t.matchSnapshot(err.stdout, 'should have expected outdated output') }) t.test('npm set-script', async t => { - const cmd = `${npmBin} set-script "hello" "echo Hello"` - const cmdRes = await exec(cmd) + const cmdRes = await exec('set-script', 'hello', 'echo Hello') t.matchSnapshot(cmdRes, 'should have expected set-script output') t.matchSnapshot( @@ -203,29 +235,25 @@ t.test('npm set-script', async t => { }) t.test('npm run-script', async t => { - const cmd = `${npmBin} run hello` - const cmdRes = await exec(cmd) + const cmdRes = await exec('run', 'hello') t.matchSnapshot(cmdRes, 'should have expected run-script output') }) t.test('npm prefix', async t => { - const cmd = `${npmBin} prefix` - const cmdRes = await exec(cmd) + const cmdRes = await exec('prefix') t.matchSnapshot(cmdRes, 'should have expected prefix output') }) t.test('npm view', async t => { - const cmd = `${npmBin} view abbrev@1.0.4` - const cmdRes = await exec(cmd) + const cmdRes = await exec('view', 'abbrev@1.0.4') t.matchSnapshot(cmdRes, 'should have expected view output') }) t.test('npm update dep', async t => { - const cmd = `${npmBin} update abbrev` - const cmdRes = await exec(cmd) + const cmdRes = await exec('update', 'abbrev') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected update reify output') t.matchSnapshot(readFile('package.json'), 'should have expected update package.json result') @@ -233,8 +261,7 @@ t.test('npm update dep', async t => { }) t.test('npm uninstall', async t => { - const cmd = `${npmBin} uninstall promise-all-reject-late` - const cmdRes = await exec(cmd) + const cmdRes = await exec('uninstall', 'promise-all-reject-late') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected uninstall reify output') t.matchSnapshot(readFile('package.json'), 'should have expected uninstall package.json result') @@ -242,12 +269,10 @@ t.test('npm uninstall', async t => { }) t.test('npm pkg', async t => { - let cmd = `${npmBin} pkg get license` - let cmdRes = await exec(cmd) + let cmdRes = await exec('pkg', 'get', 'license') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg get output') - cmd = `${npmBin} pkg set tap[test-env][0]=LC_ALL=sk` - cmdRes = await exec(cmd) + cmdRes = await exec('pkg', 'set', 'tap[test-env][0]=LC_ALL=sk') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg set output') t.matchSnapshot( @@ -255,12 +280,10 @@ t.test('npm pkg', async t => { 'should have expected npm pkg set modified package.json result' ) - cmd = `${npmBin} pkg get` - cmdRes = await exec(cmd) + cmdRes = await exec('pkg', 'get') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should print package.json contents') - cmd = `${npmBin} pkg delete tap` - cmdRes = await exec(cmd) + cmdRes = await exec('pkg', 'delete', 'tap') t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg delete output') t.matchSnapshot( @@ -271,12 +294,11 @@ t.test('npm pkg', async t => { t.test('npm update --no-save --no-package-lock', async t => { // setup, manually reset dep value - await exec(`${npmBin} pkg set "dependencies.abbrev==1.0.4"`) - await exec(`${npmBin} install`) - await exec(`${npmBin} pkg set "dependencies.abbrev=^1.0.4"`) + await exec('pkg', 'set', 'dependencies.abbrev==1.0.4') + await exec(`install`) + await exec('pkg', 'set', 'dependencies.abbrev=^1.0.4') - const cmd = `${npmBin} update --no-save --no-package-lock` - await exec(cmd) + await exec('update', '--no-save', '--no-package-lock') t.equal( JSON.parse(readFile('package.json')).dependencies.abbrev, @@ -291,8 +313,7 @@ t.test('npm update --no-save --no-package-lock', async t => { }) t.test('npm update --no-save', async t => { - const cmd = `${npmBin} update --no-save` - await exec(cmd) + await exec('update', '--no-save') t.equal( JSON.parse(readFile('package.json')).dependencies.abbrev, @@ -307,8 +328,7 @@ t.test('npm update --no-save', async t => { }) t.test('npm update --save', async t => { - const cmd = `${npmBin} update --save` - await exec(cmd) + await exec('update', '--save') t.equal( JSON.parse(readFile('package.json')).dependencies.abbrev, @@ -323,8 +343,8 @@ t.test('npm update --save', async t => { }) t.test('npm ci', async t => { - await exec(`${npmBin} uninstall abbrev`) - await exec(`${npmBin} install abbrev@1.0.4 --save-exact`) + await exec('uninstall', 'abbrev') + await exec('install', 'abbrev@1.0.4', '--save-exact') t.equal( JSON.parse(readFile('package-lock.json')).packages['node_modules/abbrev'].version, @@ -332,20 +352,9 @@ t.test('npm ci', async t => { 'should have stored exact installed version' ) - await exec(`${npmBin} pkg set "dependencies.abbrev=^1.1.1"`) - - try { - const npmOpts = [ - `--registry=${registry}`, - `--cache="${cacheLocation}"`, - `--userconfig="${userconfigLocation}"`, - '--no-audit', - '--no-update-notifier', - '--loglevel=error', - ].join(' ') - const npmBin = `"${process.execPath}" "${npmLocation}" ${npmOpts}` - await exec(`${npmBin} ci`) - } catch (err) { - t.matchSnapshot(err.stderr, 'should throw mismatch deps in lock file error') - } + await exec('pkg', 'set', 'dependencies.abbrev=^1.1.1') + + const err = await exec('ci', '--loglevel=error').catch(e => e) + t.equal(err.code, 1) + t.matchSnapshot(err.stderr, 'should throw mismatch deps in lock file error') }) From 6ac1e44e8129f2cfb5970f6c407bc6899c854a9b Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 8 Apr 2022 08:26:21 -0700 Subject: [PATCH 025/406] chore: add test-all to makefile --- Makefile | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index f863dcdc87fc5..e280ecc9abf1e 100644 --- a/Makefile +++ b/Makefile @@ -78,17 +78,14 @@ docs/content/commands/npm-%.md: docs/bin/config-doc-command.js lib/commands/%.js freshdocs: touch lib/utils/config/definitions.js - touch "docs/bin/*.js" + touch docs/bin/*.js make docs -test: deps - node bin/npm-cli.js test - -smoke-tests: deps - node bin/npm-cli.js run smoke-tests +test-all: deps + node bin/npm-cli.js run test-all ls-ok: - node . ls --production >/dev/null + node bin/npm-cli.js ls --production >/dev/null gitclean: git clean -fd @@ -100,11 +97,10 @@ link: uninstall node bin/npm-cli.js link -f --ignore-scripts prune: deps - node bin/npm-cli.js prune --production --no-save --no-audit - @[[ "$(shell git status -s)" != "" ]] && echo "ERR: found unpruned files" && exit 1 || echo "git status is clean" + node bin/npm-cli.js prune --production --no-save --no-audit --no-fund + node scripts/git-dirty.js -publish: gitclean ls-ok link test smoke-tests docs prune - @git push origin :v$(shell node bin/npm-cli.js --no-timing -v) 2>&1 || true +publish: gitclean ls-ok link test-all docs prune git push origin $(BRANCH) &&\ git push origin --tags &&\ node bin/npm-cli.js publish --tag=$(PUBLISHTAG) @@ -112,4 +108,4 @@ publish: gitclean ls-ok link test smoke-tests docs prune release: gitclean ls-ok docs prune @bash scripts/release.sh -.PHONY: all latest install dev link docs clean uninstall test man docsclean release ls-ok deps prune freshdocs +.PHONY: all latest install dev link docs clean uninstall test-all man docsclean release ls-ok deps prune freshdocs From 2d87805bd415dad62f7912f1ce1761e2a492ee98 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 8 Apr 2022 08:26:45 -0700 Subject: [PATCH 026/406] chore: make git dirty check more strict --- scripts/git-dirty.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/git-dirty.js b/scripts/git-dirty.js index 484a4d23e7be2..5730ed9006681 100644 --- a/scripts/git-dirty.js +++ b/scripts/git-dirty.js @@ -1,6 +1,6 @@ #!/usr/bin/env node const { spawnSync } = require('child_process') -const changes = spawnSync('git', ['status', '--porcelain', '-uno']) +const changes = spawnSync('git', ['status', '--porcelain', '-uall']) const stdout = changes.stdout.toString('utf8') const stderr = changes.stderr.toString('utf8') const { status, signal } = changes From 55f2efa76a574cd6c86a43388d4d1544606e2112 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 8 Apr 2022 08:27:38 -0700 Subject: [PATCH 027/406] chore: do less smoke testing on every commit --- .github/workflows/ci.yml | 55 ++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8b6886e39e10..67dcfb4d1d69a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,8 @@ jobs: with: node-version: 16.x cache: npm - - run: node ./bin/npm-cli.js run resetdeps - - run: node ./bin/npm-cli.js run lint + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js run lint check_docs: runs-on: ubuntu-latest @@ -43,40 +43,23 @@ jobs: with: node-version: 16.x cache: npm - - run: node ./bin/npm-cli.js run resetdeps - - run: node ./bin/npm-cli.js run licenses - + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js run licenses + smoke-tests: - strategy: - fail-fast: false - matrix: - node-version: - - 12.x - - 14.x - - 16.x - platform: - - os: ubuntu-latest - shell: bash - - os: macos-latest - shell: bash - - os: windows-latest - shell: cmd - runs-on: ${{ matrix.platform.os }} - defaults: - run: - shell: ${{ matrix.platform.shell }} + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: npm - - run: node ./bin/npm-cli.js run resetdeps - - run: node ./bin/npm-cli.js run smoke-tests --ignore-scripts - - name: git status - if: matrix.platform.os != 'windows-latest' - run: node scripts/git-dirty.js + - uses: actions/checkout@v3 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + cache: npm + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js test -w smoke-tests --ignore-scripts + - name: git status + if: matrix.platform.os != 'windows-latest' + run: node scripts/git-dirty.js test: strategy: @@ -107,8 +90,8 @@ jobs: with: node-version: ${{ matrix.node-version }} cache: npm - - run: node ./bin/npm-cli.js run resetdeps - - run: node ./bin/npm-cli.js run test --ignore-scripts + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js run test --ignore-scripts - name: git status if: matrix.platform.os != 'windows-latest' run: node scripts/git-dirty.js From ac9c2a64a5826cd6bac54a91cdcc6c3455185b1f Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 8 Apr 2022 08:27:54 -0700 Subject: [PATCH 028/406] chore: add release github action --- .github/workflows/release.yml | 118 ++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000000..84c40e7745106 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,118 @@ +name: Release - cli + +on: + workflow_dispatch: + pull_request: + schedule: + # 08:00am UTC everyday: https://crontab.guru/#0_8_*_*_* + # https://dateful.com/convert/utc?t=8am + - cron: "0 8 * * *" + +jobs: + lint-all: + if: | + github.event_name == 'schedule' || + github.event_name == 'workflow_dispatch' || + startsWith(github.head_ref, 'release/') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + cache: npm + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js run lint-all --ignore-scripts + + smoke-publish: + if: | + github.event_name == 'schedule' || + github.event_name == 'workflow_dispatch' || + startsWith(github.head_ref, 'release/') + strategy: + fail-fast: false + matrix: + node-version: + - 12.13.0 + - 12.x + - 14.15.0 + - 14.x + - 16.0.0 + - 16.x + platform: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + # XXX: this should be possible in windows also + # but resetdeps cant be a bash script + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - uses: actions/checkout@v3 + - name: Setup git user + run: | + git config --global user.email "ops+npm-cli@npmjs.com" + git config --global user.name "npm cli ops bot" + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + cache: npm + - name: Pack + run: | + NPM_VERSION="$(node bin/npm-cli.js --version)-$GITHUB_SHA.0" + node bin/npm-cli.js version $NPM_VERSION --ignore-scripts + node bin/npm-cli.js run resetdeps + git clean -fd + node bin/npm-cli.js ls --production >/dev/null + node bin/npm-cli.js prune --production --no-save --no-audit --no-fund + node scripts/git-dirty.js + node bin/npm-cli.js pack --pack-destination=$RUNNER_TEMP + node bin/npm-cli.js install -g $RUNNER_TEMP/npm-$NPM_VERSION.tgz + node bin/npm-cli.js install -w smoke-tests --ignore-scripts --no-audit --no-fund + rm -rf {lib,bin,index.js} + SMOKE_PUBLISH_NPM=1 npm test -w smoke-tests --ignore-scripts + + test-all: + if: | + github.event_name == 'schedule' || + github.event_name == 'workflow_dispatch' || + startsWith(github.head_ref, 'release/') + strategy: + fail-fast: false + matrix: + node-version: + - 12.13.0 + - 12.x + - 14.15.0 + - 14.x + - 16.0.0 + - 16.x + platform: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + - os: windows-latest + shell: cmd + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: npm + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js link -f --ignore-scripts + - run: node bin/npm-cli.js run test-all --ignore-scripts + - name: git status + if: matrix.platform.os != 'windows-latest' + run: node scripts/git-dirty.js From b5701cc2ad82fbc7a8bde47756afa874b916871a Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 14:24:17 -0700 Subject: [PATCH 029/406] chore: consolidate and refactor benchmark workflows (#4715) --- .github/workflows/benchmark-comment.yml | 87 -------------------- .github/workflows/benchmark.yml | 101 +++++++++++++++--------- 2 files changed, 62 insertions(+), 126 deletions(-) delete mode 100644 .github/workflows/benchmark-comment.yml diff --git a/.github/workflows/benchmark-comment.yml b/.github/workflows/benchmark-comment.yml deleted file mode 100644 index 285b2938462a2..0000000000000 --- a/.github/workflows/benchmark-comment.yml +++ /dev/null @@ -1,87 +0,0 @@ ---- -name: Benchmark CLI - Comment - -on: - issue_comment: - types: [created, edited] - -jobs: - comment-handler: - name: Trigger Benchmarks - - runs-on: ubuntu-latest - - steps: - - name: Handle Incoming Comment - env: - DISPATCH_REPO: "benchmarks" - DISPATCH_OWNER: "npm" - EVENT_NAME: ${{ github.event_name }} - OWNER: ${{ github.event.repository.owner.login }} - REPO: ${{ github.event.repository.name }} - ISSUE_NUMBER: ${{ github.event.issue.number }} - COMMENT_NODE_ID: ${{ github.event.comment.node_id }} - COMMENT_ACTIONABLE: ${{ startsWith(github.event.comment.body, 'test this please ✅') }} - AUTH_TOKEN: ${{ secrets.NPM_BENCHMARKS_TOKEN }} - run: | - # Comment Handler - - # Creates an exit early condition if there are errors - # Exit early if `jq` is not present - set -e - jq --version - - # Figure out if comment came from pull-request or issue - IS_PR=$(curl -s https://api.github.com/repos/${OWNER}/${REPO}/issues/${ISSUE_NUMBER} | jq -cr '.pull_request.url') - - if [ "${IS_PR}" != "null" ]; then - echo "Comment from pull/${ISSUE_NUMBER}." - - # It is a pull-request; check comment body for correct phrase - if [ "${COMMENT_ACTIONABLE}" == "true" ]; then - # Fetch pull-request information - PR_DATA=$(curl -s "${IS_PR}") - PR_OWNER=$(echo "${PR_DATA}" | jq '.head.repo.owner.login') - PR_REPO=$(echo "${PR_DATA}" | jq '.head.repo.name') - - # dispatch request for benchmarks - echo "Dispatching request..." - curl \ - -s \ - -X POST https://api.github.com/repos/${DISPATCH_OWNER}/${DISPATCH_REPO}/dispatches \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token ${AUTH_TOKEN}" \ - -d \ - ' - { - "event_type": "'"${EVENT_NAME} ${PR_OWNER}/${PR_REPO}#${ISSUE_NUMBER}"'", - "client_payload": { - "pr_id": "'"${ISSUE_NUMBER}"'", - "repo": "'"${PR_REPO}"'", - "owner": "'"${PR_OWNER}"'" - } - }' - - # Create reaction on comment to confirm dispatch was sent - curl \ - -s \ - -X POST https://api.github.com/graphql \ - -H "Content-Type: application/json" \ - -H "Authorization: token ${AUTH_TOKEN}" \ - -d \ - ' - { - "query": "mutation($inputData:AddReactionInput!) { addReaction(input:$inputData) { reaction { content } } }", - "variables": { - "inputData": { - "subjectId": "'"${COMMENT_NODE_ID}"'", - "content": "ROCKET" - } - } - }' - else - echo "Comment not actionable." - fi - else - echo "Comment not from pull-request." - fi diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index b9da2ddfdbe22..c97619e1e60aa 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -1,52 +1,75 @@ ---- -name: Benchmark Suite +name: Benchmark - CLI on: pull_request: branches: - - "**" + - '*' + issue_comment: + types: + - created + - edited jobs: - build: - name: Trigger Benchmarks - + pull-request: runs-on: ubuntu-latest - steps: - - name: Handle Incoming Pull-Request + - name: Incoming Pull Request + if: | + secrets.NPM_BENCHMARKS_TOKEN && ( + github.event_name == 'pull_request' || + (github.event_name == 'issue_comment' && github.event.issue.pull_request && + startsWith(github.event.comment.body, 'test this please ✅'))) env: - DISPATCH_REPO: "benchmarks" - DISPATCH_OWNER: "npm" - EVENT_NAME: ${{ github.event_name }} - REPO: ${{ github.event.repository.name }} - PR_NUMBER: ${{ github.event.pull_request.number }} - PR_OWNER: ${{ github.event.pull_request.head.repo.owner.login }} - AUTH_TOKEN: ${{ secrets.NPM_BENCHMARKS_TOKEN }} + # gh cli uses these env vars for owner/repo/token + GH_REPO: "npm/benchmarks" + GITHUB_TOKEN: ${{ secrets.NPM_BENCHMARKS_TOKEN }} run: | - # Dispatch Handler - - dispatch_request () { - echo "Dispatching request..." - curl \ - -s \ - -X POST https://api.github.com/repos/${DISPATCH_OWNER}/${DISPATCH_REPO}/dispatches \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token ${AUTH_TOKEN}" \ - -d \ - ' - { - "event_type": "'"${EVENT_NAME} ${PR_OWNER}/${REPO}#${PR_NUMBER}"'", - "client_payload": { - "pr_id": "'"${PR_NUMBER}"'", - "repo": "'"${REPO}"'", - "owner": "'"${PR_OWNER}"'" - } - }' - } + EVENT_NAME="${{ github.event_name }}" + OWNER="${{ github.event.repository.owner.login }}" + REPO="${{ github.event.repository.name }}" - if [ "${AUTH_TOKEN}" != "" ]; then - # Dispatch request for benchmarks - dispatch_request + if [[ "$EVENT_NAME" == "pull_request" ]]; then + PR="${{ github.event.pull_request.number }}" else - echo "NO AUTH - FORK PULL REQUEST" + PR="${{ github.event.issue.number }}" fi + + EVENT="${EVENT_NAME} ${OWNER}/${REPO}#${PR}" + echo '{ + "event_type": "'"$EVENT"'", + "client_payload": { + "pr_id": "'"$PR"'", + "repo": "'"$REPO"'", + "owner": "'"$OWNER"'" + } + }' | gh api repos/{owner}/{repo}/dispatches --input - + + comment: + runs-on: ubuntu-latest + steps: + - name: Incoming Comment + if: | + secrets.NPM_BENCHMARKS_TOKEN && + github.event_name == 'issue_comment' && + github.event.issue.pull_request && + startsWith(github.event.comment.body, 'test this please ✅') + env: + # gh cli uses this env var as the token + GITHUB_TOKEN: ${{ secrets.NPM_BENCHMARKS_TOKEN }} + run: | + COMMENT_NODE_ID="${{ github.event.comment.node_id }}" + QUERY='mutation ($inputData:AddReactionInput!) { + addReaction (input:$inputData) { + reaction { content } + } + }' + echo '{ + "query": "'${QUERY}'", + "variables": { + "inputData": { + "subjectId": "'"${COMMENT_NODE_ID}"'", + "content": "ROCKET" + } + } + }' | gh api graphql --input - + From a4ee396ee63cb1ce0f427906ee6f3d8097fcb64b Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 14:24:51 -0700 Subject: [PATCH 030/406] chore: add release manager script (#4716) --- scripts/changelog.js | 27 ++-- scripts/release-manager.js | 248 +++++++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+), 10 deletions(-) create mode 100644 scripts/release-manager.js diff --git a/scripts/changelog.js b/scripts/changelog.js index 0c50b562defd1..3db16d6cab08c 100644 --- a/scripts/changelog.js +++ b/scripts/changelog.js @@ -8,6 +8,11 @@ const config = require('@npmcli/template-oss') const { resolve, relative } = require('path') const exec = (...args) => execSync(...args).toString().trim() +const today = () => { + const d = new Date() + const pad = s => s.toString().padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +} const usage = () => ` node ${relative(process.cwd(), __filename)} [--read|-r] [--write|-w] [tag] @@ -74,7 +79,7 @@ const RELEASE = { return s.startsWith(TAG_PREFIX) ? s : TAG_PREFIX + s }, date (d) { - return `(${d || exec('date +%Y-%m-%d')})` + return `(${d})` }, title (v, d) { return `${this.heading}${this.version(v)} ${this.date(d)}` @@ -313,7 +318,7 @@ const generateRelease = async (args) => { // this doesnt work with majors but we dont do those very often const semverBump = commits.Features.length ? 'minor' : 'patch' const version = TAG_PREFIX + semver.parse(args.startTag).inc(semverBump).version - const date = args.endTag && exec(`git log -1 --date=short --format=%ad ${args.endTag}`) + const date = args.endTag ? exec(`git log -1 --date=short --format=%ad ${args.endTag}`) : today() const output = logger(RELEASE.title(version, date) + '\n') @@ -350,6 +355,7 @@ const generateRelease = async (args) => { } return { + date, version, release: output.toString(), } @@ -370,10 +376,13 @@ const main = async (argv) => { } // otherwise fetch the requested release from github - const { release, version } = await generateRelease(args) + const { release, version, date } = await generateRelease(args) - let msg = 'Edit release notes and run:\n' - msg += `git add CHANGELOG.md && git commit -m 'chore: changelog for ${version}'` + try { + exec(`node scripts/release-manager.js --update --version=${version.slice(1)} --date=${date}`) + } catch { + // optionally update release manager issue + } if (args.write) { const { release: existing, changelog } = findRelease(args, version) @@ -386,14 +395,12 @@ const main = async (argv) => { : changelog.replace(RELEASE.h1, RELEASE.h1 + release + RELEASE.sep), 'utf-8' ) - return console.error([ - `Release notes for ${version} written to "./${relative(process.cwd(), args.file)}".`, - msg, - ].join('\n')) + return console.log( + `Release notes for ${version} written to "./${relative(process.cwd(), args.file)}".` + ) } console.log(release) - console.error('\n' + msg) } main(process.argv.slice(2)) diff --git a/scripts/release-manager.js b/scripts/release-manager.js new file mode 100644 index 0000000000000..8622ac9982c17 --- /dev/null +++ b/scripts/release-manager.js @@ -0,0 +1,248 @@ +#!/usr/bin/env node + +const { basename, relative } = require('path') +const cp = require('child_process') + +const usage = () => ` + node ${relative(process.cwd(), __filename)} [flags] + + Copies the release process checklist to a GitHub issue, optionally updating the + version and date of the instructions. + + Flags: [--create] [--update[=]] [--date=] [--version=X.Y.Z] + + [--create] (default: true) + By default this will create a new issue in the repo. + + [--update[=]] + Update a specific issue number, or if set without a value it will update the most + recent issue created with the default tag. + + [--tag=] (default: "release-manager") + Issues will be created and looked up with this tag. + + [--version=X.Y.Z] + This script can be run before the next version number is known and then rerun + with this flag to update the checklist with the correct version number. + + [--date=] (default: ${date()}) + Set the date of the release in the release process checklist. +` + +const spawnSync = (cmd, args, options) => { + const res = cp.spawnSync(cmd, args, { ...options, encoding: 'utf-8' }) + if (res.status !== 0) { + throw new Error(res.stderr) + } + return res.stdout.trim() +} + +const get = url => + new Promise((resolve, reject) => { + require('https') + .get(url, resp => { + let d = '' + resp.on('data', c => (d += c)) + resp.on('end', () => resolve(d)) + }) + .on('error', reject) + }) + +const date = () => { + const d = new Date() + const pad = s => s.toString().padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +} + +const replaceAll = (str, rep) => + Object.entries(rep).reduce( + (a, [k, v]) => a.replace(new RegExp(k, 'g'), v), + str + ) + +const ghIssue = args => { + const label = ['-l', args.label] + const assignee = ['-a', args.assignee] + const title = ['-t', args.title] + const json = ['--json', 'body,title,number'] + const body = ['--body-file', '-'] + + const issue = (cmd, a, options) => + spawnSync('gh', ['issue', cmd, '-R', args.repo, ...a.flat()], options) + + const listIssues = () => { + const issues = JSON.parse(issue('list', [label, json])) + const ids = issues.map(i => '#' + i.number) + const msg = `Found existing label:${args.label} issues: ${ids.join(', ')}.` + return { issues, msg } + } + + switch (args.command) { + case 'list': { + // get the first matching issue + const { issues, msg } = listIssues() + if (issues.length > 1) { + throw new Error(`${msg} Rerun with --update= to target a specific issue.`) + } + return issues[0] + } + case 'view': + // get an issue by id + return JSON.parse(issue('view', [args.number, json])) + case 'create': { + const { issues, msg } = listIssues() + if (issues.length) { + throw new Error(`${msg} Close before creating a new one.`) + } + // create an issue + return issue('create', [assignee, label, title, body], { input: args.body }) + } + case 'edit': + // edit title and body of an issue + return issue('edit', [args.number, title, body], { input: args.body }) + default: + throw new Error(`Unknown command: ${JSON.stringify(args.command)}`) + } +} + +const getSection = (content, args) => { + const [, heading, section] = args.section.match(/^(#+)\s(.*)/) + + // remove the title since we are making a new one + const [title, ...lines] = content + .split(`${heading} `) + .find(s => s.split('\n')[0].match(new RegExp(section, 'i'))) + .trim() + .split('\n') + + // first task is to run this script, so thats done + const body = lines.join('\n').replace('- [ ] **0', '- [x] **0') + const created = `${basename(args.release)}${heading}${title}` + + return { + title: `Release Manager: v${args.version} (${args.date})`, + body: [ + `**Target Version**: v${args.version}`, + `**Target Date**: ${args.date}`, + // github markdown: 2x backticks + space will escape backticks within title + `**Created From:** [\`\` ${created} \`\`](${args.release})`, + body, + ] + .join('\n') + .trim(), + } +} + +const main = async args => { + const replace = s => replaceAll(s, args.replacements) + + const { body, title, number } = args.create + // get a section of the release process wiki doc + ? getSection(await get(args.release), args) + // get the contents of an existing gh issue by id + // or it will default to the most recent one by label + // this is so it will preserve state of checked todo items + : await ghIssue({ + ...args, + command: typeof args.update === 'string' ? 'view' : 'list', + number: args.update, + }) + + return ghIssue({ + ...args, + command: number ? 'edit' : 'create', + number, + body: replace(body), + title: replace(title), + }) +} + +const parseArgs = raw => { + const result = { + create: false, + update: null, + repo: 'npm/cli', + label: 'release: manager', + assignee: '@me', + date: date(), + version: 'X.Y.Z', + // look for that heading level with a match for the portion after + section: '### .*cli.*', + release: + 'https://raw.githubusercontent.com/wiki/npm/cli/Release-Process.md', + } + + const replacements = {} + + const clean = { + // this script will not work correctly with the tag style + // of the version (prefixed with a v) so strip it out + version: v => v.replace(/^v/g, ''), + } + + const shorts = { + R: 'repo', + l: 'label', + a: 'assignee', + d: 'date', + v: 'version', + c: 'create', + u: 'update', + } + + const camel = k => k.replace(/-([a-z])/g, a => a[1].toUpperCase()) + + // parse argv into array of [k,v] pairs + // works with --x=1 --x 1 --x -x + const argv = raw + .join(' ') // join to a string + .split(/(?:^|\s+)-/g) // split on starting dashses + .map(x => x.trim().replace(/\s+/g, ' ')) // collapse spaces + .filter(Boolean) // remove empties + .map(x => x.split(/[=\s]/)) // split on equal or space + .map(([k, v]) => [ + // we split on the initial dash previously so now + // 1 dash means 2 and 0 means 1 + ...(k.startsWith('-') ? ['--', k.slice(1)] : ['-', k]), + v ?? true, // default to true for no value + ]) + .map(([dash, key, value]) => ({ dash, key: camel(key), value })) + + for (const { dash, key, value } of argv) { + const k = dash.length < 2 ? shorts[key] : key + if (Object.hasOwn(result, k)) { + result[k] = clean[k] ? clean[k](value) : value + } else { + // any unknown arg is a replacement value + replacements[k] = value + } + } + + if (!result.create && !result.update) { + // set default to create if no command is specified + result.create = true + } else if (result.create && result.update) { + throw new Error('Cannot set both create and update') + } + + if (result.help) { + console.error(usage()) + return process.exit(0) + } + + return { + ...result, + replacements: { + '(\\d+\\.\\d+\\.\\d+|X\\.Y\\.Z)': result.version, + '(\\d{4}-\\d{2}-\\d{2}|YYYY-MM-DD)': result.date, + ...replacements, + }, + } +} + +main(parseArgs(process.argv.slice(2))) + .then(d => console.log(d)) + .catch(err => { + console.error(err) + process.exitCode = 1 + }) From 6611e9147f1726ab4537a7fe3b9e3beb6728f700 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Sun, 10 Apr 2022 11:03:36 -0700 Subject: [PATCH 031/406] feat(config): add more npm/node information to config ls --- lib/commands/config.js | 3 +++ tap-snapshots/test/lib/commands/config.js.test.cjs | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/commands/config.js b/lib/commands/config.js index 690a69a3233e4..24bab5fe6c9e6 100644 --- a/lib/commands/config.js +++ b/lib/commands/config.js @@ -266,6 +266,9 @@ ${defData} if (!long) { msg.push( `; node bin location = ${process.execPath}`, + `; node version = ${process.version}`, + `; npm bin location = ${dirname(dirname(__dirname))}`, + `; npm version = ${this.npm.version}`, `; cwd = ${process.cwd()}`, `; HOME = ${process.env.HOME}`, '; Run `npm config ls -l` to show all defaults.' diff --git a/tap-snapshots/test/lib/commands/config.js.test.cjs b/tap-snapshots/test/lib/commands/config.js.test.cjs index f98e74c066269..21add30da7be0 100644 --- a/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -342,6 +342,9 @@ prefix = "{LOCALPREFIX}" userconfig = "{HOME}/.npmrc" ; node bin location = {EXECPATH} +; node version = {NODE-VERSION} +; npm bin location = {NPMDIR} +; npm version = {NPM-VERSION} ; cwd = {NPMDIR} ; HOME = {HOME} ; Run \`npm config ls -l\` to show all defaults. @@ -355,6 +358,9 @@ prefix = "{LOCALPREFIX}" userconfig = "{HOME}/.npmrc" ; node bin location = {EXECPATH} +; node version = {NODE-VERSION} +; npm bin location = {NPMDIR} +; npm version = {NPM-VERSION} ; cwd = {NPMDIR} ; HOME = {HOME} ; Run \`npm config ls -l\` to show all defaults. @@ -383,6 +389,9 @@ prefix = "{LOCALPREFIX}" userconfig = "{HOME}/.npmrc" ; node bin location = {EXECPATH} +; node version = {NODE-VERSION} +; npm bin location = {NPMDIR} +; npm version = {NPM-VERSION} ; cwd = {NPMDIR} ; HOME = {HOME} ; Run \`npm config ls -l\` to show all defaults. From 03a034b882918d283da628b9582f9ffc9655d6ad Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 11 Apr 2022 11:19:00 -0700 Subject: [PATCH 032/406] fixup! feat(config): add more npm/node information to config ls --- lib/commands/config.js | 2 +- tap-snapshots/test/lib/commands/config.js.test.cjs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/commands/config.js b/lib/commands/config.js index 24bab5fe6c9e6..0432abac391f3 100644 --- a/lib/commands/config.js +++ b/lib/commands/config.js @@ -267,7 +267,7 @@ ${defData} msg.push( `; node bin location = ${process.execPath}`, `; node version = ${process.version}`, - `; npm bin location = ${dirname(dirname(__dirname))}`, + `; npm local prefix = ${this.npm.localPrefix}`, `; npm version = ${this.npm.version}`, `; cwd = ${process.cwd()}`, `; HOME = ${process.env.HOME}`, diff --git a/tap-snapshots/test/lib/commands/config.js.test.cjs b/tap-snapshots/test/lib/commands/config.js.test.cjs index 21add30da7be0..56ef71f3efd3c 100644 --- a/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -343,7 +343,7 @@ userconfig = "{HOME}/.npmrc" ; node bin location = {EXECPATH} ; node version = {NODE-VERSION} -; npm bin location = {NPMDIR} +; npm local prefix = {LOCALPREFIX} ; npm version = {NPM-VERSION} ; cwd = {NPMDIR} ; HOME = {HOME} @@ -359,7 +359,7 @@ userconfig = "{HOME}/.npmrc" ; node bin location = {EXECPATH} ; node version = {NODE-VERSION} -; npm bin location = {NPMDIR} +; npm local prefix = {LOCALPREFIX} ; npm version = {NPM-VERSION} ; cwd = {NPMDIR} ; HOME = {HOME} @@ -390,7 +390,7 @@ userconfig = "{HOME}/.npmrc" ; node bin location = {EXECPATH} ; node version = {NODE-VERSION} -; npm bin location = {NPMDIR} +; npm local prefix = {LOCALPREFIX} ; npm version = {NPM-VERSION} ; cwd = {NPMDIR} ; HOME = {HOME} From 06eff18d8a8f1ed41e91eb747f9c03e76d953353 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Sun, 10 Apr 2022 12:57:37 -0700 Subject: [PATCH 033/406] chore: refactor and update actions in nodejs pr workflow --- .github/workflows/create-cli-deps-pr.yml | 89 +++++++++++++----------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/.github/workflows/create-cli-deps-pr.yml b/.github/workflows/create-cli-deps-pr.yml index a59302ebeb0ac..c78703ac0b3e4 100644 --- a/.github/workflows/create-cli-deps-pr.yml +++ b/.github/workflows/create-cli-deps-pr.yml @@ -7,83 +7,94 @@ on: description: "6.x.x or latest" required: true default: 'latest' - + dryRun: + description: "Do a dry run" + required: true + default: false jobs: create-pull-request: runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.NPM_ROBOT_USER_PAT }} - NPM_VERSION: ${{ github.event.inputs.npmVersion }} - SUPPORT_BRANCH: "v14.x-staging" steps: - - name: Update gh cli & install jq parser - run: | - sudo apt-get update -y - sudo apt update - sudo apt-get install -y jq - sudo apt install gh - name: Checkout npm/node - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 ref: master - repository: "npm/node" + repository: npm/node token: ${{ secrets.NPM_ROBOT_USER_PAT }} - - name: Pull (Fast-Forward) upstream - id: sync - uses: aormsby/Fork-Sync-With-Upstream-action@v2.1 + - name: Setup git user + run: | + git config --global user.email "npm team" + git config --global user.name "ops+robot@npmjs.com" + - name: Sync upstream changes + uses: aormsby/Fork-Sync-With-Upstream-action@v3 with: - upstream_repository: nodejs/node - upstream_branch: master - target_branch: master - git_pull_args: --ff-only # optional arg use, defaults to simple 'pull' - github_token: ${{ secrets.NPM_ROBOT_USER_PAT }} # optional, for accessing repos that require authentication + target_sync_branch: master + target_repo_token: ${{ secrets.NPM_ROBOT_USER_PAT }} + upstream_sync_branch: master + upstream_sync_repo: nodejs/node + upstream_pull_args: --ff-only - name: Run dependency updates and create PR + env: + GITHUB_TOKEN: ${{ secrets.NPM_ROBOT_USER_PAT }} run: | + dry_run="${{ github.event.inputs.dryRun }}" + npm_version="${{ github.event.inputs.npmVersion }}" npm_tag="" base_branch="" - if [ "$NPM_VERSION" == "latest" ] - then + + if [ "$npm_version" == "latest" ]; then npm_tag=`npm view npm@latest version` base_branch="master" else - npm_tag="$NPM_VERSION" + npm_tag="$npm_version" base_branch="v14.x-staging" - fi + fi - git config user.name "npm team" - git config user.email "ops+robot@npmjs.com" - git checkout -b "npm-$npm_tag" + npm_vtag="v$npm_tag" + npm_branch="npm-$npm_tag" + message="deps: upgrade npm to $npm_tag" - BASE_DIR="$( pwd )"/ - DEPS_DIR="$BASE_DIR"deps/ + git checkout -b "$npm_branch" echo "Cloning CLI repo" gh repo clone npm/cli echo "Prepping CLI repo for release" cd cli - git checkout v"$npm_tag" + git checkout "$npm_vtag" make make release - echo "Removing old npm" - cd "$DEPS_DIR" + base_dir="$( pwd )"/ + deps_dir="$base_dir"deps/ + cd "$deps_dir" rm -rf npm/ echo "Copying new npm" - tar zxf "$BASE_DIR"cli/release/npm-"$npm_tag".tgz + tar zxf "$base_dir"cli/release/"$npm_branch".tgz echo "Removing CLI workspace" - cd "$BASE_DIR" + cd "$base_dir" rm -rf cli git add -A deps/npm - git commit -m "deps: upgrade npm to $npm_tag" + git commit -m "$message" git rebase --whitespace=fix master - git push origin "npm-$npm_tag" - gh_release_body=`gh release view v"$npm_tag" -R npm/cli --json body | jq -r '.body'` + git push origin "$npm_branch" + + gh_release=`gh release view "$npm_vtag" -R npm/cli --json body -q ".body"` + + if [[ "$dry_run" == "true" ]]; then + echo $gh_release + echo $message + echo $npm_branch + echo $base_branch + echo $npm_vtag + else + gh pr create -R nodejs/node -B "$base_branch" -H "npm:$npm_branch" -t "$message" -b "$gh_release" + fi - gh pr create -R "nodejs/node" -B "$base_branch" -H "npm:npm-$npm_tag" --title "deps: upgrade npm to $npm_tag" --body "$gh_release_body" + \ No newline at end of file From 5ba7f0cef753d4af0bc02ca7d6dd0ac1bdd11ffe Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Sun, 10 Apr 2022 22:21:17 -0700 Subject: [PATCH 034/406] fix: show more information during publish dry-run Fixes #4317 --- lib/commands/publish.js | 25 +++++++++++++------------ test/lib/commands/publish.js | 17 ++++++++++------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 1f26370e89a56..560dae1b6f0e4 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -102,19 +102,20 @@ class Publish extends BaseCommand { logTar(pkgContents, { unicode }) } + const resolved = npa.resolve(manifest.name, manifest.version) + const registry = npmFetch.pickRegistry(resolved, opts) + const creds = this.npm.config.getCredentialsByURI(registry) + const outputRegistry = replaceInfo(registry) + if (!creds.token && !creds.username) { + throw Object.assign( + new Error(`This command requires you to be logged in to ${outputRegistry}`), { + code: 'ENEEDAUTH', + } + ) + } + log.notice('', `Publishing to ${outputRegistry}${dryRun ? ' (dry-run)' : ''}`) + if (!dryRun) { - const resolved = npa.resolve(manifest.name, manifest.version) - const registry = npmFetch.pickRegistry(resolved, opts) - const creds = this.npm.config.getCredentialsByURI(registry) - const outputRegistry = replaceInfo(registry) - if (!creds.token && !creds.username) { - throw Object.assign( - new Error(`This command requires you to be logged in to ${outputRegistry}`), { - code: 'ENEEDAUTH', - } - ) - } - log.notice('', `Publishing to ${outputRegistry}`) await otplease(opts, opts => libpub(manifest, tarballData, opts)) } diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index 0acce8b001921..e266ea524ccc0 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -163,9 +163,9 @@ t.test('if loglevel=info and json, should not output package contents', async t t.test( /* eslint-disable-next-line max-len */ - 'if loglevel=silent and dry-run, should not output package contents or publish or validate credentials, should log tarball contents', + 'if loglevel=silent and dry-run, should not output package contents or publish, should log tarball contents', async t => { - t.plan(1) + t.plan(2) const testDir = t.testdir({ 'package.json': JSON.stringify( @@ -199,8 +199,9 @@ t.test( throw new Error('should not output in dry run mode') }, }, t) - npm.config.getCredentialsByURI = () => { - throw new Error('should not call getCredentialsByURI in dry run') + npm.config.getCredentialsByURI = uri => { + t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') + return { token: 'some.registry.token' } } const publish = new Publish(npm) @@ -213,7 +214,7 @@ t.test( /* eslint-disable-next-line max-len */ 'if loglevel=info and dry-run, should not publish, should log package contents and log tarball contents', async t => { - t.plan(2) + t.plan(3) const testDir = t.testdir({ 'package.json': JSON.stringify( @@ -247,9 +248,11 @@ t.test( t.pass('output fn is called') }, }, t) - npm.config.getCredentialsByURI = () => { - throw new Error('should not call getCredentialsByURI in dry run') + npm.config.getCredentialsByURI = uri => { + t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') + return { token: 'some.registry.token' } } + const publish = new Publish(npm) await publish.exec([testDir]) From 25450652240dc8e7e28e391313b93f0f27c6da19 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 11 Apr 2022 11:58:18 -0700 Subject: [PATCH 035/406] fixup! fix: show more information during publish dry-run --- lib/commands/publish.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 560dae1b6f0e4..51861c5aa3554 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -105,14 +105,18 @@ class Publish extends BaseCommand { const resolved = npa.resolve(manifest.name, manifest.version) const registry = npmFetch.pickRegistry(resolved, opts) const creds = this.npm.config.getCredentialsByURI(registry) + const noCreds = !creds.token && !creds.username const outputRegistry = replaceInfo(registry) - if (!creds.token && !creds.username) { - throw Object.assign( - new Error(`This command requires you to be logged in to ${outputRegistry}`), { - code: 'ENEEDAUTH', - } - ) + + if (noCreds) { + const msg = `This command requires you to be logged in to ${outputRegistry}` + if (dryRun) { + log.warn('', `${msg} (dry-run)`) + } else { + throw Object.assign(new Error(msg), { code: 'ENEEDAUTH' }) + } } + log.notice('', `Publishing to ${outputRegistry}${dryRun ? ' (dry-run)' : ''}`) if (!dryRun) { From e992b4a21ecdd96aa33c59682c0ac0cc8a30d776 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 11 Apr 2022 12:25:06 -0700 Subject: [PATCH 036/406] fixup! fix: show more information during publish dry-run --- test/lib/commands/publish.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index e266ea524ccc0..64eb7c60cb062 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -227,6 +227,18 @@ t.test( ), }) + const npm = mockNpm({ + config: { 'dry-run': true, loglevel: 'info' }, + output: () => { + t.pass('output fn is called') + }, + }, t) + const registry = npm.config.get('registry') + npm.config.getCredentialsByURI = uri => { + t.same(uri, registry, 'gets credentials for expected registry') + return { /* no token will call log.warn */ } + } + const Publish = t.mock('../../../lib/commands/publish.js', { '../../../lib/utils/tar.js': { getContents: () => ({ @@ -235,6 +247,12 @@ t.test( logTar: () => { t.pass('logTar is called') }, + 'proc-log': { + warn (_, msg) { + t.match(msg, + `This command requires you to be logged in to ${registry} (dry-run)`) + }, + }, }, libnpmpublish: { publish: () => { @@ -242,16 +260,6 @@ t.test( }, }, }) - const npm = mockNpm({ - config: { 'dry-run': true, loglevel: 'info' }, - output: () => { - t.pass('output fn is called') - }, - }, t) - npm.config.getCredentialsByURI = uri => { - t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } const publish = new Publish(npm) From aa4a4da336a6ec1963394fdbd06acb173c842d26 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 11 Apr 2022 17:53:33 -0700 Subject: [PATCH 037/406] fix(arborist): dont skip adding advisories to audit based on name/range When generating an audit report, a cache of seen advisories is kept to avoid doing any repeat fanout work on its nodes. Previously this cache was also preventing audits from being added to the report. This has been fixed so the cache is only used to prevent extra work, but all valid advisories are added to the output. Fixes #4681 --- workspaces/arborist/lib/audit-report.js | 75 +++++----- .../test/audit-report.js.test.cjs | 129 ++++++++++++++++++ 2 files changed, 165 insertions(+), 39 deletions(-) diff --git a/workspaces/arborist/lib/audit-report.js b/workspaces/arborist/lib/audit-report.js index 4dc6dd177c1e4..9bef84686f4b4 100644 --- a/workspaces/arborist/lib/audit-report.js +++ b/workspaces/arborist/lib/audit-report.js @@ -134,16 +134,7 @@ class AuditReport extends Map { const seen = new Set() for (const advisory of advisories) { const { name, range } = advisory - - // don't flag the exact same name/range more than once - // 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)) { - continue - } - - seen.add(k) const vuln = this.get(name) || new Vuln({ name, advisory }) if (this.has(name)) { @@ -151,44 +142,50 @@ class AuditReport extends Map { } super.set(name, vuln) - const p = [] - for (const node of this.tree.inventory.query('packageName', name)) { - if (!shouldAudit(node, this[_omit], this.filterSet)) { - continue - } + // don't flag the exact same name/range more than once + // adding multiple advisories with the same range is fine, but no + // need to search for nodes we already would have added. + if (!seen.has(k)) { + const p = [] + for (const node of this.tree.inventory.query('packageName', name)) { + if (!shouldAudit(node, this[_omit], this.filterSet)) { + continue + } - // if not vulnerable by this advisory, keep searching - if (!advisory.testVersion(node.version)) { - continue - } + // if not vulnerable by this advisory, keep searching + if (!advisory.testVersion(node.version)) { + continue + } - // we will have loaded the source already if this is a metavuln - if (advisory.type === 'metavuln') { - vuln.addVia(this.get(advisory.dependency)) - } + // we will have loaded the source already if this is a 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)) { - continue - } + // already marked this one, no need to do it again + 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)) { - this[_checkTopNode](dep, vuln, spec) - } else { + // 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)) { + this[_checkTopNode](dep, vuln, spec) + } else { // calculate a metavuln, if necessary - const calc = this.calculator.calculate(dep.packageName, advisory) - p.push(calc.then(meta => { - if (meta.testVersion(dep.version, spec)) { - advisories.add(meta) - } - })) + const calc = this.calculator.calculate(dep.packageName, advisory) + p.push(calc.then(meta => { + if (meta.testVersion(dep.version, spec)) { + advisories.add(meta) + } + })) + } } } + await Promise.all(p) + seen.add(k) } - await Promise.all(p) // make sure we actually got something. if not, remove it // this can happen if you are loading from a lockfile created by diff --git a/workspaces/arborist/tap-snapshots/test/audit-report.js.test.cjs b/workspaces/arborist/tap-snapshots/test/audit-report.js.test.cjs index 91d7ecffceaeb..cc1354e64c818 100644 --- a/workspaces/arborist/tap-snapshots/test/audit-report.js.test.cjs +++ b/workspaces/arborist/tap-snapshots/test/audit-report.js.test.cjs @@ -123,6 +123,15 @@ exports[`test/audit-report.js TAP all severity levels > json version 1`] = ` "severity": "high", "range": "<3.0.8 || >=4.0.0 <4.5.3" }, + { + "source": 1325, + "name": "handlebars", + "dependency": "handlebars", + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "severity": "high", + "range": "<3.0.8 || >=4.0.0 <4.5.3" + }, { "source": 755, "name": "handlebars", @@ -448,6 +457,15 @@ exports[`test/audit-report.js TAP all severity levels > json version 1`] = ` "url": "https://npmjs.com/advisories/1478", "severity": "high", "range": ">=4.1.0" + }, + { + "source": 1479, + "name": "subtext", + "dependency": "subtext", + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1479", + "severity": "high", + "range": ">=0.0.0" } ], "effects": [], @@ -558,6 +576,15 @@ exports[`test/audit-report.js TAP audit outdated nyc and mkdirp > json version 1 "severity": "high", "range": "<3.0.8 || >=4.0.0 <4.5.3" }, + { + "source": 1325, + "name": "handlebars", + "dependency": "handlebars", + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "severity": "high", + "range": "<3.0.8 || >=4.0.0 <4.5.3" + }, { "source": 755, "name": "handlebars", @@ -918,6 +945,15 @@ exports[`test/audit-report.js TAP audit outdated nyc and mkdirp with before: opt "severity": "high", "range": "<3.0.8 || >=4.0.0 <4.5.3" }, + { + "source": 1325, + "name": "handlebars", + "dependency": "handlebars", + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "severity": "high", + "range": "<3.0.8 || >=4.0.0 <4.5.3" + }, { "source": 755, "name": "handlebars", @@ -1278,6 +1314,15 @@ exports[`test/audit-report.js TAP audit outdated nyc and mkdirp with newer endpo "severity": "high", "range": "<3.0.8 || >=4.0.0 <4.5.3" }, + { + "source": 1325, + "name": "handlebars", + "dependency": "handlebars", + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "severity": "high", + "range": "<3.0.8 || >=4.0.0 <4.5.3" + }, { "source": 755, "name": "handlebars", @@ -2144,6 +2189,20 @@ Object { "versions": undefined, "vulnerableVersions": undefined, }, + Object { + "cvss": undefined, + "cwe": undefined, + "dependency": "handlebars", + "id": undefined, + "name": "handlebars", + "range": "<3.0.8 || >=4.0.0 <4.5.3", + "severity": "high", + "source": 1325, + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "versions": undefined, + "vulnerableVersions": undefined, + }, Object { "cvss": undefined, "cwe": undefined, @@ -2623,6 +2682,20 @@ Object { "versions": undefined, "vulnerableVersions": undefined, }, + Object { + "cvss": undefined, + "cwe": undefined, + "dependency": "handlebars", + "id": undefined, + "name": "handlebars", + "range": "<3.0.8 || >=4.0.0 <4.5.3", + "severity": "high", + "source": 1325, + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "versions": undefined, + "vulnerableVersions": undefined, + }, Object { "cvss": undefined, "cwe": undefined, @@ -2791,6 +2864,20 @@ Object { "versions": undefined, "vulnerableVersions": undefined, }, + Object { + "cvss": undefined, + "cwe": undefined, + "dependency": "handlebars", + "id": undefined, + "name": "handlebars", + "range": "<3.0.8 || >=4.0.0 <4.5.3", + "severity": "high", + "source": 1325, + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "versions": undefined, + "vulnerableVersions": undefined, + }, Object { "cvss": undefined, "cwe": undefined, @@ -3270,6 +3357,20 @@ Object { "versions": undefined, "vulnerableVersions": undefined, }, + Object { + "cvss": undefined, + "cwe": undefined, + "dependency": "handlebars", + "id": undefined, + "name": "handlebars", + "range": "<3.0.8 || >=4.0.0 <4.5.3", + "severity": "high", + "source": 1325, + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "versions": undefined, + "vulnerableVersions": undefined, + }, Object { "cvss": undefined, "cwe": undefined, @@ -3458,6 +3559,20 @@ Object { "versions": undefined, "vulnerableVersions": undefined, }, + Object { + "cvss": undefined, + "cwe": undefined, + "dependency": "handlebars", + "id": undefined, + "name": "handlebars", + "range": "<3.0.8 || >=4.0.0 <4.5.3", + "severity": "high", + "source": 1325, + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "versions": undefined, + "vulnerableVersions": undefined, + }, Object { "cvss": undefined, "cwe": undefined, @@ -3927,6 +4042,20 @@ Object { "versions": undefined, "vulnerableVersions": undefined, }, + Object { + "cvss": undefined, + "cwe": undefined, + "dependency": "handlebars", + "id": undefined, + "name": "handlebars", + "range": "<3.0.8 || >=4.0.0 <4.5.3", + "severity": "high", + "source": 1325, + "title": "Prototype Pollution", + "url": "https://npmjs.com/advisories/1325", + "versions": undefined, + "vulnerableVersions": undefined, + }, Object { "cvss": undefined, "cwe": undefined, From c057b90d0954ff5b6f2973748ae5d41885b99213 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Tue, 12 Apr 2022 23:29:30 -0700 Subject: [PATCH 038/406] feat(config): warn on deprecated configs --- lib/auth/sso.js | 2 -- lib/commands/install.js | 11 +---------- test/lib/auth/sso.js | 17 ----------------- test/lib/commands/install.js | 7 ++----- 4 files changed, 3 insertions(+), 34 deletions(-) diff --git a/lib/auth/sso.js b/lib/auth/sso.js index 795eb8972a223..9812a18cb99ca 100644 --- a/lib/auth/sso.js +++ b/lib/auth/sso.js @@ -36,8 +36,6 @@ function sleep (time) { } const login = async (npm, { creds, registry, scope }) => { - log.warn('deprecated', 'SSO --auth-type is deprecated') - const opts = { ...npm.flatOptions, creds, registry, scope } const { ssoType } = opts diff --git a/lib/commands/install.js b/lib/commands/install.js index ebba02a1bd47d..0a5c827bcc97b 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -109,7 +109,6 @@ class Install extends ArboristWorkspaceCmd { 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 @@ -140,14 +139,6 @@ class Install extends ArboristWorkspaceCmd { args = ['.'] } - // TODO: Add warnings for other deprecated flags? or remove this one? - if (isDev) { - log.warn( - 'install', - 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.' - ) - } - const opts = { ...this.npm.flatOptions, auditLevel: null, @@ -163,7 +154,7 @@ class Install extends ArboristWorkspaceCmd { 'preinstall', 'install', 'postinstall', - 'prepublish', // XXX should we remove this finally?? + 'prepublish', // XXX(npm9) should we remove this finally?? 'preprepare', 'prepare', 'postprepare', diff --git a/test/lib/auth/sso.js b/test/lib/auth/sso.js index eab51f06c0ab2..8d70077ad205f 100644 --- a/test/lib/auth/sso.js +++ b/test/lib/auth/sso.js @@ -1,7 +1,6 @@ const t = require('tap') let log = '' -let warn = '' const _flatOptions = { ssoType: 'oauth', @@ -15,9 +14,6 @@ const sso = t.mock('../../../lib/auth/sso.js', { info: (...msgs) => { log += msgs.join(' ') + '\n' }, - warn: (...msgs) => { - warn += msgs.join(' ') - }, }, 'npm-profile': profile, 'npm-registry-fetch': npmFetch, @@ -44,15 +40,8 @@ t.test('empty login', async (t) => { 'should throw if no sso-type defined in flatOptions' ) - t.equal( - warn, - 'deprecated SSO --auth-type is deprecated', - 'should print deprecation warning' - ) - _flatOptions.ssoType = 'oauth' log = '' - warn = '' }) t.test('simple login', async (t) => { @@ -104,7 +93,6 @@ t.test('simple login', async (t) => { ) log = '' - warn = '' delete profile.loginCouch delete npmFetch.json }) @@ -151,7 +139,6 @@ t.test('polling retry', async (t) => { }) log = '' - warn = '' delete profile.loginCouch delete npmFetch.json }) @@ -174,7 +161,6 @@ t.test('polling error', async (t) => { ) log = '' - warn = '' delete profile.loginCouch delete npmFetch.json }) @@ -193,7 +179,6 @@ t.test('no token retrieved from loginCouch', async (t) => { ) log = '' - warn = '' delete profile.loginCouch }) @@ -211,7 +196,6 @@ t.test('no sso url retrieved from loginCouch', async (t) => { ) log = '' - warn = '' delete profile.loginCouch }) @@ -247,7 +231,6 @@ t.test('scoped login', async (t) => { ) log = '' - warn = '' delete profile.loginCouch delete npmFetch.json }) diff --git a/test/lib/commands/install.js b/test/lib/commands/install.js index d5db3af673caa..afb6adb4fb0a5 100644 --- a/test/lib/commands/install.js +++ b/test/lib/commands/install.js @@ -12,7 +12,7 @@ t.test('with args, dev=true', async t => { let REIFY_CALLED = false let ARB_OBJ = null - const { npm, logs } = await loadMockNpm(t, { + const { npm } = await loadMockNpm(t, { '@npmcli/run-script': ({ event }) => { SCRIPTS.push(event) }, @@ -41,10 +41,7 @@ t.test('with args, dev=true', async t => { npm.prefix = path.resolve(t.testdir({})) await npm.exec('install', ['fizzbuzz']) - t.match( - logs.warn, - [['install', 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.']] - ) + t.match( ARB_ARGS, { global: false, path: npm.prefix, auditLevel: null }, From 98377d159f72a5b6073f07235b057984eb09a85c Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 09:41:50 -0700 Subject: [PATCH 039/406] deps: @npmcli/config@4.1.0 --- node_modules/@npmcli/config/lib/index.js | 5 ++--- node_modules/@npmcli/config/package.json | 6 +++--- package-lock.json | 14 +++++++------- package.json | 2 +- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/node_modules/@npmcli/config/lib/index.js b/node_modules/@npmcli/config/lib/index.js index bb8c24602fa52..5b7ea68e91e36 100644 --- a/node_modules/@npmcli/config/lib/index.js +++ b/node_modules/@npmcli/config/lib/index.js @@ -506,10 +506,9 @@ class Config { } [_checkDeprecated] (key, where, obj, kv) { - // XXX a future npm version will make this a warning. - // An even more future npm version will make this an error. + // XXX(npm9+) make this throw an error if (this.deprecated[key]) { - log.verbose('config', key, this.deprecated[key]) + log.warn('config', key, this.deprecated[key]) } } diff --git a/node_modules/@npmcli/config/package.json b/node_modules/@npmcli/config/package.json index fff1575ea9fd3..2cc04e05be8c9 100644 --- a/node_modules/@npmcli/config/package.json +++ b/node_modules/@npmcli/config/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/config", - "version": "4.0.2", + "version": "4.1.0", "files": [ "bin/", "lib/" @@ -31,7 +31,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/template-oss": "3.3.2", "tap": "^16.0.1" }, "dependencies": { @@ -49,6 +49,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "3.3.2" } } diff --git a/package-lock.json b/package-lock.json index 43cb34ccea27f..f53bbee66173e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,7 +91,7 @@ "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^5.0.4", "@npmcli/ci-detect": "^2.0.0", - "@npmcli/config": "^4.0.2", + "@npmcli/config": "^4.1.0", "@npmcli/fs": "^2.1.0", "@npmcli/map-workspaces": "^2.0.2", "@npmcli/package-json": "^2.0.0", @@ -859,9 +859,9 @@ } }, "node_modules/@npmcli/config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-4.0.2.tgz", - "integrity": "sha512-UqD4h4LgyNOb7xRmAK7QXiMu0/k2x7wEzrEqXZ1wGIQVmCl3vamsAprDjAhi7IKlgRulg09hpwYs2/57OP22xw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-4.1.0.tgz", + "integrity": "sha512-cPQmIQ2Q0vuOfrenrA3isikdMFMAHgzlXV+EmvZ8f2JeJsU5xTU2bG7ipXECiMvPF9nM+QDnMLuIg8QLw9H4xg==", "inBundle": true, "dependencies": { "@npmcli/map-workspaces": "^2.0.2", @@ -10527,9 +10527,9 @@ "version": "2.0.0" }, "@npmcli/config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-4.0.2.tgz", - "integrity": "sha512-UqD4h4LgyNOb7xRmAK7QXiMu0/k2x7wEzrEqXZ1wGIQVmCl3vamsAprDjAhi7IKlgRulg09hpwYs2/57OP22xw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-4.1.0.tgz", + "integrity": "sha512-cPQmIQ2Q0vuOfrenrA3isikdMFMAHgzlXV+EmvZ8f2JeJsU5xTU2bG7ipXECiMvPF9nM+QDnMLuIg8QLw9H4xg==", "requires": { "@npmcli/map-workspaces": "^2.0.2", "ini": "^3.0.0", diff --git a/package.json b/package.json index 3989e8e7227fa..f4fbaed09ba18 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^5.0.4", "@npmcli/ci-detect": "^2.0.0", - "@npmcli/config": "^4.0.2", + "@npmcli/config": "^4.1.0", "@npmcli/fs": "^2.1.0", "@npmcli/map-workspaces": "^2.0.2", "@npmcli/package-json": "^2.0.0", From 71ab00ac3021e147c3fac19268f8e22bd163e529 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 12 Apr 2022 08:40:59 -0700 Subject: [PATCH 040/406] chore: fix adduser tests They mock real registry calls now --- test/fixtures/mock-npm.js | 18 +- test/fixtures/mock-registry.js | 39 +++- test/lib/commands/adduser.js | 314 ++++++++++++++++----------------- 3 files changed, 200 insertions(+), 171 deletions(-) diff --git a/test/fixtures/mock-npm.js b/test/fixtures/mock-npm.js index 07e4cb8283b4c..b6742a425aa9a 100644 --- a/test/fixtures/mock-npm.js +++ b/test/fixtures/mock-npm.js @@ -61,6 +61,7 @@ const LoadMockNpm = async (t, { init = true, load = init, prefixDir = {}, + homeDir = {}, cacheDir = {}, globalPrefixDir = {}, config = {}, @@ -70,6 +71,12 @@ const LoadMockNpm = async (t, { // Mock some globals with their original values so they get torn down // back to the original at the end of the test since they are manipulated // by npm itself + const npmConfigEnv = {} + for (const key in process.env) { + if (key.startsWith('npm_config_')) { + npmConfigEnv[key] = undefined + } + } mockGlobals(t, { process: { title: process.title, @@ -77,6 +84,7 @@ const LoadMockNpm = async (t, { env: { npm_command: process.env.npm_command, COLOR: process.env.COLOR, + ...npmConfigEnv, }, }, }) @@ -94,14 +102,21 @@ const LoadMockNpm = async (t, { // Set log level as early as possible since setLoglevel(t, config.loglevel) - const dir = t.testdir({ prefix: prefixDir, cache: cacheDir, global: globalPrefixDir }) + const dir = t.testdir({ + home: homeDir, + prefix: prefixDir, + cache: cacheDir, + global: globalPrefixDir, + }) const prefix = path.join(dir, 'prefix') const cache = path.join(dir, 'cache') const globalPrefix = path.join(dir, 'global') + const home = path.join(dir, 'home') // Set cache to testdir via env var so it is available when load is run // XXX: remove this for a solution where cache argv is passed in mockGlobals(t, { + 'process.env.HOME': home, 'process.env.npm_config_cache': cache, ...(globals ? result(globals, { prefix, cache }) : {}), // Some configs don't work because they can't be set via npm.config.set until @@ -140,6 +155,7 @@ const LoadMockNpm = async (t, { ...rest, Npm, npm, + home, prefix, globalPrefix, testdir: dir, diff --git a/test/fixtures/mock-registry.js b/test/fixtures/mock-registry.js index b08ede6672972..6b6722fcbbc3c 100644 --- a/test/fixtures/mock-registry.js +++ b/test/fixtures/mock-registry.js @@ -41,7 +41,7 @@ class MockRegistry { } whoami ({ username }) { - this.nock.get('/-/whoami').reply(200, { username }) + this.nock = this.nock.get('/-/whoami').reply(200, { username }) } access ({ spec, access, publishRequires2fa }) { @@ -52,7 +52,7 @@ class MockRegistry { if (publishRequires2fa !== undefined) { body.publish_requires_tfa = publishRequires2fa } - this.nock.post( + this.nock = this.nock.post( `/-/package/${encodeURIComponent(spec)}/access`, body ).reply(200) @@ -63,7 +63,7 @@ class MockRegistry { team = team.slice(1) } const [scope, teamName] = team.split(':') - this.nock.put( + this.nock = this.nock.put( `/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package`, { package: spec, permissions } ).reply(200) @@ -74,12 +74,39 @@ class MockRegistry { team = team.slice(1) } const [scope, teamName] = team.split(':') - this.nock.delete( + this.nock = this.nock.delete( `/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package`, { package: spec } ).reply(200) } + couchlogin ({ username, password, email, otp, token = 'npm_default-test-token' }) { + this.nock = this.nock + .post('/-/v1/login').reply(401, { error: 'You must be logged in to publish packages.' }) + if (otp) { + // TODO otp failure results in a 401 with + // {"ok":false,"error":"failed to authenticate: Could not authenticate ${username}: bad otp"} + } + this.nock = this.nock.put(`/-/user/org.couchdb.user:${username}`, body => { + this.#tap.match(body, { + _id: `org.couchdb.user:${username}`, + name: username, + password, + type: 'user', + roles: [], + }) + if (!body.date) { + return false + } + return true + }).reply(201, { + ok: true, + id: 'org.couchdb.user:undefined', + rev: '_we_dont_use_revs_any_more', + token, + }) + } + // team can be a team or a username lsPackages ({ team, packages = {} }) { if (team.startsWith('@')) { @@ -92,7 +119,7 @@ class MockRegistry { } else { uri = `/-/org/${encodeURIComponent(scope)}/package` } - this.nock.get(uri).query({ format: 'cli' }).reply(200, packages) + this.nock = this.nock.get(uri).query({ format: 'cli' }).reply(200, packages) } lsCollaborators ({ spec, user, collaborators = {} }) { @@ -100,7 +127,7 @@ class MockRegistry { if (user) { query.user = user } - this.nock.get(`/-/package/${encodeURIComponent(spec)}/collaborators`) + this.nock = this.nock.get(`/-/package/${encodeURIComponent(spec)}/collaborators`) .query(query) .reply(200, collaborators) } diff --git a/test/lib/commands/adduser.js b/test/lib/commands/adduser.js index f88508d15a6fe..ca07199b2c9fb 100644 --- a/test/lib/commands/adduser.js +++ b/test/lib/commands/adduser.js @@ -1,190 +1,176 @@ const t = require('tap') -const { getCredentialsByURI, setCredentialsByURI } = - require('@npmcli/config').prototype +const path = require('path') +const fs = require('fs') +const os = require('os') -let result = '' - -const _flatOptions = { - authType: 'legacy', - registry: 'https://registry.npmjs.org/', - scope: '', - fromFlatOptions: true, -} - -let failSave = false -let deletedConfig = {} -let registryOutput = '' -let setConfig = {} -const authDummy = (npm, options) => { - if (!options.fromFlatOptions) { - throw new Error('did not pass full flatOptions to auth function') - } - - return Promise.resolve({ - message: 'success', - newCreds: { - username: 'u', - password: 'p', - email: 'u@npmjs.org', - }, - }) -} - -const deleteMock = (key, where) => { - deletedConfig = { - ...deletedConfig, - [key]: where, - } -} -const npm = { - flatOptions: _flatOptions, - config: { - delete: deleteMock, - get (key, where) { - if (!where || where === 'user') { - return _flatOptions[key] - } - }, - getCredentialsByURI, - async save () { - if (failSave) { - throw new Error('error saving user config') - } - }, - set (key, value, where) { - setConfig = { - ...setConfig, - [key]: { - value, - where, - }, - } - }, - setCredentialsByURI, - }, - output: msg => { - result = msg - }, -} - -const AddUser = t.mock('../../../lib/commands/adduser.js', { - npmlog: { - clearProgress: () => null, - disableProgress: () => null, - }, - 'proc-log': { - notice: (_, msg) => { - registryOutput = msg - }, - }, - '../../../lib/auth/legacy.js': authDummy, -}) - -const adduser = new AddUser(npm) - -t.afterEach(() => { - _flatOptions.authType = 'legacy' - _flatOptions.scope = '' - registryOutput = '' - deletedConfig = {} - setConfig = {} - result = '' - failSave = false -}) +const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') +const mockGlobals = require('../../fixtures/mock-globals.js') +const MockRegistry = require('../../fixtures/mock-registry.js') +const stream = require('stream') t.test('usage', async t => { + const { npm } = await loadMockNpm(t) + const adduser = await npm.cmd('adduser') t.match(adduser.usage, 'adduser', 'usage has command name in it') }) t.test('simple login', async t => { - await adduser.exec([]) - t.equal( - registryOutput, - 'Log in on https://registry.npmjs.org/', - 'should have correct message result' - ) - - t.same( - deletedConfig, - { - _token: 'user', - _password: 'user', - username: 'user', - _auth: 'user', - _authtoken: 'user', - '-authtoken': 'user', - _authToken: 'user', - '//registry.npmjs.org/:-authtoken': 'user', - '//registry.npmjs.org/:_authToken': 'user', - '//registry.npmjs.org/:_authtoken': 'user', - '//registry.npmjs.org/:always-auth': 'user', - '//registry.npmjs.org/:email': 'user', + const stdin = new stream.PassThrough() + stdin.write('test-user\n') + stdin.write('test-password\n') + stdin.write('test-email@npmjs.org\n') + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + const { npm, home } = await loadMockNpm(t, { + homeDir: { + // These all get cleaned up by config.setCredentialsByURI + '.npmrc': [ + '_token=user', + '_password=user', + 'username=user', + '_auth=user', + '_authtoken=user', + '-authtoken=user', + '_authToken=user', + '//registry.npmjs.org/:-authtoken=user', + '//registry.npmjs.org/:_authToken=user', + '//registry.npmjs.org/:_authtoken=user', + '//registry.npmjs.org/:always-auth=user', + '//registry.npmjs.org/:email=test-email-old@npmjs.org', + ].join('\n'), }, - 'should delete token in user config' - ) - + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + registry.couchlogin({ + username: 'test-user', + password: 'test-password', + email: 'test-email@npmjs.org', + token: 'npm_test-token', + }) + await npm.exec('adduser', []) + t.same(npm.config.get('email'), 'test-email-old@npmjs.org') + t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') + const rc = fs.readFileSync(path.join(home, '.npmrc'), 'utf8') t.same( - setConfig, - { - '//registry.npmjs.org/:_password': { value: 'cA==', where: 'user' }, - '//registry.npmjs.org/:username': { value: 'u', where: 'user' }, - email: { value: 'u@npmjs.org', where: 'user' }, - }, - 'should set expected user configs' - ) - - t.equal( - result, - 'success', - 'should output auth success msg' + rc.trim().split(os.EOL), [ + '//registry.npmjs.org/:_authToken=npm_test-token', + 'email=test-email-old@npmjs.org', + ], 'should only have token and un-nerfed old email' ) }) t.test('bad auth type', async t => { - _flatOptions.authType = 'foo' - - await t.rejects( - adduser.exec([]), - /no such auth module/, - 'should throw bad auth type error' - ) + const { npm } = await loadMockNpm(t, { + config: { + 'auth-type': 'foo', + }, + }) + await t.rejects(npm.exec('adduser', []), { + message: 'no such auth module', + }) }) t.test('scoped login', async t => { - _flatOptions.scope = '@myscope' - - await adduser.exec([]) - + const stdin = new stream.PassThrough() + stdin.write('test-user\n') + stdin.write('test-password\n') + stdin.write('test-email@npmjs.org\n') + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + const { npm, home } = await loadMockNpm(t, { + config: { + scope: '@myscope', + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + registry.couchlogin({ + username: 'test-user', + password: 'test-password', + email: 'test-email@npmjs.org', + token: 'npm_test-token', + }) + await npm.exec('adduser', []) + t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token') + t.same(npm.config.get('@myscope:registry'), 'https://registry.npmjs.org/') + const rc = fs.readFileSync(path.join(home, '.npmrc'), 'utf8') t.same( - setConfig['@myscope:registry'], - { value: 'https://registry.npmjs.org/', where: 'user' }, - 'should set scoped registry config' - ) + rc.trim().split(os.EOL), [ + '//registry.npmjs.org/:_authToken=npm_test-token', + '@myscope:registry=https://registry.npmjs.org/', + ], 'should only have token and scope:registry') }) t.test('scoped login with valid scoped registry config', async t => { - _flatOptions['@myscope:registry'] = 'https://diff-registry.npmjs.com/' - _flatOptions.scope = '@myscope' - - t.teardown(() => { - delete _flatOptions['@myscope:registry'] + const stdin = new stream.PassThrough() + stdin.write('test-user\n') + stdin.write('test-password\n') + stdin.write('test-email@npmjs.org\n') + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': '@myscope:registry=https://diff-registry.npmjs.org', + }, + config: { + scope: '@myscope', + }, }) - - await adduser.exec([]) - - t.same( - setConfig['@myscope:registry'], - { value: 'https://diff-registry.npmjs.com/', where: 'user' }, - 'should keep scoped registry config' - ) + const registry = new MockRegistry({ + tap: t, + registry: 'https://diff-registry.npmjs.org', + }) + registry.couchlogin({ + username: 'test-user', + password: 'test-password', + email: 'test-email@npmjs.org', + token: 'npm_test-token', + }) + await npm.exec('adduser', []) + t.same(npm.config.get('//diff-registry.npmjs.org/:_authToken'), 'npm_test-token') + t.same(npm.config.get('@myscope:registry'), 'https://diff-registry.npmjs.org') + const rc = fs.readFileSync(path.join(home, '.npmrc'), 'utf8') + t.same(rc.trim().split(os.EOL), + [ + '@myscope:registry=https://diff-registry.npmjs.org', + '//diff-registry.npmjs.org/:_authToken=npm_test-token', + ], 'should only have token and scope:registry') }) t.test('save config failure', async t => { - failSave = true - - await t.rejects( - adduser.exec([]), - /error saving user config/, - 'should throw config.save error' - ) + const stdin = new stream.PassThrough() + stdin.write('test-user\n') + stdin.write('test-password\n') + stdin.write('test-email@npmjs.org\n') + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + const { npm } = await loadMockNpm(t, { + homeDir: { + '.npmrc': {}, + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + registry.couchlogin({ + username: 'test-user', + password: 'test-password', + email: 'test-email@npmjs.org', + token: 'npm_test-token', + }) + await t.rejects(npm.exec('adduser', [])) }) From 0cd852f62e1453e647a2551e98c78ce7e0c8ea03 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 13 Apr 2022 08:43:23 -0700 Subject: [PATCH 041/406] fix: mitigate doctor test race condition cacache appears to not write everything to the cache by the time doctor is checking permissions. This limits the permissions error to a single directory that we know exists by the time the checks run. --- .../test/lib/commands/doctor.js.test.cjs | 98 +------------------ test/lib/commands/doctor.js | 6 +- 2 files changed, 5 insertions(+), 99 deletions(-) diff --git a/tap-snapshots/test/lib/commands/doctor.js.test.cjs b/tap-snapshots/test/lib/commands/doctor.js.test.cjs index a28654e5d9b29..d84d7d368580c 100644 --- a/tap-snapshots/test/lib/commands/doctor.js.test.cjs +++ b/tap-snapshots/test/lib/commands/doctor.js.test.cjs @@ -467,7 +467,7 @@ node -v ok current: v1.0.0, recommended: v1.0.0 npm config get registry ok using default registry (https://registry.npmjs.org/) which git ok /path/to/git Perms check on cached files not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache (should be owned by current user) -Perms check on local node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/prefix/node_modules (should be owned by current user) +Perms check on local node_modules ok Perms check on global node_modules ok Perms check on local bin folder ok Perms check on global bin folder ok @@ -514,106 +514,10 @@ Object { ], ], "warn": Array [ - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache", - ], Array [ "checkFilesPermission", "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache", ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_logs", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/index-v5", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/tmp", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_logs/{DATE}-debug-0.log", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2/sha512", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/index-v5/5e", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/index-v5/af", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2/sha512/{sha}", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2/sha512/{sha}", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/index-v5/5e/be", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/index-v5/af/03", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2/sha512/{sha}", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2/sha512/{sha}", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/index-v5/5e/be/ccdeeea0a01ebb0e365e566161f7c68ddcbbe04206d8542742d98875f03f", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/index-v5/af/03/5c781820370e585dc2323edbbc80669bf714da5b47d56510c7d0bd7521ee", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2/sha512/{sha}", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache/content-v2/sha512/{sha}", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/prefix/node_modules", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/prefix/node_modules/.bin", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/prefix/node_modules/testDir", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/prefix/node_modules/testLink", - ], - Array [ - "checkFilesPermission", - "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/prefix/node_modules/testDir/testFile", - ], ], } ` diff --git a/test/lib/commands/doctor.js b/test/lib/commands/doctor.js index 620d908d3030e..eaf2ee6c6f8a2 100644 --- a/test/lib/commands/doctor.js +++ b/test/lib/commands/doctor.js @@ -359,8 +359,10 @@ t.test('incorrect owner', async t => { ...fs, lstat: (p, cb) => { const stat = fs.lstatSync(p) - stat.uid += 1 - stat.gid += 1 + if (p.endsWith('_cacache')) { + stat.uid += 1 + stat.gid += 1 + } return cb(null, stat) }, }, From 605ccef6916c170f6d0c53775614f8a02682262a Mon Sep 17 00:00:00 2001 From: Gar Date: Sat, 9 Apr 2022 19:28:10 -0700 Subject: [PATCH 042/406] deps: remove ansistyles chalk is already in use elsewhere and does what we need --- lib/commands/outdated.js | 13 ++- lib/commands/profile.js | 4 +- lib/commands/token.js | 4 +- lib/commands/view.js | 10 +-- node_modules/ansistyles/LICENSE | 23 ------ node_modules/ansistyles/ansistyles.js | 38 --------- node_modules/ansistyles/package.json | 23 ------ node_modules/ansistyles/test/ansistyles.js | 15 ---- package-lock.json | 10 --- package.json | 2 - .../test/lib/commands/profile.js.test.cjs | 82 +++++++++---------- test/lib/commands/profile.js | 1 - 12 files changed, 56 insertions(+), 169 deletions(-) delete mode 100644 node_modules/ansistyles/LICENSE delete mode 100644 node_modules/ansistyles/ansistyles.js delete mode 100644 node_modules/ansistyles/package.json delete mode 100644 node_modules/ansistyles/test/ansistyles.js diff --git a/lib/commands/outdated.js b/lib/commands/outdated.js index 0cb5b4247a000..1420d94cd5319 100644 --- a/lib/commands/outdated.js +++ b/lib/commands/outdated.js @@ -2,8 +2,7 @@ const os = require('os') const path = require('path') const pacote = require('pacote') const table = require('text-table') -const color = require('chalk') -const styles = require('ansistyles') +const chalk = require('chalk') const npa = require('npm-package-arg') const pickManifest = require('npm-pick-manifest') const localeCompare = require('@isaacs/string-locale-compare')('en') @@ -106,7 +105,7 @@ class Outdated extends ArboristWorkspaceCmd { const outTable = [outHead].concat(outList) if (this.npm.color) { - outTable[0] = outTable[0].map(heading => styles.underline(heading)) + outTable[0] = outTable[0].map(heading => chalk.underline(heading)) } const tableOpts = { @@ -282,7 +281,7 @@ class Outdated extends ArboristWorkspaceCmd { : node.name return this.npm.color && humanOutput - ? color.green(workspaceName) + ? chalk.green(workspaceName) : workspaceName } @@ -307,9 +306,9 @@ class Outdated extends ArboristWorkspaceCmd { } if (this.npm.color) { - columns[0] = color[current === wanted ? 'yellow' : 'red'](columns[0]) // current - columns[2] = color.green(columns[2]) // wanted - columns[3] = color.magenta(columns[3]) // latest + columns[0] = chalk[current === wanted ? 'yellow' : 'red'](columns[0]) // current + columns[2] = chalk.green(columns[2]) // wanted + columns[3] = chalk.magenta(columns[3]) // latest } return columns diff --git a/lib/commands/profile.js b/lib/commands/profile.js index a82d31fd443a9..fcf0eb7d53fa6 100644 --- a/lib/commands/profile.js +++ b/lib/commands/profile.js @@ -1,6 +1,6 @@ const inspect = require('util').inspect const { URL } = require('url') -const ansistyles = require('ansistyles') +const chalk = require('chalk') const log = require('../utils/log-shim.js') const npmProfile = require('npm-profile') const qrcodeTerminal = require('qrcode-terminal') @@ -163,7 +163,7 @@ class Profile extends BaseCommand { } else { const table = new Table() for (const key of Object.keys(cleaned)) { - table.push({ [ansistyles.bright(key)]: cleaned[key] }) + table.push({ [chalk.bold(key)]: cleaned[key] }) } this.npm.output(table.toString()) diff --git a/lib/commands/token.js b/lib/commands/token.js index f57c212c49e45..edfb07b9d3a9a 100644 --- a/lib/commands/token.js +++ b/lib/commands/token.js @@ -1,5 +1,5 @@ const Table = require('cli-table3') -const ansistyles = require('ansistyles') +const chalk = require('chalk') const { v4: isCidrV4, v6: isCidrV6 } = require('is-cidr') const log = require('../utils/log-shim.js') const profile = require('npm-profile') @@ -161,7 +161,7 @@ class Token extends BaseCommand { } else { const table = new Table() for (const k of Object.keys(result)) { - table.push({ [ansistyles.bright(k)]: String(result[k]) }) + table.push({ [chalk.bold(k)]: String(result[k]) }) } this.npm.output(table.toString()) } diff --git a/lib/commands/view.js b/lib/commands/view.js index 99cf2981306fa..afe4b24282bd9 100644 --- a/lib/commands/view.js +++ b/lib/commands/view.js @@ -4,6 +4,7 @@ // npm view [pkg [pkg ...]] const color = require('ansicolors') +const chalk = require('chalk') const columns = require('cli-columns') const fs = require('fs') const jsonParse = require('json-parse-even-better-errors') @@ -13,7 +14,6 @@ const { resolve } = require('path') const formatBytes = require('../utils/format-bytes.js') const relativeDate = require('tiny-relative-date') const semver = require('semver') -const style = require('ansistyles') const { inspect, promisify } = require('util') const { packument } = require('pacote') @@ -318,7 +318,7 @@ class View extends BaseCommand { Object.keys(packument['dist-tags']).forEach((t) => { const version = packument['dist-tags'][t] - tags.push(`${style.bright(color.green(t))}: ${version}`) + tags.push(`${chalk.bold(color.green(t))}: ${version}`) }) const unpackedSize = manifest.dist.unpackedSize && formatBytes(manifest.dist.unpackedSize, true) @@ -365,14 +365,14 @@ class View extends BaseCommand { unpackedSize: unpackedSize && color.yellow(unpackedSize), } if (info.license.toLowerCase().trim() === 'proprietary') { - info.license = style.bright(color.red(info.license)) + info.license = chalk.bold(color.red(info.license)) } else { info.license = color.green(info.license) } console.log('') console.log( - style.underline(style.bright(`${info.name}@${info.version}`)) + + chalk.underline.bold(`${info.name}@${info.version}`) + ' | ' + info.license + ' | deps: ' + (info.deps.length ? color.cyan(info.deps.length) : color.green('none')) + ' | versions: ' + info.versions @@ -384,7 +384,7 @@ class View extends BaseCommand { const warningSign = unicode ? ' ⚠️ ' : '!!' info.deprecated && console.log( - `\n${style.bright(color.red('DEPRECATED'))}${ + `\n${chalk.bold(color.red('DEPRECATED'))}${ warningSign } - ${info.deprecated}` ) diff --git a/node_modules/ansistyles/LICENSE b/node_modules/ansistyles/LICENSE deleted file mode 100644 index 41702c5043478..0000000000000 --- a/node_modules/ansistyles/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2013 Thorsten Lorenz. -All rights reserved. - -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/ansistyles/ansistyles.js b/node_modules/ansistyles/ansistyles.js deleted file mode 100644 index 5b8788c0f9419..0000000000000 --- a/node_modules/ansistyles/ansistyles.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -/* - * Info: http://www.termsys.demon.co.uk/vtansi.htm#colors - * Following caveats - * bright - brightens the color (bold-blue is same as brigthtBlue) - * dim - nothing on Mac or Linux - * italic - nothing on Mac or Linux - * underline - underlines string - * blink - nothing on Mac or linux - * inverse - background becomes foreground and vice versa - * - * In summary, the only styles that work are: - * - bright, underline and inverse - * - the others are only included for completeness - */ - -var styleNums = { - reset : [0, 22] - , bright : [1, 22] - , dim : [2, 22] - , italic : [3, 23] - , underline : [4, 24] - , blink : [5, 25] - , inverse : [7, 27] - } - , styles = {} - ; - -Object.keys(styleNums).forEach(function (k) { - styles[k] = function (s) { - var open = styleNums[k][0] - , close = styleNums[k][1]; - return '\u001b[' + open + 'm' + s + '\u001b[' + close + 'm'; - }; -}); - -module.exports = styles; diff --git a/node_modules/ansistyles/package.json b/node_modules/ansistyles/package.json deleted file mode 100644 index 2fe1f4da4fffa..0000000000000 --- a/node_modules/ansistyles/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "ansistyles", - "version": "0.1.3", - "description": "Functions that surround a string with ansistyle codes so it prints in style.", - "main": "ansistyles.js", - "scripts": { - "test": "node test/ansistyles.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/thlorenz/ansistyles.git" - }, - "keywords": [ - "ansi", - "style", - "terminal", - "console" - ], - "author": "Thorsten Lorenz (thlorenz.com)", - "license": "MIT", - "readmeFilename": "README.md", - "gitHead": "27bf1bc65231bcc7fd109bf13b13601b51f8cd04" -} diff --git a/node_modules/ansistyles/test/ansistyles.js b/node_modules/ansistyles/test/ansistyles.js deleted file mode 100644 index f769bf803b209..0000000000000 --- a/node_modules/ansistyles/test/ansistyles.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; -/*jshint asi: true */ -var assert = require('assert') - , styles = require('../') - -function inspect(obj, depth) { - console.log(require('util').inspect(obj, false, depth || 5, true)); -} - -assert.equal(styles.reset('reset'), '\u001b[0mreset\u001b[22m', 'reset') -assert.equal(styles.underline('underlined'), '\u001b[4munderlined\u001b[24m', 'underline') -assert.equal(styles.bright('bright'), '\u001b[1mbright\u001b[22m', 'bright') -assert.equal(styles.inverse('inversed'), '\u001b[7minversed\u001b[27m', 'inverse') - -console.log('OK'); diff --git a/package-lock.json b/package-lock.json index f53bbee66173e..3704afac626c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,6 @@ "@npmcli/run-script", "abbrev", "ansicolors", - "ansistyles", "archy", "cacache", "chalk", @@ -98,7 +97,6 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", "archy": "~1.0.0", "cacache": "^16.0.4", "chalk": "^4.1.2", @@ -1248,11 +1246,6 @@ "inBundle": true, "license": "MIT" }, - "node_modules/ansistyles": { - "version": "0.1.3", - "inBundle": true, - "license": "MIT" - }, "node_modules/anymatch": { "version": "3.1.2", "dev": true, @@ -10782,9 +10775,6 @@ "ansicolors": { "version": "0.3.2" }, - "ansistyles": { - "version": "0.1.3" - }, "anymatch": { "version": "3.1.2", "dev": true, diff --git a/package.json b/package.json index f4fbaed09ba18..548e509ded1f2 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", "archy": "~1.0.0", "cacache": "^16.0.4", "chalk": "^4.1.2", @@ -139,7 +138,6 @@ "@npmcli/run-script", "abbrev", "ansicolors", - "ansistyles", "archy", "cacache", "chalk", diff --git a/tap-snapshots/test/lib/commands/profile.js.test.cjs b/tap-snapshots/test/lib/commands/profile.js.test.cjs index 31205b7fedc05..2103ccdd32e33 100644 --- a/tap-snapshots/test/lib/commands/profile.js.test.cjs +++ b/tap-snapshots/test/lib/commands/profile.js.test.cjs @@ -47,56 +47,56 @@ github https://github.com/npm ` exports[`test/lib/commands/profile.js TAP profile get no args default output > should output table with contents 1`] = ` -name: foo -email: foo@github.com (verified) -two-factor auth: auth-and-writes -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z +name: foo +email: foo@github.com (verified) +two-factor auth: auth-and-writes +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z ` exports[`test/lib/commands/profile.js TAP profile get no args no tfa enabled > should output expected profile values 1`] = ` -name: foo -email: foo@github.com (verified) -two-factor auth: disabled -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z +name: foo +email: foo@github.com (verified) +two-factor auth: disabled +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z ` exports[`test/lib/commands/profile.js TAP profile get no args profile has cidr_whitelist item > should output table with contents 1`] = ` -name: foo -email: foo@github.com (verified) -two-factor auth: auth-and-writes -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z -cidr_whitelist: 192.168.1.1 +name: foo +email: foo@github.com (verified) +two-factor auth: auth-and-writes +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z +cidr_whitelist: 192.168.1.1 ` exports[`test/lib/commands/profile.js TAP profile get no args unverified email > should output table with contents 1`] = ` -name: foo -email: foo@github.com(unverified) -two-factor auth: auth-and-writes -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z +name: foo +email: foo@github.com(unverified) +two-factor auth: auth-and-writes +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z ` exports[`test/lib/commands/profile.js TAP profile set writable key --parseable > should output parseable set key success msg 1`] = ` diff --git a/test/lib/commands/profile.js b/test/lib/commands/profile.js index da32d4300840a..09fd08cfc5329 100644 --- a/test/lib/commands/profile.js +++ b/test/lib/commands/profile.js @@ -19,7 +19,6 @@ const npm = mockNpm({ }, }) const mocks = { - ansistyles: { bright: a => a }, npmlog: { gauge: { show () {} }, }, From c22fb1e756d43b54fefd826f2c3f459d4f1204b5 Mon Sep 17 00:00:00 2001 From: Gar Date: Sun, 10 Apr 2022 16:26:55 -0700 Subject: [PATCH 043/406] deps: remove ansicolors --- lib/commands/help-search.js | 4 +- lib/commands/view.js | 49 +++++++------ node_modules/ansicolors/LICENSE | 23 ------ node_modules/ansicolors/ansicolors.js | 65 ----------------- node_modules/ansicolors/package.json | 23 ------ node_modules/ansicolors/test/ansicolors.js | 71 ------------------- package-lock.json | 10 --- package.json | 2 - .../tap-snapshots/test/index.js.test.cjs | 22 +++--- .../test/lib/commands/view.js.test.cjs | 8 +-- test/lib/commands/help-search.js | 4 +- 11 files changed, 43 insertions(+), 238 deletions(-) delete mode 100644 node_modules/ansicolors/LICENSE delete mode 100644 node_modules/ansicolors/ansicolors.js delete mode 100644 node_modules/ansicolors/package.json delete mode 100644 node_modules/ansicolors/test/ansicolors.js diff --git a/lib/commands/help-search.js b/lib/commands/help-search.js index 3387ac8eb542c..23b426eaa016d 100644 --- a/lib/commands/help-search.js +++ b/lib/commands/help-search.js @@ -1,6 +1,6 @@ const fs = require('fs') const path = require('path') -const color = require('ansicolors') +const chalk = require('chalk') const { promisify } = require('util') const glob = promisify(require('glob')) const readFile = promisify(fs.readFile) @@ -173,7 +173,7 @@ class HelpSearch extends BaseCommand { for (const f of finder) { hilitLine.push(line.slice(p, p + f.length)) const word = line.slice(p + f.length, p + f.length + arg.length) - const hilit = color.bgBlack(color.red(word)) + const hilit = chalk.bgBlack.red(word) hilitLine.push(hilit) p += f.length + arg.length } diff --git a/lib/commands/view.js b/lib/commands/view.js index afe4b24282bd9..403d09d813dc7 100644 --- a/lib/commands/view.js +++ b/lib/commands/view.js @@ -3,7 +3,6 @@ // npm view [pkg [pkg ...]] -const color = require('ansicolors') const chalk = require('chalk') const columns = require('cli-columns') const fs = require('fs') @@ -318,34 +317,34 @@ class View extends BaseCommand { Object.keys(packument['dist-tags']).forEach((t) => { const version = packument['dist-tags'][t] - tags.push(`${chalk.bold(color.green(t))}: ${version}`) + tags.push(`${chalk.bold.green(t)}: ${version}`) }) const unpackedSize = manifest.dist.unpackedSize && formatBytes(manifest.dist.unpackedSize, true) const licenseField = manifest.license || 'Proprietary' const info = { - name: color.green(manifest.name), - version: color.green(manifest.version), - bins: Object.keys(manifest.bin || {}).map(color.yellow), - versions: color.yellow(packument.versions.length + ''), + name: chalk.green(manifest.name), + version: chalk.green(manifest.version), + bins: Object.keys(manifest.bin || {}), + versions: chalk.yellow(packument.versions.length + ''), description: manifest.description, deprecated: manifest.deprecated, - keywords: (packument.keywords || []).map(color.yellow), + keywords: packument.keywords || [], license: typeof licenseField === 'string' ? licenseField : (licenseField.type || 'Proprietary'), deps: Object.keys(manifest.dependencies || {}).map((dep) => { - return `${color.yellow(dep)}: ${manifest.dependencies[dep]}` + return `${chalk.yellow(dep)}: ${manifest.dependencies[dep]}` }), publisher: manifest._npmUser && unparsePerson({ - name: color.yellow(manifest._npmUser.name), - email: color.cyan(manifest._npmUser.email), + name: chalk.yellow(manifest._npmUser.name), + email: chalk.cyan(manifest._npmUser.email), }), modified: !packument.time ? undefined - : color.yellow(relativeDate(packument.time[manifest.version])), + : chalk.yellow(relativeDate(packument.time[manifest.version])), maintainers: (packument.maintainers || []).map((u) => unparsePerson({ - name: color.yellow(u.name), - email: color.cyan(u.email), + name: chalk.yellow(u.name), + email: chalk.cyan(u.email), })), repo: ( manifest.bugs && (manifest.bugs.url || manifest.bugs) @@ -356,47 +355,47 @@ class View extends BaseCommand { manifest.homepage && (manifest.homepage.url || manifest.homepage) ), tags, - tarball: color.cyan(manifest.dist.tarball), - shasum: color.yellow(manifest.dist.shasum), + tarball: chalk.cyan(manifest.dist.tarball), + shasum: chalk.yellow(manifest.dist.shasum), integrity: - manifest.dist.integrity && color.yellow(manifest.dist.integrity), + manifest.dist.integrity && chalk.yellow(manifest.dist.integrity), fileCount: - manifest.dist.fileCount && color.yellow(manifest.dist.fileCount), - unpackedSize: unpackedSize && color.yellow(unpackedSize), + manifest.dist.fileCount && chalk.yellow(manifest.dist.fileCount), + unpackedSize: unpackedSize && chalk.yellow(unpackedSize), } if (info.license.toLowerCase().trim() === 'proprietary') { - info.license = chalk.bold(color.red(info.license)) + info.license = chalk.bold.red(info.license) } else { - info.license = color.green(info.license) + info.license = chalk.green(info.license) } console.log('') console.log( chalk.underline.bold(`${info.name}@${info.version}`) + ' | ' + info.license + - ' | deps: ' + (info.deps.length ? color.cyan(info.deps.length) : color.green('none')) + + ' | deps: ' + (info.deps.length ? chalk.cyan(info.deps.length) : chalk.green('none')) + ' | versions: ' + info.versions ) info.description && console.log(info.description) if (info.repo || info.site) { - info.site && console.log(color.cyan(info.site)) + info.site && console.log(chalk.cyan(info.site)) } const warningSign = unicode ? ' ⚠️ ' : '!!' info.deprecated && console.log( - `\n${chalk.bold(color.red('DEPRECATED'))}${ + `\n${chalk.bold.red('DEPRECATED')}${ warningSign } - ${info.deprecated}` ) if (info.keywords.length) { console.log('') - console.log('keywords:', info.keywords.join(', ')) + console.log('keywords:', chalk.yellow(info.keywords.join(', '))) } if (info.bins.length) { console.log('') - console.log('bin:', info.bins.join(', ')) + console.log('bin:', chalk.yellow(info.bins.join(', '))) } console.log('') diff --git a/node_modules/ansicolors/LICENSE b/node_modules/ansicolors/LICENSE deleted file mode 100644 index 41702c5043478..0000000000000 --- a/node_modules/ansicolors/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2013 Thorsten Lorenz. -All rights reserved. - -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/ansicolors/ansicolors.js b/node_modules/ansicolors/ansicolors.js deleted file mode 100644 index 16b2586f6b163..0000000000000 --- a/node_modules/ansicolors/ansicolors.js +++ /dev/null @@ -1,65 +0,0 @@ -// ColorCodes explained: http://www.termsys.demon.co.uk/vtansi.htm -'use strict'; - -var colorNums = { - white : 37 - , black : 30 - , blue : 34 - , cyan : 36 - , green : 32 - , magenta : 35 - , red : 31 - , yellow : 33 - , brightBlack : 90 - , brightRed : 91 - , brightGreen : 92 - , brightYellow : 93 - , brightBlue : 94 - , brightMagenta : 95 - , brightCyan : 96 - , brightWhite : 97 - } - , backgroundColorNums = { - bgBlack : 40 - , bgRed : 41 - , bgGreen : 42 - , bgYellow : 43 - , bgBlue : 44 - , bgMagenta : 45 - , bgCyan : 46 - , bgWhite : 47 - , bgBrightBlack : 100 - , bgBrightRed : 101 - , bgBrightGreen : 102 - , bgBrightYellow : 103 - , bgBrightBlue : 104 - , bgBrightMagenta : 105 - , bgBrightCyan : 106 - , bgBrightWhite : 107 - } - , open = {} - , close = {} - , colors = {} - ; - -Object.keys(colorNums).forEach(function (k) { - var o = open[k] = '\u001b[' + colorNums[k] + 'm'; - var c = close[k] = '\u001b[39m'; - - colors[k] = function (s) { - return o + s + c; - }; -}); - -Object.keys(backgroundColorNums).forEach(function (k) { - var o = open[k] = '\u001b[' + backgroundColorNums[k] + 'm'; - var c = close[k] = '\u001b[49m'; - - colors[k] = function (s) { - return o + s + c; - }; -}); - -module.exports = colors; -colors.open = open; -colors.close = close; diff --git a/node_modules/ansicolors/package.json b/node_modules/ansicolors/package.json deleted file mode 100644 index cda0c75b5850a..0000000000000 --- a/node_modules/ansicolors/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "ansicolors", - "version": "0.3.2", - "description": "Functions that surround a string with ansicolor codes so it prints in color.", - "main": "ansicolors.js", - "scripts": { - "test": "node test/*.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/thlorenz/ansicolors.git" - }, - "keywords": [ - "ansi", - "colors", - "highlight", - "string" - ], - "author": "Thorsten Lorenz (thlorenz.com)", - "license": "MIT", - "readmeFilename": "README.md", - "gitHead": "858847ca28e8b360d9b70eee0592700fa2ab087d" -} diff --git a/node_modules/ansicolors/test/ansicolors.js b/node_modules/ansicolors/test/ansicolors.js deleted file mode 100644 index 494539305d3ac..0000000000000 --- a/node_modules/ansicolors/test/ansicolors.js +++ /dev/null @@ -1,71 +0,0 @@ -'use strict'; - -var assert = require('assert') - , colors = require('..') - , open = colors.open - , close = colors.close - -console.log('Foreground colors ..'); - -assert.equal(colors.white('printed in white'), '\u001b[37mprinted in white\u001b[39m'); - -assert.equal(colors.black('printed in black'), '\u001b[30mprinted in black\u001b[39m'); -assert.equal(colors.brightBlack('printed in bright black'), '\u001b[90mprinted in bright black\u001b[39m'); - -assert.equal(colors.green('printed in green'), '\u001b[32mprinted in green\u001b[39m'); -assert.equal(colors.brightGreen('printed in bright green'), '\u001b[92mprinted in bright green\u001b[39m'); - -assert.equal(colors.red('printed in red'), '\u001b[31mprinted in red\u001b[39m'); -assert.equal(colors.brightRed('printed in bright red'), '\u001b[91mprinted in bright red\u001b[39m'); - -console.log('OK'); - -console.log('Background colors ..'); - -assert.equal( - colors.bgBlack('printed with black background') - , '\u001b[40mprinted with black background\u001b[49m' -); - -assert.equal( - colors.bgYellow('printed with yellow background') - , '\u001b[43mprinted with yellow background\u001b[49m' -); -assert.equal( - colors.bgBrightYellow('printed with bright yellow background') - , '\u001b[103mprinted with bright yellow background\u001b[49m' -); - -assert.equal( - colors.bgWhite('printed with white background') - , '\u001b[47mprinted with white background\u001b[49m' -); - -console.log('OK'); - -console.log('Mixing background and foreground colors ..'); - -assert.equal( - colors.blue(colors.bgYellow('printed in blue with yellow background')) - , '\u001b[34m\u001b[43mprinted in blue with yellow background\u001b[49m\u001b[39m' -); -assert.equal( - colors.bgYellow(colors.blue('printed in blue with yellow background again')) - , '\u001b[43m\u001b[34mprinted in blue with yellow background again\u001b[39m\u001b[49m' -); - -console.log('OK'); - -console.log('Open ...'); - -assert.equal(open.black, '\u001b[30m'); -assert.equal(open.bgYellow, '\u001b[43m'); - -console.log('OK'); - -console.log('Close ...'); - -assert.equal(close.black, '\u001b[39m'); -assert.equal(close.bgYellow, '\u001b[49m'); - -console.log('OK'); diff --git a/package-lock.json b/package-lock.json index 3704afac626c5..5138eee431c5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "@npmcli/package-json", "@npmcli/run-script", "abbrev", - "ansicolors", "archy", "cacache", "chalk", @@ -96,7 +95,6 @@ "@npmcli/package-json": "^2.0.0", "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", - "ansicolors": "~0.3.2", "archy": "~1.0.0", "cacache": "^16.0.4", "chalk": "^4.1.2", @@ -1241,11 +1239,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansicolors": { - "version": "0.3.2", - "inBundle": true, - "license": "MIT" - }, "node_modules/anymatch": { "version": "3.1.2", "dev": true, @@ -10772,9 +10765,6 @@ "color-convert": "^2.0.1" } }, - "ansicolors": { - "version": "0.3.2" - }, "anymatch": { "version": "3.1.2", "dev": true, diff --git a/package.json b/package.json index 548e509ded1f2..44e5beca0a121 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "@npmcli/package-json": "^2.0.0", "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", - "ansicolors": "~0.3.2", "archy": "~1.0.0", "cacache": "^16.0.4", "chalk": "^4.1.2", @@ -137,7 +136,6 @@ "@npmcli/package-json", "@npmcli/run-script", "abbrev", - "ansicolors", "archy", "cacache", "chalk", diff --git a/smoke-tests/tap-snapshots/test/index.js.test.cjs b/smoke-tests/tap-snapshots/test/index.js.test.cjs index 486849d6cbf54..5a13b4e9a5c20 100644 --- a/smoke-tests/tap-snapshots/test/index.js.test.cjs +++ b/smoke-tests/tap-snapshots/test/index.js.test.cjs @@ -761,24 +761,24 @@ changed 1 package exports[`test/index.js TAP npm view > should have expected view output 1`] = ` -abbrev@1.0.4 | MIT | deps: none | versions: 8 +abbrev@1.0.4 | MIT | deps: none | versions: 8 Like ruby's abbrev module, but in js -https://github.com/isaacs/abbrev-js#readme +https://github.com/isaacs/abbrev-js#readme dist -.tarball: https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz -.shasum: bd55ae5e413ba1722ee4caba1f6ea10414a59ecd +.tarball: https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz +.shasum: bd55ae5e413ba1722ee4caba1f6ea10414a59ecd maintainers: -- nlf <quitlahok@gmail.com> -- ruyadorno <ruyadorno@hotmail.com> -- darcyclarke <darcy@darcyclarke.me> -- adam_baldwin <evilpacket@gmail.com> -- isaacs <i@izs.me> +- nlf +- ruyadorno +- darcyclarke +- adam_baldwin +- isaacs dist-tags: -latest: 1.1.1 +latest: 1.1.1 -published over a year ago by isaacs <i@izs.me> +published over a year ago by isaacs ` diff --git a/tap-snapshots/test/lib/commands/view.js.test.cjs b/tap-snapshots/test/lib/commands/view.js.test.cjs index 229a9d323dbae..5868e7b04babe 100644 --- a/tap-snapshots/test/lib/commands/view.js.test.cjs +++ b/tap-snapshots/test/lib/commands/view.js.test.cjs @@ -127,7 +127,7 @@ green is a very important color DEPRECATED!! - true -keywords:colors, green, crayola +keywords:colors, green, crayola bin:green @@ -209,7 +209,7 @@ green is a very important color DEPRECATED!! - true -keywords:colors, green, crayola +keywords:colors, green, crayola bin:green @@ -440,7 +440,7 @@ green is a very important color DEPRECATED!! - true -keywords:colors, green, crayola +keywords:colors, green, crayola bin:green @@ -508,7 +508,7 @@ green is a very important color DEPRECATED!! - true -keywords:colors, green, crayola +keywords:colors, green, crayola bin:green diff --git a/test/lib/commands/help-search.js b/test/lib/commands/help-search.js index 8d13009a22252..7fbeb195d23c7 100644 --- a/test/lib/commands/help-search.js +++ b/test/lib/commands/help-search.js @@ -1,7 +1,7 @@ const t = require('tap') const { join } = require('path') const { fake: mockNpm } = require('../../fixtures/mock-npm') -const ansicolors = require('ansicolors') +const chalk = require('chalk') const OUTPUT = [] const output = msg => { @@ -106,7 +106,7 @@ t.test('npm help-search long output with color', async t => { await helpSearch.exec(['help-search']) - const highlightedText = ansicolors.bgBlack(ansicolors.red('help-search')) + const highlightedText = chalk.bgBlack.red('help-search') t.equal( OUTPUT.some(line => line.includes(highlightedText)), true, From ba8b2a753d63c8a8c7a44a48c2e13626b12025fe Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 10:19:58 -0700 Subject: [PATCH 044/406] fix(ls): make `--omit` filter `npm ls` This makes `npm ls` use the same logic as other commands (eg `outdated`) when parsing config items that filter the output based on package type. Previously `--development` and `--production` has special semantics when used with `npm ls` that were inconsistent with the rest of the CLI. To achieve the same behavior as these deprecated flags use: - in place of `--development` use `--omit peer --omit prod --omit optional` - in place of `--production` use `--omit dev --omit peer` Fixes #4739 --- lib/commands/ls.js | 45 ++----- lib/commands/outdated.js | 2 +- test/lib/commands/ls.js | 224 +++------------------------------- test/lib/commands/outdated.js | 25 ++-- 4 files changed, 44 insertions(+), 252 deletions(-) diff --git a/lib/commands/ls.js b/lib/commands/ls.js index e56c90dae16ea..06268fe7e0ac0 100644 --- a/lib/commands/ls.js +++ b/lib/commands/ls.js @@ -52,16 +52,12 @@ class LS extends ArboristWorkspaceCmd { const all = this.npm.config.get('all') const color = this.npm.color const depth = this.npm.config.get('depth') - const dev = this.npm.config.get('dev') - const development = this.npm.config.get('development') const global = this.npm.config.get('global') const json = this.npm.config.get('json') const link = this.npm.config.get('link') const long = this.npm.config.get('long') - const only = this.npm.config.get('only') + const omit = this.npm.flatOptions.omit const parseable = this.npm.config.get('parseable') - const prod = this.npm.config.get('prod') - const production = this.npm.config.get('production') const unicode = this.npm.config.get('unicode') const packageLockOnly = this.npm.config.get('package-lock-only') const workspacesEnabled = this.npm.flatOptions.workspacesEnabled @@ -138,15 +134,10 @@ class LS extends ArboristWorkspaceCmd { ? [] : [...(node.target).edgesOut.values()] .filter(filterBySelectedWorkspaces) - .filter(filterByEdgesTypes({ - currentDepth, - dev, - development, + .filter(currentDepth === 0 ? filterByEdgesTypes({ link, - prod, - production, - only, - })) + omit, + }) : () => true) .map(mapEdgesToNodes({ seenPaths })) .concat(appendExtraneousChildren({ node, seenPaths })) .sort(sortAlphabetically) @@ -399,27 +390,13 @@ const getJsonOutputItem = (node, { global, long }) => { return augmentItemWithIncludeMetadata(node, item) } -const filterByEdgesTypes = ({ - currentDepth, - dev, - development, - link, - prod, - production, - only, -}) => { - // filter deps by type, allows for: `npm ls --dev`, `npm ls --prod`, - // `npm ls --link`, `npm ls --only=dev`, etc - const filterDev = currentDepth === 0 && - (dev || development || /^dev(elopment)?$/.test(only)) - const filterProd = currentDepth === 0 && - (prod || production || /^prod(uction)?$/.test(only)) - const filterLink = currentDepth === 0 && link - - return (edge) => - (filterDev ? edge.dev : true) && - (filterProd ? (!edge.dev && !edge.peer && !edge.peerOptional) : true) && - (filterLink ? (edge.to && edge.to.isLink) : true) +const filterByEdgesTypes = ({ link, omit = [] }) => (edge) => { + for (const omitType of omit) { + if (edge[omitType]) { + return false + } + } + return link ? edge.to && edge.to.isLink : true } const appendExtraneousChildren = ({ node, seenPaths }) => diff --git a/lib/commands/outdated.js b/lib/commands/outdated.js index 1420d94cd5319..0953c17ca10d2 100644 --- a/lib/commands/outdated.js +++ b/lib/commands/outdated.js @@ -207,7 +207,7 @@ class Outdated extends ArboristWorkspaceCmd { : edge.dev ? 'devDependencies' : 'dependencies' - for (const omitType of this.npm.config.get('omit')) { + for (const omitType of this.npm.flatOptions.omit) { if (node[omitType]) { return } diff --git a/test/lib/commands/ls.js b/test/lib/commands/ls.js index 9fd4db167df6f..412d5ce6532a0 100644 --- a/test/lib/commands/ls.js +++ b/test/lib/commands/ls.js @@ -99,14 +99,12 @@ const LS = t.mock('../../../lib/commands/ls.js', { const config = { all: true, color: false, - dev: false, depth: Infinity, global: false, json: false, link: false, - only: null, + omit: [], parseable: false, - production: false, 'package-lock-only': false, } const flatOptions = { @@ -456,7 +454,7 @@ t.test('ls', t => { }) t.test('--dev', async t => { - config.dev = true + flatOptions.omit = ['peer', 'prod', 'optional'] npm.prefix = t.testdir({ 'package.json': JSON.stringify({ name: 'test-npm-ls', @@ -479,34 +477,7 @@ t.test('ls', t => { }) await ls.exec([]) t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps') - config.dev = false - }) - - t.test('--only=development', async t => { - config.only = 'development' - npm.prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - 'prod-dep': '^1.0.0', - chai: '^1.0.0', - }, - devDependencies: { - 'dev-dep': '^1.0.0', - }, - optionalDependencies: { - 'optional-dep': '^1.0.0', - }, - peerDependencies: { - 'peer-dep': '^1.0.0', - }, - }), - ...diffDepTypesNmFixture, - }) - await ls.exec([]) - t.matchSnapshot(redactCwd(result), 'should output tree containing only development deps') - config.only = null + flatOptions.omit = [] }) t.test('--link', async t => { @@ -581,7 +552,7 @@ t.test('ls', t => { }) t.test('--production', async t => { - config.production = true + flatOptions.omit = ['dev', 'peer'] npm.prefix = t.testdir({ 'package.json': JSON.stringify({ name: 'test-npm-ls', @@ -604,34 +575,7 @@ t.test('ls', t => { }) await ls.exec([]) t.matchSnapshot(redactCwd(result), 'should output tree containing production deps') - config.production = false - }) - - t.test('--only=prod', async t => { - config.only = 'prod' - npm.prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - 'prod-dep': '^1.0.0', - chai: '^1.0.0', - }, - devDependencies: { - 'dev-dep': '^1.0.0', - }, - optionalDependencies: { - 'optional-dep': '^1.0.0', - }, - peerDependencies: { - 'peer-dep': '^1.0.0', - }, - }), - ...diffDepTypesNmFixture, - }) - await ls.exec([]) - t.matchSnapshot(redactCwd(result), 'should output tree containing only prod deps') - config.only = null + flatOptions.omit = [] }) t.test('--long', async t => { @@ -1484,12 +1428,12 @@ t.test('ls', t => { t.matchSnapshot(redactCwd(result), 'should list --all workspaces properly') // --production - config.production = true + flatOptions.omit = ['dev', 'peer', 'optional'] await ls.exec([]) t.matchSnapshot(redactCwd(result), 'should list only prod deps of workspaces') - config.production = false + flatOptions.omit = [] // filter out a single workspace using args await ls.exec(['d']) @@ -1811,7 +1755,7 @@ t.test('ls --parseable', t => { }) t.test('--dev', async t => { - config.dev = true + flatOptions.omit = ['peer', 'prod', 'optional'] npm.prefix = t.testdir({ 'package.json': JSON.stringify({ name: 'test-npm-ls', @@ -1834,34 +1778,7 @@ t.test('ls --parseable', t => { }) await ls.exec([]) t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps') - config.dev = false - }) - - t.test('--only=development', async t => { - config.only = 'development' - npm.prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - 'prod-dep': '^1.0.0', - chai: '^1.0.0', - }, - devDependencies: { - 'dev-dep': '^1.0.0', - }, - optionalDependencies: { - 'optional-dep': '^1.0.0', - }, - peerDependencies: { - 'peer-dep': '^1.0.0', - }, - }), - ...diffDepTypesNmFixture, - }) - await ls.exec([]) - t.matchSnapshot(redactCwd(result), 'should output tree containing only development deps') - config.only = null + flatOptions.omit = [] }) t.test('--link', async t => { @@ -1902,7 +1819,7 @@ t.test('ls --parseable', t => { }) t.test('--production', async t => { - config.production = true + flatOptions.omit = ['dev', 'peer'] npm.prefix = t.testdir({ 'package.json': JSON.stringify({ name: 'test-npm-ls', @@ -1925,34 +1842,7 @@ t.test('ls --parseable', t => { }) await ls.exec([]) t.matchSnapshot(redactCwd(result), 'should output tree containing production deps') - config.production = false - }) - - t.test('--only=prod', async t => { - config.only = 'prod' - npm.prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - 'prod-dep': '^1.0.0', - chai: '^1.0.0', - }, - devDependencies: { - 'dev-dep': '^1.0.0', - }, - optionalDependencies: { - 'optional-dep': '^1.0.0', - }, - peerDependencies: { - 'peer-dep': '^1.0.0', - }, - }), - ...diffDepTypesNmFixture, - }) - await ls.exec([]) - t.matchSnapshot(redactCwd(result), 'should output tree containing only prod deps') - config.only = null + flatOptions.omit = [] }) t.test('--long', async t => { @@ -2935,7 +2825,7 @@ t.test('ls --json', t => { }) t.test('--dev', async t => { - config.dev = true + flatOptions.omit = ['prod', 'optional', 'peer'] npm.prefix = t.testdir({ 'package.json': JSON.stringify({ name: 'test-npm-ls', @@ -2976,52 +2866,7 @@ t.test('ls --json', t => { }, 'should output json containing dev deps' ) - config.dev = false - }) - - t.test('--only=development', async t => { - config.only = 'development' - npm.prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - 'prod-dep': '^1.0.0', - chai: '^1.0.0', - }, - devDependencies: { - 'dev-dep': '^1.0.0', - }, - optionalDependencies: { - 'optional-dep': '^1.0.0', - }, - peerDependencies: { - 'peer-dep': '^1.0.0', - }, - }), - ...diffDepTypesNmFixture, - }) - await ls.exec([]) - t.same( - jsonParse(result), - { - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - 'dev-dep': { - version: '1.0.0', - dependencies: { - foo: { - version: '1.0.0', - dependencies: { dog: { version: '1.0.0' } }, - }, - }, - }, - }, - }, - 'should output json containing only development deps' - ) - config.only = null + flatOptions.omit = [] }) t.test('--link', async t => { @@ -3075,7 +2920,7 @@ t.test('ls --json', t => { }) t.test('--production', async t => { - config.production = true + flatOptions.omit = ['dev', 'peer'] npm.prefix = t.testdir({ 'package.json': JSON.stringify({ name: 'test-npm-ls', @@ -3110,46 +2955,7 @@ t.test('ls --json', t => { }, 'should output json containing production deps' ) - config.production = false - }) - - t.test('--only=prod', async t => { - config.only = 'prod' - npm.prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - 'prod-dep': '^1.0.0', - chai: '^1.0.0', - }, - devDependencies: { - 'dev-dep': '^1.0.0', - }, - optionalDependencies: { - 'optional-dep': '^1.0.0', - }, - peerDependencies: { - 'peer-dep': '^1.0.0', - }, - }), - ...diffDepTypesNmFixture, - }) - await ls.exec([]) - t.same( - jsonParse(result), - { - name: 'test-npm-ls', - version: '1.0.0', - dependencies: { - chai: { version: '1.0.0' }, - 'optional-dep': { version: '1.0.0' }, - 'prod-dep': { version: '1.0.0', dependencies: { dog: { version: '2.0.0' } } }, - }, - }, - 'should output json containing only prod deps' - ) - config.only = null + flatOptions.omit = [] }) t.test('from lockfile', async t => { diff --git a/test/lib/commands/outdated.js b/test/lib/commands/outdated.js index 3bf42b10a2601..14647ce6cef28 100644 --- a/test/lib/commands/outdated.js +++ b/test/lib/commands/outdated.js @@ -84,10 +84,6 @@ const globalDir = t.testdir({ }, }) -const flatOptions = { - workspacesEnabled: true, -} - const outdated = (dir, opts) => { logs = '' const Outdated = t.mock('../../../lib/commands/outdated.js', { @@ -95,11 +91,22 @@ const outdated = (dir, opts) => { packument, }, }) + if (opts.config && opts.config.omit) { + opts.flatOptions = { + omit: opts.config.omit, + ...opts.flatOptions, + } + delete opts.config.omit + } const npm = mockNpm({ ...opts, localPrefix: dir, prefix: dir, - flatOptions, + flatOptions: { + workspacesEnabled: true, + omit: [], + ...opts.flatOptions, + }, globalDir: `${globalDir}/node_modules`, output, }) @@ -529,14 +536,16 @@ t.test('workspaces', async t => { t.matchSnapshot(logs, 'should display ws outdated deps human output') t.equal(process.exitCode, 1) - flatOptions.workspacesEnabled = false - await outdated(testDir, {}).exec([]) + await outdated(testDir, { + flatOptions: { + workspacesEnabled: false, + }, + }).exec([]) // TODO: This should display dog, but doesn't because arborist filters // workspace deps even if they're also root deps // This will be fixed in a future arborist version t.matchSnapshot(logs, 'should display only root outdated when ws disabled') - flatOptions.workspacesEnabled = true await outdated(testDir, { config: { From 45869f48b9bb93c145c85cdc99dcd44adc6e3397 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 14:46:59 -0700 Subject: [PATCH 045/406] chore: remove deprecated configs from Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e280ecc9abf1e..670f31e9708f1 100644 --- a/Makefile +++ b/Makefile @@ -85,7 +85,7 @@ test-all: deps node bin/npm-cli.js run test-all ls-ok: - node bin/npm-cli.js ls --production >/dev/null + node bin/npm-cli.js ls --omit=dev >/dev/null gitclean: git clean -fd @@ -97,7 +97,7 @@ link: uninstall node bin/npm-cli.js link -f --ignore-scripts prune: deps - node bin/npm-cli.js prune --production --no-save --no-audit --no-fund + node bin/npm-cli.js prune --omit=dev --no-save --no-audit --no-fund node scripts/git-dirty.js publish: gitclean ls-ok link test-all docs prune From 974a4f8f10bec9a6090a9c39543903883472f79d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 00:27:13 +0000 Subject: [PATCH 046/406] chore(latest): release libnpmversion 3.0.3 --- workspaces/libnpmversion/CHANGELOG.md | 7 +++++++ workspaces/libnpmversion/package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmversion/CHANGELOG.md b/workspaces/libnpmversion/CHANGELOG.md index 83134e27efea9..2adb434e28653 100644 --- a/workspaces/libnpmversion/CHANGELOG.md +++ b/workspaces/libnpmversion/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [3.0.3](https://github.com/npm/cli/compare/libnpmversion-v3.0.2...libnpmversion-v3.0.3) (2022-04-12) + + +### Dependencies + +* remove stringify-package ([#4714](https://github.com/npm/cli/issues/4714)) ([e33aa0f](https://github.com/npm/cli/commit/e33aa0f94f87ae4f9d2a73781e84832ef61d1855)) + ### [3.0.2](https://github.com/npm/cli/compare/libnpmversion-v3.0.1...libnpmversion-v3.0.2) (2022-04-06) diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index f75d73c3ee6f3..431587f07c4c5 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -1,6 +1,6 @@ { "name": "libnpmversion", - "version": "3.0.2", + "version": "3.0.3", "main": "lib/index.js", "files": [ "bin/", From 970244c415da91b98ca3b200d88c1206ba81d774 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Tue, 12 Apr 2022 00:27:43 +0000 Subject: [PATCH 047/406] deps: libnpmversion@3.0.3 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 5138eee431c5d..f256b3a2245eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9995,7 +9995,7 @@ } }, "workspaces/libnpmversion": { - "version": "3.0.2", + "version": "3.0.3", "license": "ISC", "dependencies": { "@npmcli/git": "^3.0.0", From 4a0e005ffbc08b1dd51c625355f19307455f37e4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Apr 2022 21:36:25 +0000 Subject: [PATCH 048/406] chore(latest): release arborist 5.0.6 --- workspaces/arborist/CHANGELOG.md | 8 ++++++++ workspaces/arborist/package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/workspaces/arborist/CHANGELOG.md b/workspaces/arborist/CHANGELOG.md index e254d8f2606e8..2bc09164227ad 100644 --- a/workspaces/arborist/CHANGELOG.md +++ b/workspaces/arborist/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +### [5.0.6](https://github.com/npm/cli/compare/arborist-v5.0.5...arborist-v5.0.6) (2022-04-13) + + +### Bug Fixes + +* **arborist:** dont skip adding advisories to audit based on name/range ([aa4a4da](https://github.com/npm/cli/commit/aa4a4da336a6ec1963394fdbd06acb173c842d26)), closes [#4681](https://github.com/npm/cli/issues/4681) +* **arborist:** when reloading an edge, also refresh overrides ([4d676e3](https://github.com/npm/cli/commit/4d676e31a68f081b8553eff4e79db1f29acf47e1)) + ### [5.0.5](https://github.com/npm/cli/compare/arborist-v5.0.4...arborist-v5.0.5) (2022-04-06) diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index a936a3b01d96f..01e3db329ad50 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "5.0.5", + "version": "5.0.6", "description": "Manage node_modules trees", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", From 42dc0b03d60dc27602dab26a2f8cbfc17bf4ab40 Mon Sep 17 00:00:00 2001 From: npm cli ops bot Date: Wed, 13 Apr 2022 21:36:59 +0000 Subject: [PATCH 049/406] deps: @npmcli/arborist@5.0.6 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index f256b3a2245eb..c7462cbe8caf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9748,7 +9748,7 @@ }, "workspaces/arborist": { "name": "@npmcli/arborist", - "version": "5.0.5", + "version": "5.0.6", "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", From 6b5c7dfd206a933e8d5215ee77d77327d7c542eb Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 17:12:27 -0700 Subject: [PATCH 050/406] chore: fix reading latest release from changelog --- scripts/changelog.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/changelog.js b/scripts/changelog.js index 3db16d6cab08c..f91e28d5a6e6f 100644 --- a/scripts/changelog.js +++ b/scripts/changelog.js @@ -177,13 +177,13 @@ const findRelease = (args, version) => { RELEASE.heading, v ? escRegExp(v) : RELEASE.versionRe, ' ', - escRegExp(RELEASE.date()).replace(/\d/g, '\\d'), + escRegExp(RELEASE.date(today())).replace(/\d/g, '\\d'), '$', ].join('') const releaseSrc = [ '(', - titleSrc(RELEASE.version(version)), + titleSrc(version && RELEASE.version(version)), '[\\s\\S]*?', RELEASE.sep, ')', @@ -366,11 +366,11 @@ const main = async (argv) => { if (args.read) { // this reads the release notes for that version - let { release } = findRelease(args, args.endTag || args.startTag) + let { release } = findRelease(args, args.tag) if (args.type === 'gh') { // changelog was written in markdown so convert user links to gh release style // XXX: this needs to be changed if the `generateRelease` format changes - release = release.replace(/\(\[(@[a-z\d-]+)\]\(https:\/\/github.com\/[a-z\d-]+\)\)/g, '($1)') + release = release.replace(/\(\[(@[a-z\d-]+)\]\(https:\/\/github.com\/[a-z\d-]+\)\)/gi, '($1)') } return console.log(release) } From ec065b22bd61343a6240c386d66f83a8325774d1 Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 14 Apr 2022 10:59:24 -0700 Subject: [PATCH 051/406] chore: fix Makefile for building markdown docs --- Makefile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 670f31e9708f1..f52f2795b5c85 100644 --- a/Makefile +++ b/Makefile @@ -73,13 +73,22 @@ man/man7/%.7: docs/content/using-npm/%.md docs/bin/docs-build.js docs/content/using-npm/config.md: docs/bin/config-doc.js lib/utils/config/*.js node docs/bin/config-doc.js -docs/content/commands/npm-%.md: docs/bin/config-doc-command.js lib/commands/%.js lib/utils/config/*.js lib/utils/cmd-list.js +mddocs: docs/bin/config-doc-command.js lib/utils/config/*.js lib/utils/cmd-list.js + @for file in $(shell find docs/content/commands -name 'npm-*.md'); do \ + cmdname=$$(basename $$file .md) ;\ + cmdname=$${cmdname##npm-} ;\ + echo node docs/bin/config-doc-command.js $${file} lib/commands/$${cmdname}.js ;\ + node docs/bin/config-doc-command.js $${file} lib/commands/$${cmdname}.js ;\ + done + +docs/content/commands/npm-%.md: lib/commands/%.js node docs/bin/config-doc-command.js $@ $< freshdocs: touch lib/utils/config/definitions.js touch docs/bin/*.js make docs + make mddocs test-all: deps node bin/npm-cli.js run test-all @@ -108,4 +117,4 @@ publish: gitclean ls-ok link test-all docs prune release: gitclean ls-ok docs prune @bash scripts/release.sh -.PHONY: all latest install dev link docs clean uninstall test-all man docsclean release ls-ok deps prune freshdocs +.PHONY: all latest install dev link docs mddocs clean uninstall test-all man docsclean release ls-ok deps prune freshdocs From 1f9eabac4bb19671a5d508be4b5cc54c9c83ac66 Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 14 Apr 2022 11:12:13 -0700 Subject: [PATCH 052/406] chore: make sure to build markdown docs for all commands as part of the docs target --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f52f2795b5c85..72b285359e776 100644 --- a/Makefile +++ b/Makefile @@ -24,9 +24,11 @@ misc_mandocs = $(shell find docs/content/using-npm -name '*.md' \ mandocs = $(cli_mandocs) $(files_mandocs) $(misc_mandocs) +markdown_docs = $(shell for file in $(find lib/commands -name '*.js'); do echo docs/content/commands/npm-$(basename $file .js).md; done) + all: docs -docs: mandocs htmldocs +docs: mandocs htmldocs $(markdown_docs) # don't regenerate the snapshot if we're generating # snapshots, since presumably we just did that. From 91741ee7274658d5867505f1dea34ae81233876d Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 17:39:11 -0700 Subject: [PATCH 053/406] chore: increase smoke test timeout --- smoke-tests/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/smoke-tests/package.json b/smoke-tests/package.json index f8d1ffd0b9de8..787db4d203502 100644 --- a/smoke-tests/package.json +++ b/smoke-tests/package.json @@ -37,6 +37,7 @@ }, "tap": { "no-coverage": true, + "timeout": 300, "files": "test/index.js" }, "files": [ From ac761fb52a5c72042299821b24ade28711bbd415 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 17:15:38 -0700 Subject: [PATCH 054/406] chore: changelog for v8.7.0 --- CHANGELOG.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64794ff1c9821..ee70bdb4dafa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,76 @@ # Changelog +## v8.7.0 (2022-04-13) + +### Features + + * [`6611e91`](https://github.com/npm/cli/commit/6611e9147f1726ab4537a7fe3b9e3beb6728f700) [#4723](https://github.com/npm/cli/pull/4723) feat(config): add more npm/node information to config ls ([@lukekarrys](https://github.com/lukekarrys)) + * [`c057b90`](https://github.com/npm/cli/commit/c057b90d0954ff5b6f2973748ae5d41885b99213) [#4740](https://github.com/npm/cli/pull/4740) feat(config): warn on deprecated configs ([@lukekarrys](https://github.com/lukekarrys)) + +### Bug Fixes + + * [`2829cb2`](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d) [#4658](https://github.com/npm/cli/pull/4658) fix: update readme badges ([@lukekarrys](https://github.com/lukekarrys)) + * [`e3da5df`](https://github.com/npm/cli/commit/e3da5df4152fbe547f7871547165328e1bf06262) [#4667](https://github.com/npm/cli/pull/4667) fix: replace deprecated String.prototype.substr() ([@CommanderRoot](https://github.com/CommanderRoot)) + * [`2a26e5e`](https://github.com/npm/cli/commit/2a26e5e21af788f025a5731d88f15f6dc88b4c0c) [#4645](https://github.com/npm/cli/pull/4645) fix: remove dedupe --save ([@wraithgar](https://github.com/wraithgar)) + * [`47438ff`](https://github.com/npm/cli/commit/47438ff19f4b6e84a0325ed73b97999ce34bc789) [#4645](https://github.com/npm/cli/pull/4645) fix: do not export npm_config_include_workspace_root ([@wraithgar](https://github.com/wraithgar)) + * [`840c338`](https://github.com/npm/cli/commit/840c338aa6aba7dc39d9d3afba075701e3979362) [#4678](https://github.com/npm/cli/pull/4678) fix(run-script): don't cascade if-present config ([@ruyadorno](https://github.com/ruyadorno)) + * [`4d676e3`](https://github.com/npm/cli/commit/4d676e31a68f081b8553eff4e79db1f29acf47e1) [#4709](https://github.com/npm/cli/pull/4709) fix(arborist): when reloading an edge, also refresh overrides ([@nlf](https://github.com/nlf)) + * [`3f7fe17`](https://github.com/npm/cli/commit/3f7fe17d1ea743b3ce1f27b9156e9fa0e358a7df) [#4659](https://github.com/npm/cli/pull/4659) fix: skip update notifier file if not requested ([@lukekarrys](https://github.com/lukekarrys)) + * [`5ba7f0c`](https://github.com/npm/cli/commit/5ba7f0cef753d4af0bc02ca7d6dd0ac1bdd11ffe) [#4726](https://github.com/npm/cli/pull/4726) fix: show more information during publish dry-run ([@lukekarrys](https://github.com/lukekarrys)) + * [`aa4a4da`](https://github.com/npm/cli/commit/aa4a4da336a6ec1963394fdbd06acb173c842d26) [#4735](https://github.com/npm/cli/pull/4735) fix(arborist): dont skip adding advisories to audit based on name/range ([@lukekarrys](https://github.com/lukekarrys)) + * [`0cd852f`](https://github.com/npm/cli/commit/0cd852f62e1453e647a2551e98c78ce7e0c8ea03) [#4741](https://github.com/npm/cli/pull/4741) fix: mitigate doctor test race condition ([@wraithgar](https://github.com/wraithgar)) + * [`ba8b2a7`](https://github.com/npm/cli/commit/ba8b2a753d63c8a8c7a44a48c2e13626b12025fe) [#4744](https://github.com/npm/cli/pull/4744) fix(ls): make `--omit` filter `npm ls` ([@lukekarrys](https://github.com/lukekarrys)) + +### Documentation + + * [`85b3c48`](https://github.com/npm/cli/commit/85b3c48d2c9bc4199aed699cc4c00ac96c5feebd) [#4666](https://github.com/npm/cli/pull/4666) docs(ci): add note that configuration must be consistent between install and ci ([@nlf](https://github.com/nlf)) + * [`44108f7`](https://github.com/npm/cli/commit/44108f7be5e1e928d8aa3eda3c5c177bcd216c99) [#4670](https://github.com/npm/cli/pull/4670) docs: fix npm-uninstall typo ([@JSKitty](https://github.com/JSKitty)) + +### Dependencies + + * [`aaf86f6`](https://github.com/npm/cli/commit/aaf86f61836c45b254794785f0a2e8f43dc38800) [#4674](https://github.com/npm/cli/pull/4674) deps: `@npmcli/metavuln-calculator@3.1.0` + * [`4a9a705`](https://github.com/npm/cli/commit/4a9a705de6992a3e9eefecc6c0cf8da45a527c7a) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/package-json@2.0.0` + * [`1a90b9e`](https://github.com/npm/cli/commit/1a90b9e9ebe98cce83591e11312aaf41c830f835) [#4691](https://github.com/npm/cli/pull/4691) deps: `treeverse@2.0.0` + * [`f86f1af`](https://github.com/npm/cli/commit/f86f1af636f39d7d30a97873bbb6652416f68013) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/disparity-colors@2.0.0` + * [`3a76dff`](https://github.com/npm/cli/commit/3a76dff3f49af9688a44a508d956f2091363b66d) [#4691](https://github.com/npm/cli/pull/4691) deps: `make-fetch-happen@10.1.2` + * [`0230428`](https://github.com/npm/cli/commit/02304284ddd147e604835a000d3a28a2deb65702) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/config@4.0.2` + * [`82dc75f`](https://github.com/npm/cli/commit/82dc75fe62466714ea59accf245a6f9d6d111e17) [#4691](https://github.com/npm/cli/pull/4691) deps: `npm-pick-manifest@7.0.1` + * [`ad99360`](https://github.com/npm/cli/commit/ad9936063f20829eb9d5358d056593883f17a57b) [#4691](https://github.com/npm/cli/pull/4691) deps: `npm-install-checks@5.0.0` + * [`79fc706`](https://github.com/npm/cli/commit/79fc706f9c389a17ba50dd8835223160b8b0c3fb) [#4691](https://github.com/npm/cli/pull/4691) deps: `bin-links@3.0.1` + * [`1f2fb1e`](https://github.com/npm/cli/commit/1f2fb1e07b752ee34867c271a0fd1f186397d8ec) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/git@3.0.1` + * [`0f23c33`](https://github.com/npm/cli/commit/0f23c3378c991b2a482463ce7f700829a3752940) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/run-script@3.0.2` + * [`485753d`](https://github.com/npm/cli/commit/485753df44e66921dcb593e1bcbb39de79c6dc11) [#4691](https://github.com/npm/cli/pull/4691) deps: `cacache@16.0.4` + * [`e9b25cd`](https://github.com/npm/cli/commit/e9b25cd66bef17e807a84e7b10384f5f4d0064b7) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/move-file@2.0.0` + * [`0e87cac`](https://github.com/npm/cli/commit/0e87cac8b6f09692f6bd1bf086aadbe323d127b5) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/node-gyp@2.0.0` + * [`b632746`](https://github.com/npm/cli/commit/b632746b99121b5a271c75b985a849dfd75b6c57) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/promise-spawn@3.0.0` + * [`b1863bf`](https://github.com/npm/cli/commit/b1863bf87adeb6deec83869f0f7bb1df4a5731ef) [#4691](https://github.com/npm/cli/pull/4691) deps: `pacote@13.1.1` + * [`a2781a3`](https://github.com/npm/cli/commit/a2781a367d62328d7f870de878f1b63d66593f4f) [#4691](https://github.com/npm/cli/pull/4691) deps: `ssri@9.0.0` + * [`5172e03`](https://github.com/npm/cli/commit/5172e03a572c99159568861049e4c2a536922f50) [#4691](https://github.com/npm/cli/pull/4691) deps: `ini@3.0.0` + * [`71296d5`](https://github.com/npm/cli/commit/71296d5ca4ace5805e1061c1a58878939c1c32f3) [#4691](https://github.com/npm/cli/pull/4691) deps: `npm-package-arg@9.0.2` + * [`69d8343`](https://github.com/npm/cli/commit/69d834319a9d668bd451600ab6e124a8819b284d) [#4691](https://github.com/npm/cli/pull/4691) deps: `graceful-fs@4.2.10` + * [`c44c2b0`](https://github.com/npm/cli/commit/c44c2b02920854897ba7a663ef705b9b474c2250) [#4691](https://github.com/npm/cli/pull/4691) deps: `lru-cache@7.7.3` + * [`38029ed`](https://github.com/npm/cli/commit/38029edea846ffe81768d7073d4ec09a4b129c24) [#4691](https://github.com/npm/cli/pull/4691) deps: `dezalgo@1.0.4` + * [`e57353c`](https://github.com/npm/cli/commit/e57353c78e798afbd3eb4390a42da5d5076be45d) [#4691](https://github.com/npm/cli/pull/4691) deps: `semver@7.3.6` + * [`1b30c72`](https://github.com/npm/cli/commit/1b30c725ecd0f03f55e3c0576962972748eec238) [#4691](https://github.com/npm/cli/pull/4691) deps: `minimatch@5.0.1` + * [`c70232c`](https://github.com/npm/cli/commit/c70232cc12fd9b3b024c2c759edd708af2367b8d) [#4706](https://github.com/npm/cli/pull/4706) deps: `@npmcli/arborist@5.0.5` + * [`baff482`](https://github.com/npm/cli/commit/baff4828f733efee0a569e00f87d25f06f2b384b) [#4705](https://github.com/npm/cli/pull/4705) deps: `libnpmdiff@4.0.3` + * [`dda8a97`](https://github.com/npm/cli/commit/dda8a976a9dd696cf2b2e2be5b55b2048e768768) [#4704](https://github.com/npm/cli/pull/4704) deps: `libnpmorg@4.0.3` + * [`8914864`](https://github.com/npm/cli/commit/891486451f1c34a2e7649b0a76c6c0d611ce3d39) [#4703](https://github.com/npm/cli/pull/4703) deps: `libnpmaccess@6.0.3` + * [`3516f61`](https://github.com/npm/cli/commit/3516f61e415d9ce6e9b00378c45791e33bb99fc9) [#4702](https://github.com/npm/cli/pull/4702) deps: `libnpmfund@3.0.2` + * [`ecd22b0`](https://github.com/npm/cli/commit/ecd22b07af515d86b77248e6a4cc2dec57bafd50) [#4701](https://github.com/npm/cli/pull/4701) deps: `libnpmversion@3.0.2` + * [`7ed9faf`](https://github.com/npm/cli/commit/7ed9fafaa951071a7988a3ec4ca3a5e01756b11d) [#4700](https://github.com/npm/cli/pull/4700) deps: `libnpmhook@8.0.3` + * [`df92e23`](https://github.com/npm/cli/commit/df92e23af63ca07bb4c261abd7365530529d3fd2) [#4699](https://github.com/npm/cli/pull/4699) deps: `libnpmexec@4.0.3` + * [`5074adc`](https://github.com/npm/cli/commit/5074adc5e17d1b0ec753cde3b7efd96c2fc7c4a3) [#4698](https://github.com/npm/cli/pull/4698) deps: `libnpmsearch@5.0.3` + * [`35e5100`](https://github.com/npm/cli/commit/35e5100e287925d19df4aab98de96cf70a6ff5a6) [#4697](https://github.com/npm/cli/pull/4697) deps: `libnpmteam@4.0.3` + * [`86f5b27`](https://github.com/npm/cli/commit/86f5b273fc57118b8b1a5e53ec3ca49d94d81601) [#4696](https://github.com/npm/cli/pull/4696) deps: `libnpmpack@4.0.3` + * [`1617bce`](https://github.com/npm/cli/commit/1617bce61663a743435d162b003d3b99376d426f) [#4695](https://github.com/npm/cli/pull/4695) deps: `libnpmpublish@6.0.3` + * [`e33aa0f`](https://github.com/npm/cli/commit/e33aa0f94f87ae4f9d2a73781e84832ef61d1855) [#4714](https://github.com/npm/cli/pull/4714) deps: remove stringify-package + * [`98377d1`](https://github.com/npm/cli/commit/98377d159f72a5b6073f07235b057984eb09a85c) [#4740](https://github.com/npm/cli/pull/4740) deps: `@npmcli/config@4.1.0` + * [`605ccef`](https://github.com/npm/cli/commit/605ccef6916c170f6d0c53775614f8a02682262a) [#4728](https://github.com/npm/cli/pull/4728) deps: remove ansistyles + * [`c22fb1e`](https://github.com/npm/cli/commit/c22fb1e756d43b54fefd826f2c3f459d4f1204b5) [#4728](https://github.com/npm/cli/pull/4728) deps: remove ansicolors + * [`970244c`](https://github.com/npm/cli/commit/970244c415da91b98ca3b200d88c1206ba81d774) [#4734](https://github.com/npm/cli/pull/4734) deps: `libnpmversion@3.0.3` + * [`42dc0b0`](https://github.com/npm/cli/commit/42dc0b03d60dc27602dab26a2f8cbfc17bf4ab40) [#4733](https://github.com/npm/cli/pull/4733) deps: `@npmcli/arborist@5.0.6` + ## v8.6.0 (2022-03-31) ### Features From 8731990de16b8ff1c856a6c1066d15bc0cbd2f76 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 17:16:41 -0700 Subject: [PATCH 055/406] chore: update AUTHORS --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index c2e8eb2172f17..5e7c0c9ad8e6c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -827,3 +827,6 @@ Wassim Chegham <1699357+manekinekko@users.noreply.github.com> David Chin David Walker Boris Verkhovskiy +JSKitty +CommanderRoot +npm cli ops bot From 7c4ee929a8d7e0c6a55a974db280d8eeb10d279e Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 17:16:41 -0700 Subject: [PATCH 056/406] 8.7.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 c7462cbe8caf4..066fe2f4191b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "npm", - "version": "8.6.0", + "version": "8.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "npm", - "version": "8.6.0", + "version": "8.7.0", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", diff --git a/package.json b/package.json index 44e5beca0a121..da2cba63e220a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "8.6.0", + "version": "8.7.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ From d75ed474b4ed5bcf259936d29aa3a9937800010d Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 13 Apr 2022 18:21:36 -0700 Subject: [PATCH 057/406] chore: fix benchmark script syntax You cannot use a secret as part of an if expression in actions --- .github/workflows/benchmark.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index c97619e1e60aa..1d8e3455c25e3 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -15,18 +15,25 @@ jobs: steps: - name: Incoming Pull Request if: | - secrets.NPM_BENCHMARKS_TOKEN && ( - github.event_name == 'pull_request' || - (github.event_name == 'issue_comment' && github.event.issue.pull_request && - startsWith(github.event.comment.body, 'test this please ✅'))) + github.event_name == 'pull_request' || ( + github.event_name == 'issue_comment' && + github.event.issue.pull_request && + startsWith(github.event.comment.body, 'test this please ✅') + ) env: # gh cli uses these env vars for owner/repo/token GH_REPO: "npm/benchmarks" GITHUB_TOKEN: ${{ secrets.NPM_BENCHMARKS_TOKEN }} run: | + if [[ "$GITHUB_TOKEN" == "" ]]; then + echo "No auth - from fork pull request, exiting" + exit 0 + fi + EVENT_NAME="${{ github.event_name }}" OWNER="${{ github.event.repository.owner.login }}" REPO="${{ github.event.repository.name }}" + PR="" if [[ "$EVENT_NAME" == "pull_request" ]]; then PR="${{ github.event.pull_request.number }}" @@ -49,7 +56,6 @@ jobs: steps: - name: Incoming Comment if: | - secrets.NPM_BENCHMARKS_TOKEN && github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, 'test this please ✅') From b10462ed156ada4d4ad90e6cf613e292a9361a87 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 14 Apr 2022 08:59:10 -0700 Subject: [PATCH 058/406] fix: deprecate completion Found a bug refactoring the tests. libnpmaccess mutates the response from the server, and the completion code was not looking for the right value. --- lib/commands/deprecate.js | 2 +- test/fixtures/mock-registry.js | 21 ++-- test/lib/commands/deprecate.js | 177 ++++++++++++++++++--------------- test/lib/commands/unpublish.js | 38 +++---- 4 files changed, 131 insertions(+), 107 deletions(-) diff --git a/lib/commands/deprecate.js b/lib/commands/deprecate.js index 88eb320c32a52..0ae88f1921f56 100644 --- a/lib/commands/deprecate.js +++ b/lib/commands/deprecate.js @@ -26,7 +26,7 @@ class Deprecate extends BaseCommand { const packages = await libaccess.lsPackages(username, this.npm.flatOptions) return Object.keys(packages) .filter((name) => - packages[name] === 'write' && + packages[name] === 'read-write' && (opts.conf.argv.remain.length === 0 || name.startsWith(opts.conf.argv.remain[0]))) } diff --git a/test/fixtures/mock-registry.js b/test/fixtures/mock-registry.js index 6b6722fcbbc3c..8b847213f33a7 100644 --- a/test/fixtures/mock-registry.js +++ b/test/fixtures/mock-registry.js @@ -40,8 +40,12 @@ class MockRegistry { this.#nock = nock } - whoami ({ username }) { - this.nock = this.nock.get('/-/whoami').reply(200, { username }) + whoami ({ username, body, responseCode = 200, times = 1 }) { + if (username) { + this.nock = this.nock.get('/-/whoami').times(times).reply(responseCode, { username }) + } else { + this.nock = this.nock.get('/-/whoami').times(times).reply(responseCode, body) + } } access ({ spec, access, publishRequires2fa }) { @@ -108,7 +112,7 @@ class MockRegistry { } // team can be a team or a username - lsPackages ({ team, packages = {} }) { + lsPackages ({ team, packages = {}, times = 1 }) { if (team.startsWith('@')) { team = team.slice(1) } @@ -119,7 +123,7 @@ class MockRegistry { } else { uri = `/-/org/${encodeURIComponent(scope)}/package` } - this.nock = this.nock.get(uri).query({ format: 'cli' }).reply(200, packages) + this.nock = this.nock.get(uri).query({ format: 'cli' }).times(times).reply(200, packages) } lsCollaborators ({ spec, user, collaborators = {} }) { @@ -169,8 +173,10 @@ class MockRegistry { this.nock = nock } - // the last packument in the packuments array will be tagged as latest - manifest ({ name = 'test-package', packuments } = {}) { + // either pass in packuments if you need to set specific attributes besides version, + // or an array of versions + // the last packument in the packuments or versions array will be tagged latest + manifest ({ name = 'test-package', packuments, versions } = {}) { packuments = this.packuments(packuments, name) const latest = packuments.slice(-1)[0] const manifest = { @@ -184,6 +190,9 @@ class MockRegistry { 'dist-tags': { latest: latest.version }, ...latest, } + if (versions) { + packuments = versions.map(version => ({ version })) + } for (const packument of packuments) { manifest.versions[packument.version] = { diff --git a/test/lib/commands/deprecate.js b/test/lib/commands/deprecate.js index 37a407c3b6a1a..03177cb7be0b9 100644 --- a/test/lib/commands/deprecate.js +++ b/test/lib/commands/deprecate.js @@ -1,137 +1,152 @@ const t = require('tap') +const { load: loadMockNpm } = require('../../fixtures/mock-npm') -let getIdentityImpl = () => 'someperson' -let npmFetchBody = null +const MockRegistry = require('../../fixtures/mock-registry.js') -const npmFetch = async (uri, opts) => { - npmFetchBody = opts.body -} +const user = 'test-user' +const token = 'test-auth-token' +const auth = { '//registry.npmjs.org/:_authToken': token } +const versions = ['1.0.0', '1.0.1', '1.0.1-pre'] -npmFetch.json = async (uri, opts) => { - return { - versions: { - '1.0.0': {}, - '1.0.1': {}, - '1.0.1-pre': {}, - }, - } -} - -const Deprecate = t.mock('../../../lib/commands/deprecate.js', { - '../../../lib/utils/get-identity.js': async () => getIdentityImpl(), - libnpmaccess: { - lsPackages: async () => ({ foo: 'write', bar: 'write', baz: 'write', buzz: 'read' }), - }, - 'npm-registry-fetch': npmFetch, -}) - -const deprecate = new Deprecate({ - flatOptions: { registry: 'https://registry.npmjs.org' }, -}) +// libnpmaccess maps these to read-write and read-only +const packages = { foo: 'write', bar: 'write', baz: 'write', buzz: 'read' } t.test('completion', async t => { - const defaultIdentityImpl = getIdentityImpl - t.teardown(() => { - getIdentityImpl = defaultIdentityImpl + const { npm } = await loadMockNpm(t, { + config: { + ...auth, + }, }) + const deprecate = await npm.cmd('deprecate') const testComp = async (argv, expect) => { const res = await deprecate.completion({ conf: { argv: { remain: argv } } }) t.strictSame(res, expect, `completion: ${argv}`) } + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + + registry.whoami({ username: user, times: 4 }) + registry.lsPackages({ team: user, packages, times: 4 }) await Promise.all([ testComp([], ['foo', 'bar', 'baz']), testComp(['b'], ['bar', 'baz']), testComp(['fo'], ['foo']), testComp(['g'], []), - testComp(['foo', 'something'], []), ]) - getIdentityImpl = () => { - throw new Error('deprecate test failure') - } + await testComp(['foo', 'something'], []) + + registry.whoami({ statusCode: 404, body: {} }) - t.rejects(testComp([], []), { message: 'deprecate test failure' }) + t.rejects(testComp([], []), { code: 'ENEEDAUTH' }) }) t.test('no args', async t => { + const { npm } = await loadMockNpm(t) await t.rejects( - deprecate.exec([]), - /Usage:/, + npm.exec('deprecate', []), + { code: 'EUSAGE' }, 'logs usage' ) }) t.test('only one arg', async t => { + const { npm } = await loadMockNpm(t) await t.rejects( - deprecate.exec(['foo']), - /Usage:/, + npm.exec('deprecate', ['foo']), + { code: 'EUSAGE' }, 'logs usage' ) }) t.test('invalid semver range', async t => { + const { npm } = await loadMockNpm(t) await t.rejects( - deprecate.exec(['foo@notaversion', 'this will fail']), + npm.exec('deprecate', ['foo@notaversion', 'this will fail']), /invalid version range/, 'logs semver error' ) }) t.test('undeprecate', async t => { - t.teardown(() => { - npmFetchBody = null + const { npm, joinedOutput } = await loadMockNpm(t, { config: { ...auth } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, }) - await deprecate.exec(['foo', '']) - t.match(npmFetchBody, { - versions: { - '1.0.0': { deprecated: '' }, - '1.0.1': { deprecated: '' }, - '1.0.1-pre': { deprecated: '' }, - }, - }, 'undeprecates everything') + const manifest = registry.manifest({ + name: 'foo', + versions, + }) + registry.package({ manifest, query: { write: true } }) + registry.nock.put('/foo', body => { + for (const version of versions) { + if (body.versions[version].deprecated !== '') { + return false + } + } + return true + }).reply(200, {}) + + await npm.exec('deprecate', ['foo', '']) + t.match(joinedOutput(), '') }) t.test('deprecates given range', async t => { - t.teardown(() => { - npmFetchBody = null + const { npm, joinedOutput } = await loadMockNpm(t, { config: { ...auth } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, }) - - await deprecate.exec(['foo@1.0.0', 'this version is deprecated']) - t.match(npmFetchBody, { - versions: { - '1.0.0': { - deprecated: 'this version is deprecated', - }, - '1.0.1': { - // the undefined here is necessary to ensure that we absolutely - // did not assign this property - deprecated: undefined, - }, - }, + const manifest = registry.manifest({ + name: 'foo', + versions, }) + registry.package({ manifest, query: { write: true } }) + const message = 'test deprecation message' + registry.nock.put('/foo', body => { + if (body.versions['1.0.1'].deprecated) { + return false + } + if (body.versions['1.0.1-pre'].deprecated) { + return false + } + return body.versions['1.0.0'].deprecated === message + }).reply(200, {}) + await npm.exec('deprecate', ['foo@1.0.0', message]) + t.match(joinedOutput(), '') }) t.test('deprecates all versions when no range is specified', async t => { - t.teardown(() => { - npmFetchBody = null + const { npm, joinedOutput } = await loadMockNpm(t, { config: { ...auth } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, }) - - await deprecate.exec(['foo', 'this version is deprecated']) - - t.match(npmFetchBody, { - versions: { - '1.0.0': { - deprecated: 'this version is deprecated', - }, - '1.0.1': { - deprecated: 'this version is deprecated', - }, - '1.0.1-pre': { - deprecated: 'this version is deprecated', - }, - }, + const manifest = registry.manifest({ + name: 'foo', + versions, }) + registry.package({ manifest, query: { write: true } }) + const message = 'test deprecation message' + registry.nock.put('/foo', body => { + for (const version of versions) { + if (body.versions[version].deprecated !== message) { + return false + } + } + return true + }).reply(200, {}) + + await npm.exec('deprecate', ['foo', message]) + t.match(joinedOutput(), '') }) diff --git a/test/lib/commands/unpublish.js b/test/lib/commands/unpublish.js index 829d41c5bb875..28f93ea3e77a4 100644 --- a/test/lib/commands/unpublish.js +++ b/test/lib/commands/unpublish.js @@ -423,8 +423,8 @@ t.test('completion', async t => { packuments: ['1.0.0', '1.0.1'], }) await registry.package({ manifest, query: { write: true } }) - registry.nock.get('/-/whoami').reply(200, { username: user }) - .get('/-/org/test-user/package?format=cli').reply(200, { [pkg]: 'write' }) + registry.whoami({ username: user }) + registry.nock.get('/-/org/test-user/package?format=cli').reply(200, { [pkg]: 'write' }) await testComp(t, { argv: ['npm', 'unpublish'], @@ -445,8 +445,8 @@ t.test('completion', async t => { const manifest = registry.manifest({ name: pkg }) manifest.versions = {} await registry.package({ manifest, query: { write: true } }) - registry.nock.get('/-/whoami').reply(200, { username: user }) - .get('/-/org/test-user/package?format=cli').reply(200, { [pkg]: 'write' }) + registry.whoami({ username: user }) + registry.nock.get('/-/org/test-user/package?format=cli').reply(200, { [pkg]: 'write' }) await testComp(t, { argv: ['npm', 'unpublish'], @@ -464,12 +464,12 @@ t.test('completion', async t => { registry: npm.config.get('registry'), authorization: 'test-auth-token', }) - registry.nock.get('/-/whoami').reply(200, { username: user }) - .get('/-/org/test-user/package?format=cli').reply(200, { - [pkg]: 'write', - [`${pkg}a`]: 'write', - [`${pkg}b`]: 'write', - }) + registry.whoami({ username: user }) + registry.nock.get('/-/org/test-user/package?format=cli').reply(200, { + [pkg]: 'write', + [`${pkg}a`]: 'write', + [`${pkg}b`]: 'write', + }) await testComp(t, { argv: ['npm', 'unpublish'], @@ -488,7 +488,7 @@ t.test('completion', async t => { registry: npm.config.get('registry'), authorization: 'test-auth-token', }) - registry.nock.get('/-/whoami').reply(200, { username: user }) + registry.whoami({ username: user }) registry.nock.get('/-/org/test-user/package?format=cli').reply(200, {}) await testComp(t, { @@ -505,11 +505,11 @@ t.test('completion', async t => { registry: npm.config.get('registry'), authorization: 'test-auth-token', }) - registry.nock.get('/-/whoami').reply(200, { username: user }) - .get('/-/org/test-user/package?format=cli').reply(200, { - [pkg]: 'write', - [`${pkg}a`]: 'write', - }) + registry.whoami({ username: user }) + registry.nock.get('/-/org/test-user/package?format=cli').reply(200, { + [pkg]: 'write', + [`${pkg}a`]: 'write', + }) await testComp(t, { argv: ['npm', 'unpublish'], @@ -525,8 +525,8 @@ t.test('completion', async t => { registry: npm.config.get('registry'), authorization: 'test-auth-token', }) - registry.nock.get('/-/whoami').reply(200, { username: user }) - .get('/-/org/test-user/package?format=cli').reply(200, null) + registry.whoami({ username: user }) + registry.nock.get('/-/org/test-user/package?format=cli').reply(200, null) await testComp(t, { argv: ['npm', 'unpublish'], @@ -542,7 +542,7 @@ t.test('completion', async t => { registry: npm.config.get('registry'), authorization: 'test-auth-token', }) - registry.nock.get('/-/whoami').reply(404) + registry.whoami({ responseCode: 404 }) await testComp(t, { argv: ['npm', 'unpublish'], From f1787327c86028f1276683cf331a8536d62108ce Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 14 Apr 2022 14:17:21 -0700 Subject: [PATCH 059/406] chore: update DEPENDENCIES.md 3 deps are gone now, and there's a new workspace --- DEPENDENCIES.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 61803e40853f8..aa9c47d453448 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -76,7 +76,6 @@ graph LR; libnpmversion-->npmcli-template-oss["@npmcli/template-oss"]; libnpmversion-->proc-log; libnpmversion-->semver; - libnpmversion-->stringify-package; make-fetch-happen-->cacache; make-fetch-happen-->minipass-fetch; make-fetch-happen-->ssri; @@ -405,7 +404,6 @@ graph LR; libnpmversion-->proc-log; libnpmversion-->require-inject; libnpmversion-->semver; - libnpmversion-->stringify-package; libnpmversion-->tap; make-fetch-happen-->agentkeepalive; make-fetch-happen-->cacache; @@ -456,8 +454,6 @@ graph LR; normalize-package-data-->semver; normalize-package-data-->validate-npm-package-license; npm-->abbrev; - npm-->ansicolors; - npm-->ansistyles; npm-->archy; npm-->cacache; npm-->chalk; @@ -524,6 +520,7 @@ graph LR; npm-->readdir-scoped-modules; npm-->rimraf; npm-->semver; + npm-->smoke-tests; npm-->spawk; npm-->ssri; npm-->tap; @@ -686,6 +683,13 @@ graph LR; readdir-scoped-modules-->once; rimraf-->glob; semver-->lru-cache; + smoke-tests-->minify-registry-metadata; + smoke-tests-->npmcli-eslint-config["@npmcli/eslint-config"]; + smoke-tests-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + smoke-tests-->npmcli-template-oss["@npmcli/template-oss"]; + smoke-tests-->rimraf; + smoke-tests-->tap; + smoke-tests-->which; socks-->ip; socks-->smart-buffer; socks-proxy-agent-->agent-base; @@ -735,4 +739,4 @@ packages higher up the chain. - make-fetch-happen, libnpmversion, @npmcli/config, init-package-json - @npmcli/installed-package-contents, @npmcli/map-workspaces, cacache, @npmcli/git, @npmcli/run-script, npm-packlist, read-package-json, readdir-scoped-modules, promzard - npm-bundled, read-package-json-fast, @npmcli/fs, unique-filename, @npmcli/promise-spawn, npm-package-arg, normalize-package-data, bin-links, nopt, npm-install-checks, npmlog, dezalgo, read - - npm-normalize-package-bin, @npmcli/name-from-folder, semver, @npmcli/move-file, fs-minipass, infer-owner, ssri, unique-slug, proc-log, @npmcli/node-gyp, hosted-git-info, validate-npm-package-name, ignore-walk, minipass-fetch, @npmcli/package-json, cmd-shim, read-cmd-shim, write-file-atomic, abbrev, are-we-there-yet, gauge, parse-conflict-json, wrappy, treeverse, @npmcli/eslint-config, @npmcli/template-oss, @npmcli/disparity-colors, @npmcli/ci-detect, mute-stream, stringify-package, ini, npm-audit-report, npm-user-validate \ No newline at end of file + - npm-normalize-package-bin, @npmcli/name-from-folder, semver, @npmcli/move-file, fs-minipass, infer-owner, ssri, unique-slug, proc-log, @npmcli/node-gyp, hosted-git-info, validate-npm-package-name, ignore-walk, minipass-fetch, @npmcli/package-json, cmd-shim, read-cmd-shim, write-file-atomic, abbrev, are-we-there-yet, gauge, parse-conflict-json, wrappy, treeverse, @npmcli/eslint-config, @npmcli/template-oss, @npmcli/disparity-colors, @npmcli/ci-detect, mute-stream, ini, npm-audit-report, npm-user-validate \ No newline at end of file From 9f57404dc148835d7393b5fe617c8c5e2c958061 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 13 Apr 2022 09:36:34 -0700 Subject: [PATCH 060/406] deps: npm-registry-fetch@13.1.1 --- node_modules/npm-registry-fetch/lib/errors.js | 2 +- node_modules/npm-registry-fetch/package.json | 10 +++++----- package-lock.json | 11 +++++++---- package.json | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/node_modules/npm-registry-fetch/lib/errors.js b/node_modules/npm-registry-fetch/lib/errors.js index 0efc923e3e900..cf5ddba6f300c 100644 --- a/node_modules/npm-registry-fetch/lib/errors.js +++ b/node_modules/npm-registry-fetch/lib/errors.js @@ -4,7 +4,7 @@ const url = require('url') function packageName (href) { try { - let basePath = new url.URL(href).pathname.substr(1) + let basePath = new url.URL(href).pathname.slice(1) if (!basePath.match(/^-/)) { basePath = basePath.split('/') var index = basePath.indexOf('_rewrite') diff --git a/node_modules/npm-registry-fetch/package.json b/node_modules/npm-registry-fetch/package.json index 9e15f627cd5a7..0ce12c633637a 100644 --- a/node_modules/npm-registry-fetch/package.json +++ b/node_modules/npm-registry-fetch/package.json @@ -1,6 +1,6 @@ { "name": "npm-registry-fetch", - "version": "13.1.0", + "version": "13.1.1", "description": "Fetch-based http client for use with npm registry APIs", "main": "lib", "files": [ @@ -44,12 +44,12 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.1.2", + "@npmcli/template-oss": "3.3.2", "cacache": "^16.0.2", "nock": "^13.2.4", "require-inject": "^1.4.4", - "ssri": "^8.0.1", - "tap": "^15.1.6" + "ssri": "^9.0.0", + "tap": "^16.0.1" }, "tap": { "check-coverage": true, @@ -60,6 +60,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.1.2" + "version": "3.3.2" } } diff --git a/package-lock.json b/package-lock.json index 066fe2f4191b6..a2f0677d3414d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -134,7 +134,7 @@ "npm-package-arg": "^9.0.2", "npm-pick-manifest": "^7.0.1", "npm-profile": "^6.0.2", - "npm-registry-fetch": "^13.1.0", + "npm-registry-fetch": "^13.1.1", "npm-user-validate": "^1.0.1", "npmlog": "^6.0.1", "opener": "^1.5.2", @@ -5152,9 +5152,10 @@ } }, "node_modules/npm-registry-fetch": { - "version": "13.1.0", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.1.1.tgz", + "integrity": "sha512-5p8rwe6wQPLJ8dMqeTnA57Dp9Ox6GH9H60xkyJup07FmVlu3Mk7pf/kIIpl9gaN5bM8NM+UUx3emUWvDNTt39w==", "inBundle": true, - "license": "ISC", "dependencies": { "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", @@ -13369,7 +13370,9 @@ } }, "npm-registry-fetch": { - "version": "13.1.0", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.1.1.tgz", + "integrity": "sha512-5p8rwe6wQPLJ8dMqeTnA57Dp9Ox6GH9H60xkyJup07FmVlu3Mk7pf/kIIpl9gaN5bM8NM+UUx3emUWvDNTt39w==", "requires": { "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", diff --git a/package.json b/package.json index da2cba63e220a..846510f5cb927 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "npm-package-arg": "^9.0.2", "npm-pick-manifest": "^7.0.1", "npm-profile": "^6.0.2", - "npm-registry-fetch": "^13.1.0", + "npm-registry-fetch": "^13.1.1", "npm-user-validate": "^1.0.1", "npmlog": "^6.0.1", "opener": "^1.5.2", From 4ca858c4e210781f369c4403e711dbbbbe5aaca6 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Thu, 14 Apr 2022 15:44:57 -0700 Subject: [PATCH 061/406] chore(test): fix config definitions test when run without tap --- test/lib/utils/config/definitions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/lib/utils/config/definitions.js b/test/lib/utils/config/definitions.js index b387835df55a3..088d0cdb6e128 100644 --- a/test/lib/utils/config/definitions.js +++ b/test/lib/utils/config/definitions.js @@ -375,6 +375,8 @@ t.test('color', t => { t.strictSame(flat, { color: false, logColor: false }, 'true when --no-color') setTTY('stdout', false) + setTTY('stderr', false) + obj.color = true definitions.color.flatten('color', obj, flat) t.strictSame(flat, { color: false, logColor: false }, 'no color when stdout not tty') @@ -383,7 +385,6 @@ t.test('color', t => { t.strictSame(flat, { color: true, logColor: false }, '--color turns on color when stdout is tty') setTTY('stdout', false) - setTTY('stderr', false) obj.color = true definitions.color.flatten('color', obj, flat) t.strictSame(flat, { color: false, logColor: false }, 'no color when stderr not tty') From 3d964940f410052918e37a9b05818fe9dc4cd86a Mon Sep 17 00:00:00 2001 From: nlf Date: Wed, 13 Apr 2022 15:03:37 -0700 Subject: [PATCH 062/406] fix(arborist): when replacing a Link with a Node, make sure to remove the Link target from the root --- workspaces/arborist/lib/node.js | 3 +++ .../test/arborist/reify.js.test.cjs | 26 ------------------- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/workspaces/arborist/lib/node.js b/workspaces/arborist/lib/node.js index c79bc0bd3a00b..abd54ffe9725a 100644 --- a/workspaces/arborist/lib/node.js +++ b/workspaces/arborist/lib/node.js @@ -1149,6 +1149,9 @@ class Node { for (const kid of node.children.values()) { kid.parent = this } + if (node.isLink && node.target) { + node.target.root = null + } } if (!node.isRoot) { diff --git a/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs b/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs index 49b02273ec59f..32b02494f7cf2 100644 --- a/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs +++ b/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs @@ -2228,19 +2228,6 @@ ArboristNode { "type": "prod", }, }, - "fsChildren": Set { - ArboristNode { - "dev": true, - "extraneous": true, - "location": "target", - "name": "target", - "optional": true, - "packageName": "ABBREV", - "path": "{CWD}/test/arborist/tap-testdir-reify-collide-case-variant-dep-names/target", - "peer": true, - "version": "1.0.0", - }, - }, "isProjectRoot": true, "location": "", "name": "tap-testdir-reify-collide-case-variant-dep-names", @@ -2275,19 +2262,6 @@ ArboristNode { "type": "prod", }, }, - "fsChildren": Set { - ArboristNode { - "dev": true, - "extraneous": true, - "location": "target", - "name": "target", - "optional": true, - "packageName": "ABBREV", - "path": "{CWD}/test/arborist/tap-testdir-reify-collide-case-variant-dep-names/target", - "peer": true, - "version": "1.0.0", - }, - }, "isProjectRoot": true, "location": "", "name": "tap-testdir-reify-collide-case-variant-dep-names", From 0ebadf5b603368557e9e837a46ea5c59c2677a81 Mon Sep 17 00:00:00 2001 From: nlf Date: Wed, 13 Apr 2022 15:07:01 -0700 Subject: [PATCH 063/406] feat(arborist): add support for installLinks when set, installLinks instructs arborist to pack and extract a file: dependency rather than creating a symlink to it. this has the effect of also installing the dependencies for the linked dependency, though if local changes are made it also requires the user to reinstall the package --- .../arborist/lib/arborist/build-ideal-tree.js | 22 +- .../arborist/lib/arborist/load-actual.js | 1 + .../arborist/lib/arborist/load-virtual.js | 2 + workspaces/arborist/lib/dep-valid.js | 16 +- workspaces/arborist/lib/node.js | 2 + workspaces/arborist/lib/place-dep.js | 3 + .../tap-snapshots/test/link.js.test.cjs | 4 + .../tap-snapshots/test/node.js.test.cjs | 248 ++++++++++++++++++ workspaces/arborist/test/arborist/reify.js | 165 ++++++++++++ workspaces/arborist/test/dep-valid.js | 8 + workspaces/arborist/test/node.js | 10 + 11 files changed, 471 insertions(+), 10 deletions(-) diff --git a/workspaces/arborist/lib/arborist/build-ideal-tree.js b/workspaces/arborist/lib/arborist/build-ideal-tree.js index f3166c37e1475..55eb8292335d0 100644 --- a/workspaces/arborist/lib/arborist/build-ideal-tree.js +++ b/workspaces/arborist/lib/arborist/build-ideal-tree.js @@ -124,6 +124,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { globalStyle = false, idealTree = null, includeWorkspaceRoot = false, + installLinks = false, legacyPeerDeps = false, packageLock = true, strictPeerDeps = false, @@ -135,6 +136,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { this[_strictPeerDeps] = !!strictPeerDeps this.idealTree = idealTree + this.installLinks = installLinks this.legacyPeerDeps = legacyPeerDeps this[_usePackageLock] = packageLock @@ -410,6 +412,7 @@ Try using the package name instead, e.g: peer: false, optional: false, global: this[_global], + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, loadOverrides: true, }) @@ -424,6 +427,7 @@ Try using the package name instead, e.g: peer: false, optional: false, global: this[_global], + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, root, }) @@ -992,6 +996,7 @@ This is a one-time fix-up, please be patient... preferDedupe: this[_preferDedupe], legacyBundling: this[_legacyBundling], strictPeerDeps: this[_strictPeerDeps], + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, globalStyle: this[_globalStyle], })) @@ -1151,6 +1156,7 @@ This is a one-time fix-up, please be patient... const vr = new Node({ path: node.realpath, sourceReference: node, + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, overrides: node.overrides, }) @@ -1268,17 +1274,18 @@ This is a one-time fix-up, please be patient... // the object so it doesn't get mutated. // Don't bother to load the manifest for link deps, because the target // might be within another package that doesn't exist yet. - const { legacyPeerDeps } = this + const { installLinks, legacyPeerDeps } = this + const isWorkspace = this.idealTree.workspaces && this.idealTree.workspaces.has(spec.name) - // spec is a directory, link it - if (spec.type === 'directory') { + // spec is a directory, link it unless installLinks is set or it's a workspace + if (spec.type === 'directory' && (isWorkspace || !installLinks)) { return this[_linkFromSpec](name, spec, parent, edge) } // if the spec matches a workspace name, then see if the workspace node will // satisfy the edge. if it does, we return the workspace node to make sure it // takes priority. - if (this.idealTree.workspaces && this.idealTree.workspaces.has(spec.name)) { + if (isWorkspace) { const existingNode = this.idealTree.edgesOut.get(spec.name).to if (existingNode && existingNode.isWorkspace && existingNode.satisfies(edge)) { return edge.to @@ -1288,7 +1295,7 @@ This is a one-time fix-up, please be patient... // spec isn't a directory, and either isn't a workspace or the workspace we have // doesn't satisfy the edge. try to fetch a manifest and build a node from that. return this[_fetchManifest](spec) - .then(pkg => new Node({ name, pkg, parent, legacyPeerDeps }), error => { + .then(pkg => new Node({ name, pkg, parent, installLinks, legacyPeerDeps }), error => { error.requiredBy = edge.from.location || '.' // failed to load the spec, either because of enotarget or @@ -1298,6 +1305,7 @@ This is a one-time fix-up, please be patient... name, parent, error, + installLinks, legacyPeerDeps, }) this[_loadFailures].add(n) @@ -1307,9 +1315,9 @@ This is a one-time fix-up, please be patient... [_linkFromSpec] (name, spec, parent, edge) { const realpath = spec.fetchSpec - const { legacyPeerDeps } = this + const { installLinks, legacyPeerDeps } = this return rpj(realpath + '/package.json').catch(() => ({})).then(pkg => { - const link = new Link({ name, parent, realpath, pkg, legacyPeerDeps }) + const link = new Link({ name, parent, realpath, pkg, installLinks, legacyPeerDeps }) this[_linkNodes].add(link) return link }) diff --git a/workspaces/arborist/lib/arborist/load-actual.js b/workspaces/arborist/lib/arborist/load-actual.js index b04fc88f65ccb..70b898141cc54 100644 --- a/workspaces/arborist/lib/arborist/load-actual.js +++ b/workspaces/arborist/lib/arborist/load-actual.js @@ -283,6 +283,7 @@ module.exports = cls => class ActualLoader extends cls { .then(pkg => [pkg, null], error => [null, error]) .then(([pkg, error]) => { return this[normalize(path) === real ? _newNode : _newLink]({ + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, path, realpath: real, diff --git a/workspaces/arborist/lib/arborist/load-virtual.js b/workspaces/arborist/lib/arborist/load-virtual.js index 8a41e7686e7e1..097e5fb84298e 100644 --- a/workspaces/arborist/lib/arborist/load-virtual.js +++ b/workspaces/arborist/lib/arborist/load-virtual.js @@ -278,6 +278,7 @@ module.exports = cls => class VirtualLoader extends cls { const peer = sw.peer const node = new Node({ + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, root: this.virtualTree, path, @@ -304,6 +305,7 @@ module.exports = cls => class VirtualLoader extends cls { [loadLink] (location, targetLoc, target, meta) { const path = resolve(this.path, location) const link = new Link({ + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, path, realpath: resolve(this.path, targetLoc), diff --git a/workspaces/arborist/lib/dep-valid.js b/workspaces/arborist/lib/dep-valid.js index 2c837ae888448..c69ab557ae491 100644 --- a/workspaces/arborist/lib/dep-valid.js +++ b/workspaces/arborist/lib/dep-valid.js @@ -53,9 +53,7 @@ const depValid = (child, requested, requestor) => { return semver.satisfies(child.version, requested.fetchSpec, true) case 'directory': - // directory must be a link to the specified folder - return !!child.isLink && - relative(child.realpath, requested.fetchSpec) === '' + return linkValid(child, requested, requestor) case 'file': return tarballValid(child, requested, requestor) @@ -108,6 +106,18 @@ const depValid = (child, requested, requestor) => { return false } +const linkValid = (child, requested, requestor) => { + const isLink = !!child.isLink + // if we're installing links and the node is a link, then it's invalid because we want + // a real node to be there + if (requestor.installLinks) { + return !isLink + } + + // directory must be a link to the specified folder + return isLink && relative(child.realpath, requested.fetchSpec) === '' +} + const tarballValid = (child, requested, requestor) => { if (child.isLink) { return false diff --git a/workspaces/arborist/lib/node.js b/workspaces/arborist/lib/node.js index abd54ffe9725a..60301798b918d 100644 --- a/workspaces/arborist/lib/node.js +++ b/workspaces/arborist/lib/node.js @@ -86,6 +86,7 @@ class Node { name, children, fsChildren, + installLinks = false, legacyPeerDeps = false, linksIn, hasShrinkwrap, @@ -152,6 +153,7 @@ class Node { } this.integrity = integrity || pkg._integrity || null this.hasShrinkwrap = hasShrinkwrap || pkg._hasShrinkwrap || false + this.installLinks = installLinks this.legacyPeerDeps = legacyPeerDeps this.children = new CaseInsensitiveMap() diff --git a/workspaces/arborist/lib/place-dep.js b/workspaces/arborist/lib/place-dep.js index c0cbe91fe3667..9d84d3f1b08a5 100644 --- a/workspaces/arborist/lib/place-dep.js +++ b/workspaces/arborist/lib/place-dep.js @@ -45,6 +45,7 @@ class PlaceDep { auditReport, legacyBundling, strictPeerDeps, + installLinks, legacyPeerDeps, globalStyle, } = parent || options @@ -56,6 +57,7 @@ class PlaceDep { auditReport, legacyBundling, strictPeerDeps, + installLinks, legacyPeerDeps, globalStyle, }) @@ -293,6 +295,7 @@ class PlaceDep { pkg: dep.package, resolved: dep.resolved, integrity: dep.integrity, + installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, error: dep.errors[0], ...(dep.overrides ? { overrides: dep.overrides } : {}), diff --git a/workspaces/arborist/tap-snapshots/test/link.js.test.cjs b/workspaces/arborist/tap-snapshots/test/link.js.test.cjs index a1b4d8753ff97..71d4414c33c56 100644 --- a/workspaces/arborist/tap-snapshots/test/link.js.test.cjs +++ b/workspaces/arborist/tap-snapshots/test/link.js.test.cjs @@ -16,6 +16,7 @@ Link { "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -42,6 +43,7 @@ exports[`test/link.js TAP > instantiate without providing target 1`] = ` "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "../../../../../some/other/path" => <*ref_1>, @@ -56,6 +58,7 @@ exports[`test/link.js TAP > instantiate without providing target 1`] = ` "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -94,6 +97,7 @@ exports[`test/link.js TAP > instantiate without providing target 1`] = ` "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, diff --git a/workspaces/arborist/tap-snapshots/test/node.js.test.cjs b/workspaces/arborist/tap-snapshots/test/node.js.test.cjs index cc83ba8656ca7..08705aca6f8eb 100644 --- a/workspaces/arborist/tap-snapshots/test/node.js.test.cjs +++ b/workspaces/arborist/tap-snapshots/test/node.js.test.cjs @@ -17,6 +17,7 @@ exports[`test/node.js TAP basic instantiation > just a lone root node 1`] = ` "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -204,6 +205,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -227,6 +229,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -267,6 +270,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -285,6 +289,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -320,6 +325,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -334,6 +340,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -360,6 +367,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -377,6 +385,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -401,6 +410,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -419,6 +429,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -453,6 +464,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -477,6 +489,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -491,6 +504,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -538,6 +552,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -556,6 +571,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -591,6 +607,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -605,6 +622,7 @@ exports[`test/node.js TAP set workspaces > should setup edges out for each works "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -650,6 +668,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -684,6 +703,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -733,6 +753,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -749,6 +770,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -785,6 +807,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -814,6 +837,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -843,6 +867,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -872,6 +897,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -897,6 +923,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -930,6 +957,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -944,6 +972,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1000,6 +1029,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -1017,6 +1047,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1051,6 +1082,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1100,6 +1132,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1116,6 +1149,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1145,6 +1179,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1181,6 +1216,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1210,6 +1246,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1239,6 +1276,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1268,6 +1306,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1293,6 +1332,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1326,6 +1366,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1340,6 +1381,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1376,6 +1418,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1410,6 +1453,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1434,6 +1478,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1474,6 +1519,7 @@ exports[`test/node.js TAP testing with dep tree with meta > add new meta under p "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1519,6 +1565,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1568,6 +1615,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1584,6 +1632,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1620,6 +1669,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1649,6 +1699,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1678,6 +1729,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1707,6 +1759,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1732,6 +1785,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1778,6 +1832,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -1805,6 +1860,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1854,6 +1910,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1870,6 +1927,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1899,6 +1957,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1935,6 +1994,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -1971,6 +2031,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2000,6 +2061,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2029,6 +2091,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2058,6 +2121,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2083,6 +2147,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2124,6 +2189,7 @@ exports[`test/node.js TAP testing with dep tree with meta > initial load with so "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2181,6 +2247,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2197,6 +2264,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2233,6 +2301,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2262,6 +2331,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2291,6 +2361,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2320,6 +2391,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2345,6 +2417,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2384,6 +2457,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2430,6 +2504,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -2469,6 +2544,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2485,6 +2561,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2514,6 +2591,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2550,6 +2628,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2579,6 +2658,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2608,6 +2688,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2637,6 +2718,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2662,6 +2744,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2701,6 +2784,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2742,6 +2826,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move meta to top lev "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2799,6 +2884,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2815,6 +2901,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2848,6 +2935,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2877,6 +2965,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2906,6 +2995,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2935,6 +3025,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2960,6 +3051,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -2986,6 +3078,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3023,6 +3116,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3037,6 +3131,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3093,6 +3188,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -3132,6 +3228,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3148,6 +3245,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3177,6 +3275,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3210,6 +3309,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3239,6 +3339,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3268,6 +3369,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3297,6 +3399,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3322,6 +3425,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3346,6 +3450,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3371,6 +3476,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3408,6 +3514,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3422,6 +3529,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3473,6 +3581,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3530,6 +3639,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3546,6 +3656,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3579,6 +3690,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3608,6 +3720,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3637,6 +3750,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3666,6 +3780,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3691,6 +3806,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3717,6 +3833,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3754,6 +3871,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3768,6 +3886,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3824,6 +3943,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -3863,6 +3983,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3879,6 +4000,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3908,6 +4030,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3941,6 +4064,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3970,6 +4094,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -3999,6 +4124,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4028,6 +4154,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4053,6 +4180,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4077,6 +4205,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4102,6 +4231,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4139,6 +4269,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4153,6 +4284,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4204,6 +4336,7 @@ exports[`test/node.js TAP testing with dep tree with meta > move new meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4239,6 +4372,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4273,6 +4407,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4322,6 +4457,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4338,6 +4474,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4374,6 +4511,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4403,6 +4541,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4432,6 +4571,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4461,6 +4601,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4486,6 +4627,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4519,6 +4661,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4533,6 +4676,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4589,6 +4733,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -4606,6 +4751,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4640,6 +4786,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4689,6 +4836,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4705,6 +4853,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4734,6 +4883,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4770,6 +4920,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4799,6 +4950,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4828,6 +4980,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4857,6 +5010,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4882,6 +5036,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4915,6 +5070,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4929,6 +5085,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4965,6 +5122,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -4999,6 +5157,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5023,6 +5182,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5063,6 +5223,7 @@ exports[`test/node.js TAP testing with dep tree without meta > add new meta unde "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5108,6 +5269,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5157,6 +5319,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5173,6 +5336,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5209,6 +5373,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5238,6 +5403,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5267,6 +5433,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5296,6 +5463,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5321,6 +5489,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5367,6 +5536,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -5394,6 +5564,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5443,6 +5614,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5459,6 +5631,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5488,6 +5661,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5524,6 +5698,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5560,6 +5735,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5589,6 +5765,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5618,6 +5795,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5647,6 +5825,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5672,6 +5851,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5713,6 +5893,7 @@ exports[`test/node.js TAP testing with dep tree without meta > initial load with "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5770,6 +5951,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5786,6 +5968,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5822,6 +6005,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5851,6 +6035,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5880,6 +6065,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5909,6 +6095,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5934,6 +6121,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -5973,6 +6161,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6019,6 +6208,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -6058,6 +6248,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6074,6 +6265,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6103,6 +6295,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6139,6 +6332,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6168,6 +6362,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6197,6 +6392,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6226,6 +6422,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6251,6 +6448,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6290,6 +6488,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "meta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6331,6 +6530,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move meta to top "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6388,6 +6588,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6404,6 +6605,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6437,6 +6639,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6466,6 +6669,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6495,6 +6699,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6524,6 +6729,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6549,6 +6755,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6575,6 +6782,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6612,6 +6820,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6626,6 +6835,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6682,6 +6892,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -6721,6 +6932,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6737,6 +6949,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6766,6 +6979,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6799,6 +7013,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6828,6 +7043,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6857,6 +7073,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6886,6 +7103,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6911,6 +7129,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6935,6 +7154,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6960,6 +7180,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -6997,6 +7218,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7011,6 +7233,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7062,6 +7285,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7119,6 +7343,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7135,6 +7360,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7168,6 +7394,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7197,6 +7424,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7226,6 +7454,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7255,6 +7484,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7280,6 +7510,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7306,6 +7537,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7343,6 +7575,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7357,6 +7590,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7413,6 +7647,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory { "" => <*ref_1>, @@ -7452,6 +7687,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7468,6 +7704,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to }, }, "hasShrinkwrap": false, + "installLinks": false, "integrity": "prod", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7497,6 +7734,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7530,6 +7768,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "bundled", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7559,6 +7798,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "dev", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7588,6 +7828,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "opt", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7617,6 +7858,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "peer", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7642,6 +7884,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "extraneous", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7666,6 +7909,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7691,6 +7935,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7728,6 +7973,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "newMeta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7742,6 +7988,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": "metameta", "inventory": Inventory {}, "legacyPeerDeps": false, @@ -7793,6 +8040,7 @@ exports[`test/node.js TAP testing with dep tree without meta > move new meta to "extraneous": true, "fsChildren": Set {}, "hasShrinkwrap": false, + "installLinks": false, "integrity": null, "inventory": Inventory {}, "legacyPeerDeps": false, diff --git a/workspaces/arborist/test/arborist/reify.js b/workspaces/arborist/test/arborist/reify.js index 9124b4630ca88..813c984ceffb4 100644 --- a/workspaces/arborist/test/arborist/reify.js +++ b/workspaces/arborist/test/arborist/reify.js @@ -2652,3 +2652,168 @@ t.test('save package.json on update', t => { }) t.end() }) + +t.test('installLinks', (t) => { + t.test('when true, packs and extracts instead of symlinks', async (t) => { + const path = t.testdir({ + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + main: 'index.js', + dependencies: { + b: 'file:../b', + }, + }), + 'index.js': '', + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + main: 'index.js', + }), + 'index.js': '', + }, + }) + + await reify(resolve(path, 'a'), { installLinks: true }) + + const installedB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(installedB.isDirectory(), 'a/node_modules/b is a directory') + }) + + t.test('when false, symlinks', async (t) => { + const path = t.testdir({ + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + main: 'index.js', + dependencies: { + b: 'file:../b', + }, + }), + 'index.js': '', + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + main: 'index.js', + }), + 'index.js': '', + }, + }) + + await reify(resolve(path, 'a'), { installLinks: false }) + + const installedB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(installedB.isSymbolicLink(), 'a/node_modules/b is a symlink') + }) + + t.test('when symlinks exist, installLinks set to true replaces them with dirs', async (t) => { + const path = t.testdir({ + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + main: 'index.js', + dependencies: { + b: 'file:../b', + }, + }), + 'index.js': '', + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + main: 'index.js', + }), + 'index.js': '', + }, + }) + + await reify(resolve(path, 'a'), { installLinks: false, save: true }) + + const firstB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(firstB.isSymbolicLink(), 'a/node_modules/b is a symlink') + + await reify(resolve(path, 'a'), { installLinks: true, save: true }) + + const secondB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(secondB.isDirectory(), 'a/node_modules/b is now a directory') + }) + + t.test('when directories exist, installLinks set to false replaces them with symlinks', async (t) => { + const path = t.testdir({ + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + main: 'index.js', + dependencies: { + b: 'file:../b', + }, + }), + 'index.js': '', + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + main: 'index.js', + }), + 'index.js': '', + }, + }) + + await reify(resolve(path, 'a'), { installLinks: true }) + + const firstB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(firstB.isDirectory(), 'a/node_modules/b is a directory') + + await reify(resolve(path, 'a'), { installLinks: false }) + + const secondB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(secondB.isSymbolicLink(), 'a/node_modules/b is now a symlink') + }) + + t.test('when installLinks is true, dependencies of links are installed', async (t) => { + const path = t.testdir({ + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + main: 'index.js', + dependencies: { + b: 'file:../b', + }, + }), + 'index.js': '', + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + main: 'index.js', + dependencies: { + abbrev: '^1.0.0', + }, + }), + 'index.js': '', + }, + }) + + await reify(resolve(path, 'a'), { installLinks: true }) + + const installedB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(installedB.isDirectory(), 'a/node_modules/b is a directory') + + const abbrev = fs.lstatSync(resolve(path, 'a/node_modules/abbrev')) + t.ok(abbrev.isDirectory(), 'abbrev got installed') + }) + + t.end() +}) diff --git a/workspaces/arborist/test/dep-valid.js b/workspaces/arborist/test/dep-valid.js index 3294ea4e88acf..901325b2390b9 100644 --- a/workspaces/arborist/test/dep-valid.js +++ b/workspaces/arborist/test/dep-valid.js @@ -176,3 +176,11 @@ t.test('invalid request all together', t => { }, 'parent got an error for their invalid request') t.end() }) + +t.test('installLinks makes Link nodes invalid', t => { + const requestor = { errors: [], installLinks: true } + const child = { isLink: true, name: 'kid' } + const request = { type: 'directory' } + t.notOk(depValid(child, request, null, requestor)) + t.end() +}) diff --git a/workspaces/arborist/test/node.js b/workspaces/arborist/test/node.js index 80bc21559569b..73e0818938f27 100644 --- a/workspaces/arborist/test/node.js +++ b/workspaces/arborist/test/node.js @@ -328,6 +328,16 @@ t.test('testing with dep tree', t => { t.equal(prodLink.children.size, 0, 'links do not have child nodes') t.equal(prodLink.target.children.size, kidCount, 'link target has children') + t.equal(newProd.canReplace(prodLink), true, 'node can replace link') + const { target } = prodLink + newProd.replace(prodLink) + t.equal(prodLink.parent, null, 'prodLink removed from tree') + t.equal(prodLink.target, null, 'prodLink lost its target') + t.equal(prodLink.root, prodLink, 'prodLink removed from tree') + t.equal(target.root, target, 'prodLinks old target removed from tree') + t.equal(normalizePath(newProd.path), normalizePath(prodLink.path), 'replaced node') + t.equal(prodLink.children.size, 0, 'prodLink has no child nodes') + t.end() }) From a4adf256b4fc268fc64cfd5e66526b4685716e79 Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 14 Apr 2022 09:57:54 -0700 Subject: [PATCH 064/406] chore(arborist): add installLinks with workspaces test --- workspaces/arborist/test/arborist/reify.js | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/workspaces/arborist/test/arborist/reify.js b/workspaces/arborist/test/arborist/reify.js index 813c984ceffb4..5097004041174 100644 --- a/workspaces/arborist/test/arborist/reify.js +++ b/workspaces/arborist/test/arborist/reify.js @@ -2815,5 +2815,53 @@ t.test('installLinks', (t) => { t.ok(abbrev.isDirectory(), 'abbrev got installed') }) + t.test('workspaces are always symlinks, even with installLinks set to true', async (t) => { + const path = t.testdir({ + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + main: 'index.js', + dependencies: { + b: 'file:../b', + c: '^1.0.0', + }, + workspaces: ['./c'], + }), + 'index.js': '', + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + main: 'index.js', + }), + 'index.js': '', + }, + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + main: 'index.js', + dependencies: { + abbrev: '^1.0.0', + }, + }), + 'index.js': '', + }, + }) + + await reify(resolve(path, 'a'), { installLinks: true }) + + const installedB = fs.lstatSync(resolve(path, 'a/node_modules/b')) + t.ok(installedB.isDirectory(), 'a/node_modules/b is a directory') + + const installedC = fs.lstatSync(resolve(path, 'a/node_modules/c')) + t.ok(installedC.isSymbolicLink(), 'a/node_modules/c is a symlink') + + const abbrev = fs.lstatSync(resolve(path, 'a/node_modules/abbrev')) + t.ok(abbrev.isDirectory(), 'abbrev got installed') + }) + t.end() }) From bedd8a1f5844b5b379af5a756baa70821d78c610 Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 14 Apr 2022 10:04:57 -0700 Subject: [PATCH 065/406] feat: add install-links config definition --- docs/content/using-npm/config.md | 12 +++++++ lib/arborist-cmd.js | 1 + lib/utils/config/definitions.js | 11 +++++++ .../test/lib/commands/config.js.test.cjs | 2 ++ .../test/lib/commands/ls.js.test.cjs | 32 ------------------- .../test/lib/load-all-commands.js.test.cjs | 24 +++++++------- .../lib/utils/config/definitions.js.test.cjs | 12 +++++++ .../lib/utils/config/describe-all.js.test.cjs | 12 +++++++ .../test/lib/utils/npm-usage.js.test.cjs | 24 +++++++------- 9 files changed, 74 insertions(+), 56 deletions(-) diff --git a/docs/content/using-npm/config.md b/docs/content/using-npm/config.md index 71dab98a3831e..200a2e401c7a6 100644 --- a/docs/content/using-npm/config.md +++ b/docs/content/using-npm/config.md @@ -891,6 +891,18 @@ number, if not already set in package.json. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + #### `json` * Default: false diff --git a/lib/arborist-cmd.js b/lib/arborist-cmd.js index 6518e91e0ad9d..5007fbd9244d2 100644 --- a/lib/arborist-cmd.js +++ b/lib/arborist-cmd.js @@ -12,6 +12,7 @@ class ArboristCmd extends BaseCommand { 'workspace', 'workspaces', 'include-workspace-root', + 'install-links', ] static ignoreImplicitWorkspace = false diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index 7ff0eeb1283c5..f4ffb821837b0 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -1070,6 +1070,17 @@ define('init.version', { `, }) +define('install-links', { + default: false, + type: Boolean, + description: ` + When set file: protocol dependencies that exist outside of the project root + will be packed and installed as regular dependencies instead of creating a + symlink. This option has no effect on workspaces. + `, + flatten, +}) + define('json', { default: false, type: Boolean, diff --git a/tap-snapshots/test/lib/commands/config.js.test.cjs b/tap-snapshots/test/lib/commands/config.js.test.cjs index 56ef71f3efd3c..c6f07dd326cb2 100644 --- a/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -81,6 +81,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "init.license": "ISC", "init.module": "{HOME}/.npm-init.js", "init.version": "1.0.0", + "install-links": false, "key": null, "legacy-bundling": false, "legacy-peer-deps": false, @@ -234,6 +235,7 @@ init.author.url = "" init.license = "ISC" init.module = "{HOME}/.npm-init.js" init.version = "1.0.0" +install-links = false json = false key = null legacy-bundling = false diff --git a/tap-snapshots/test/lib/commands/ls.js.test.cjs b/tap-snapshots/test/lib/commands/ls.js.test.cjs index e98898aeff417..a10d37ab92881 100644 --- a/tap-snapshots/test/lib/commands/ls.js.test.cjs +++ b/tap-snapshots/test/lib/commands/ls.js.test.cjs @@ -114,23 +114,6 @@ test-npm-ls@1.0.0 ` -exports[`test/lib/commands/ls.js TAP ls --only=development > should output tree containing only development deps 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---only-development -\`-- dev-dep@1.0.0 - \`-- foo@1.0.0 - \`-- dog@1.0.0 - -` - -exports[`test/lib/commands/ls.js TAP ls --only=prod > should output tree containing only prod deps 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---only-prod -+-- chai@1.0.0 -+-- optional-dep@1.0.0 -\`-- prod-dep@1.0.0 - \`-- dog@2.0.0 - -` - exports[`test/lib/commands/ls.js TAP ls --parseable --depth=0 > should output tree containing only top-level dependencies 1`] = ` {CWD}/tap-testdir-ls-ls---parseable---depth-0 {CWD}/tap-testdir-ls-ls---parseable---depth-0/node_modules/chai @@ -204,21 +187,6 @@ exports[`test/lib/commands/ls.js TAP ls --parseable --long with extraneous deps {CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps/node_modules/dog:dog@1.0.0 ` -exports[`test/lib/commands/ls.js TAP ls --parseable --only=development > should output tree containing only development deps 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---only-development -{CWD}/tap-testdir-ls-ls---parseable---only-development/node_modules/dev-dep -{CWD}/tap-testdir-ls-ls---parseable---only-development/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable---only-development/node_modules/dog -` - -exports[`test/lib/commands/ls.js TAP ls --parseable --only=prod > should output tree containing only prod deps 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---only-prod -{CWD}/tap-testdir-ls-ls---parseable---only-prod/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable---only-prod/node_modules/optional-dep -{CWD}/tap-testdir-ls-ls---parseable---only-prod/node_modules/prod-dep -{CWD}/tap-testdir-ls-ls---parseable---only-prod/node_modules/prod-dep/node_modules/dog -` - exports[`test/lib/commands/ls.js TAP ls --parseable --production > should output tree containing production deps 1`] = ` {CWD}/tap-testdir-ls-ls---parseable---production {CWD}/tap-testdir-ls-ls---parseable---production/node_modules/chai diff --git a/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/tap-snapshots/test/lib/load-all-commands.js.test.cjs index cd8b0592c36e8..37349cbe01e7d 100644 --- a/tap-snapshots/test/lib/load-all-commands.js.test.cjs +++ b/tap-snapshots/test/lib/load-all-commands.js.test.cjs @@ -51,7 +51,7 @@ Options: [--omit [--omit ...]] [--foreground-scripts] [--ignore-scripts] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] Run "npm help audit" for more info ` @@ -164,7 +164,7 @@ Options: [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] alias: ddp @@ -314,7 +314,7 @@ Options: [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] Run "npm help find-dupes" for more info ` @@ -423,7 +423,7 @@ Options: [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall @@ -467,7 +467,7 @@ Options: [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] alias: it @@ -488,7 +488,7 @@ Options: [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] alias: ln @@ -506,7 +506,7 @@ Options: [--omit [--omit ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] alias: la @@ -550,7 +550,7 @@ Options: [--omit [--omit ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] alias: list @@ -683,7 +683,7 @@ Options: [--omit [--omit ...]] [--dry-run] [--json] [--foreground-scripts] [--ignore-scripts] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] Run "npm help prune" for more info ` @@ -711,7 +711,7 @@ npm rebuild [[<@scope>/][@] ...] Options: [-g|--global] [--no-bin-links] [--foreground-scripts] [--ignore-scripts] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] alias: rb @@ -921,7 +921,7 @@ npm uninstall [<@scope>/]... Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] aliases: unlink, remove, rm, r, un @@ -967,7 +967,7 @@ Options: [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] +[-ws|--workspaces] [--include-workspace-root] [--install-links] aliases: up, upgrade, udpate diff --git a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs index 91f0d782878a3..b190d7eb10ba6 100644 --- a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs @@ -76,6 +76,7 @@ Array [ "init.license", "init.module", "init.version", + "install-links", "json", "key", "legacy-bundling", @@ -973,6 +974,17 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for init. Alias for \`--init-version\` ` +exports[`test/lib/utils/config/definitions.js TAP > config description for install-links 1`] = ` +#### \`install-links\` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. +` + exports[`test/lib/utils/config/definitions.js TAP > config description for json 1`] = ` #### \`json\` diff --git a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs index 7b13c34daf682..a97b35d3acfe2 100644 --- a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs @@ -765,6 +765,18 @@ number, if not already set in package.json. +#### \`install-links\` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + #### \`json\` * Default: false diff --git a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs index fef4cc65edc65..eb71ced8d73b5 100644 --- a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs +++ b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs @@ -206,7 +206,7 @@ All commands: [--omit [--omit ...]] [--foreground-scripts] [--ignore-scripts] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] Run "npm help audit" for more info @@ -296,7 +296,7 @@ All commands: [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] alias: ddp @@ -426,7 +426,7 @@ All commands: [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] Run "npm help find-dupes" for more info @@ -511,7 +511,7 @@ All commands: [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall @@ -551,7 +551,7 @@ All commands: [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] alias: it @@ -570,7 +570,7 @@ All commands: [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] alias: ln @@ -586,7 +586,7 @@ All commands: [--omit [--omit ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] alias: la @@ -624,7 +624,7 @@ All commands: [--omit [--omit ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] alias: list @@ -739,7 +739,7 @@ All commands: [--omit [--omit ...]] [--dry-run] [--json] [--foreground-scripts] [--ignore-scripts] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] Run "npm help prune" for more info @@ -763,7 +763,7 @@ All commands: Options: [-g|--global] [--no-bin-links] [--foreground-scripts] [--ignore-scripts] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] alias: rb @@ -941,7 +941,7 @@ All commands: Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] aliases: unlink, remove, rm, r, un @@ -981,7 +981,7 @@ All commands: [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] - [-ws|--workspaces] [--include-workspace-root] + [-ws|--workspaces] [--include-workspace-root] [--install-links] aliases: up, upgrade, udpate From a6ea8843a9761d4392b3344400eb56e07691a91d Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 14 Apr 2022 11:25:39 -0700 Subject: [PATCH 066/406] docs: add some more docs for --install-links --- docs/content/commands/npm-ci.md | 5 +++-- docs/content/commands/npm-install.md | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/content/commands/npm-ci.md b/docs/content/commands/npm-ci.md index b4ce811869bb2..2bb542a725b5d 100644 --- a/docs/content/commands/npm-ci.md +++ b/docs/content/commands/npm-ci.md @@ -48,8 +48,9 @@ In short, the main differences between using `npm install` and `npm ci` are: NOTE: If you create your `package-lock.json` file by running `npm install` with flags that can affect the shape of your dependency tree, such as -`--legacy-peer-deps`, you _must_ provide the same flags to `npm ci` or you -are likely to encounter errors. An easy way to do this is to run +`--legacy-peer-deps` or `--install-links`, you _must_ provide the same +flags to `npm ci` or you are likely to encounter errors. An easy way to do +this is to run, for example, `npm config set legacy-peer-deps=true --location=project` and commit the `.npmrc` file to your repo. diff --git a/docs/content/commands/npm-install.md b/docs/content/commands/npm-install.md index 7e370319b82ff..5d27f669f0f01 100644 --- a/docs/content/commands/npm-install.md +++ b/docs/content/commands/npm-install.md @@ -91,12 +91,12 @@ into a tarball (b). *npm will not install the package dependencies* in the directory ``, but it will create a symlink to ``. - > NOTE: If you want to install the content of a directory like a package from the registry instead of creating a link, you would need to use [`npm pack`](/commands/npm-pack) while in the `` directory, and then install the resulting tarball instead of the `` using `npm install ` + > NOTE: If you want to install the content of a directory like a package from the registry instead of creating a link, you would need to use the `--install-links` option. Example: ```bash - npm install ../../other-package + npm install ../../other-package --install-links npm install ./sub-package ``` From 0004be86b7fd79e7a1ad18e4388c11121bf2a23a Mon Sep 17 00:00:00 2001 From: nlf Date: Thu, 14 Apr 2022 11:33:09 -0700 Subject: [PATCH 067/406] chore: rebuild docs for install-links config --- docs/content/commands/npm-audit.md | 12 ++++++++++++ docs/content/commands/npm-dedupe.md | 12 ++++++++++++ docs/content/commands/npm-find-dupes.md | 12 ++++++++++++ docs/content/commands/npm-install-test.md | 12 ++++++++++++ docs/content/commands/npm-install.md | 12 ++++++++++++ docs/content/commands/npm-link.md | 12 ++++++++++++ docs/content/commands/npm-ls.md | 12 ++++++++++++ docs/content/commands/npm-prune.md | 12 ++++++++++++ docs/content/commands/npm-rebuild.md | 12 ++++++++++++ docs/content/commands/npm-uninstall.md | 12 ++++++++++++ docs/content/commands/npm-update.md | 12 ++++++++++++ 11 files changed, 132 insertions(+) diff --git a/docs/content/commands/npm-audit.md b/docs/content/commands/npm-audit.md index 0f164ac9d3ec5..9d09a4107fdc7 100644 --- a/docs/content/commands/npm-audit.md +++ b/docs/content/commands/npm-audit.md @@ -399,6 +399,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-dedupe.md b/docs/content/commands/npm-dedupe.md index b9768c25db88d..f816b99433581 100644 --- a/docs/content/commands/npm-dedupe.md +++ b/docs/content/commands/npm-dedupe.md @@ -310,6 +310,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-find-dupes.md b/docs/content/commands/npm-find-dupes.md index 3549be47daae9..a92c57bd7e183 100644 --- a/docs/content/commands/npm-find-dupes.md +++ b/docs/content/commands/npm-find-dupes.md @@ -234,6 +234,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-install-test.md b/docs/content/commands/npm-install-test.md index 8975fc4ce61de..931ff050718e1 100644 --- a/docs/content/commands/npm-install-test.md +++ b/docs/content/commands/npm-install-test.md @@ -319,6 +319,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-install.md b/docs/content/commands/npm-install.md index 5d27f669f0f01..5cf3b0326d72f 100644 --- a/docs/content/commands/npm-install.md +++ b/docs/content/commands/npm-install.md @@ -709,6 +709,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### Algorithm diff --git a/docs/content/commands/npm-link.md b/docs/content/commands/npm-link.md index fb7e46de04a09..fb2b23921b044 100644 --- a/docs/content/commands/npm-link.md +++ b/docs/content/commands/npm-link.md @@ -387,6 +387,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-ls.md b/docs/content/commands/npm-ls.md index 8d4799777e20f..ded8c0c0d26ef 100644 --- a/docs/content/commands/npm-ls.md +++ b/docs/content/commands/npm-ls.md @@ -285,6 +285,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-prune.md b/docs/content/commands/npm-prune.md index 81dccf889ce4d..28f02f6add190 100644 --- a/docs/content/commands/npm-prune.md +++ b/docs/content/commands/npm-prune.md @@ -191,6 +191,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-rebuild.md b/docs/content/commands/npm-rebuild.md index bddd18c2bcaf4..52c368c8c513b 100644 --- a/docs/content/commands/npm-rebuild.md +++ b/docs/content/commands/npm-rebuild.md @@ -162,6 +162,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-uninstall.md b/docs/content/commands/npm-uninstall.md index 572d9dd8aaa3d..e39c7e328b20a 100644 --- a/docs/content/commands/npm-uninstall.md +++ b/docs/content/commands/npm-uninstall.md @@ -145,6 +145,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also diff --git a/docs/content/commands/npm-update.md b/docs/content/commands/npm-update.md index be0b0cb937eae..394773214995c 100644 --- a/docs/content/commands/npm-update.md +++ b/docs/content/commands/npm-update.md @@ -437,6 +437,18 @@ This value is not exported to the environment for child processes. +#### `install-links` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies that exist outside of the project root +will be packed and installed as regular dependencies instead of creating a +symlink. This option has no effect on workspaces. + + + + ### See Also From 4a46a27f2b968e2f8c1f4821508f93013738c482 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Wed, 30 Mar 2022 16:37:27 -0400 Subject: [PATCH 068/406] fix(libnpmexec): fix read mixed local/registry pkg Refactor / clean up of the logic around reading installed packages. Fixes reading packages from mixed sources (one being from the local installed tree and the other from the registry using pacote.manifest). Makes it so that libnpmexec is always reading from the Arborist actual tree instead of reading `node_modules` from the file system when retrieving local package data. Fixes: https://github.com/npm/cli/issues/3668 Relates to: https://github.com/npm/cli/pull/4643 Relates to: https://github.com/npm/cli/issues/4619 Relates to: https://github.com/npm/statusboard/issues/403 --- test/lib/commands/exec.js | 274 +++++++++++++++--- workspaces/libnpmexec/lib/index.js | 73 +++-- workspaces/libnpmexec/lib/manifest-missing.js | 19 -- .../libnpmexec/test/manifest-missing.js | 32 -- 4 files changed, 287 insertions(+), 111 deletions(-) delete mode 100644 workspaces/libnpmexec/lib/manifest-missing.js delete mode 100644 workspaces/libnpmexec/test/manifest-missing.js diff --git a/test/lib/commands/exec.js b/test/lib/commands/exec.js index 1f7230d25b654..6b57bf6666e1e 100644 --- a/test/lib/commands/exec.js +++ b/test/lib/commands/exec.js @@ -190,9 +190,14 @@ t.test('npx foo, bin already exists globally', async t => { t.test('npm exec foo, already present locally', async t => { const path = t.testdir() + const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -339,10 +344,18 @@ t.test('npm exec foo, not present locally or in central loc', async t => { const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -375,12 +388,21 @@ t.test('npm exec foo, not present locally or in central loc', async t => { t.test('npm exec foo, not present locally but in central loc', async t => { const path = t.testdir() const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') + const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -413,12 +435,21 @@ t.test('npm exec foo, not present locally but in central loc', async t => { t.test('npm exec foo, present locally but wrong version', async t => { const path = t.testdir() const installDir = resolve('npx-cache-dir/2badf4630f1cfaad') + const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } MANIFESTS['foo@2.x'] = { name: 'foo', @@ -448,11 +479,63 @@ t.test('npm exec foo, present locally but wrong version', async t => { ]) }) +t.test('npm exec foo, present locally but outdated version', async t => { + const path = t.testdir() + const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') + const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } + npm.localPrefix = path + ARB_ACTUAL_TREE[path] = { + inventory: { + query () { + return new Set() + }, + }, + } + ARB_ACTUAL_TREE[installDir] = { + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, + } + MANIFESTS.foo = { + name: 'foo', + version: '2.3.4', + bin: { + foo: 'foo', + }, + _from: 'foo@2.x', + } + await exec.exec(['foo', 'one arg', 'two arg']) + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ path }]) + t.match(ARB_REIFY, [{ add: ['foo'], legacyPeerDeps: false }], 'need to add foo@2.x') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [ + { + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }, + ]) +}) + t.test('npm exec --package=foo bar', async t => { const path = t.testdir() + const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -499,9 +582,18 @@ t.test('npm exec @foo/bar -- --some=arg, locally installed', async t => { }, }, }) + const pkg = { + name: '@foo/bar', + version: '1.2.3', + bin: { foo: 'foo', bar: 'bar' }, + } npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map([['@foo/bar', { name: '@foo/bar', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } MANIFESTS['@foo/bar'] = foobarManifest await exec.exec(['@foo/bar', '--some=arg']) @@ -526,7 +618,7 @@ t.test('npm exec @foo/bar -- --some=arg, locally installed', async t => { t.test( 'npm exec @foo/bar, with same bin alias and no unscoped named bin, locally installed', async t => { - const foobarManifest = { + const pkg = { name: '@foo/bar', version: '1.2.3', bin: { @@ -538,15 +630,19 @@ t.test( const path = t.testdir({ node_modules: { '@foo/bar': { - 'package.json': JSON.stringify(foobarManifest), + 'package.json': JSON.stringify(pkg), }, }, }) npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map([['@foo/bar', { name: '@foo/bar', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } - MANIFESTS['@foo/bar'] = foobarManifest + MANIFESTS['@foo/bar'] = pkg await exec.exec(['@foo/bar', 'one arg', 'two arg']) t.strictSame(MKDIRPS, [], 'no need to make any dirs') t.match(ARB_CTOR, [{ path }]) @@ -571,9 +667,22 @@ t.test( 'npm exec @foo/bar, with different bin alias and no unscoped named bin, locally installed', async t => { const path = t.testdir() + const pkg = { + name: '@foo/bar', + version: '1.2.3.', + bin: { foo: 'qux', corge: 'qux', baz: 'quux' }, + } npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map([['@foo/bar', { name: '@foo/bar', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ + ...pkg, + package: pkg, + pkgid: `${pkg.name}@${pkg.version}`, + }]) + }, + }, } MANIFESTS['@foo/bar'] = { name: '@foo/bar', @@ -609,10 +718,18 @@ t.test('run command with 2 packages, need install, verify sort', async t => { const installDir = resolve('npx-cache-dir/07de77790e5f40f2') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -653,10 +770,25 @@ t.test('run command with 2 packages, need install, verify sort', async t => { }) t.test('npm exec foo, no bin in package', async t => { - const path = t.testdir() + const pkg = { name: 'foo', version: '1.2.3' } + const path = t.testdir({ + node_modules: { + foo: { + 'package.json': JSON.stringify(pkg), + }, + }, + }) npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ + ...pkg, + package: pkg, + pkgid: `${pkg.name}@${pkg.version}`, + }]) + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -672,9 +804,22 @@ t.test('npm exec foo, no bin in package', async t => { t.test('npm exec foo, many bins in package, none named foo', async t => { const path = t.testdir() + const pkg = { + name: 'foo', + version: '1.2.3', + bin: { bar: 'bar', baz: 'baz' }, + } npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ + ...pkg, + package: pkg, + pkgid: `${pkg.name}@${pkg.version}`, + }]) + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -694,11 +839,16 @@ t.test('npm exec foo, many bins in package, none named foo', async t => { t.test('npm exec -p foo -c "ls -laF"', async t => { const path = t.testdir() + const pkg = { name: 'foo', version: '1.2.3' } npm.localPrefix = path config.package = ['foo'] config.call = 'ls -laF' ARB_ACTUAL_TREE[path] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -751,10 +901,18 @@ t.test('prompt when installs are needed if not already present and shell is a TT const installDir = resolve('npx-cache-dir/07de77790e5f40f2') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -823,10 +981,18 @@ t.test( const installDir = resolve('npx-cache-dir/07de77790e5f40f2') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -896,10 +1062,18 @@ t.test( const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -957,10 +1131,18 @@ t.test('abort if prompt rejected', async t => { const installDir = resolve('npx-cache-dir/07de77790e5f40f2') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -1014,10 +1196,18 @@ t.test('abort if prompt false', async t => { const installDir = resolve('npx-cache-dir/07de77790e5f40f2') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -1070,10 +1260,18 @@ t.test('abort if -n provided', async t => { const installDir = resolve('npx-cache-dir/07de77790e5f40f2') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', @@ -1105,10 +1303,18 @@ t.test('forward legacyPeerDeps opt', async t => { const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') npm.localPrefix = path ARB_ACTUAL_TREE[path] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } ARB_ACTUAL_TREE[installDir] = { - children: new Map(), + inventory: { + query () { + return new Set() + }, + }, } MANIFESTS.foo = { name: 'foo', diff --git a/workspaces/libnpmexec/lib/index.js b/workspaces/libnpmexec/lib/index.js index 81d152a20bd6e..fbe5c5520c381 100644 --- a/workspaces/libnpmexec/lib/index.js +++ b/workspaces/libnpmexec/lib/index.js @@ -9,15 +9,14 @@ const npmlog = require('npmlog') const mkdirp = require('mkdirp-infer-owner') const npa = require('npm-package-arg') const pacote = require('pacote') -const readPackageJson = require('read-package-json-fast') const cacheInstallDir = require('./cache-install-dir.js') const { fileExists, localFileExists } = require('./file-exists.js') const getBinFromManifest = require('./get-bin-from-manifest.js') -const manifestMissing = require('./manifest-missing.js') const noTTY = require('./no-tty.js') const runScript = require('./run-script.js') const isWindows = require('./is-windows.js') +const _localManifest = Symbol('localManifest') /* istanbul ignore next */ const PATH = ( @@ -86,20 +85,42 @@ const exec = async (opts) => { packages.push(args[0]) } + // figure out whether we need to install stuff, or if local is fine + const localArb = new Arborist({ + ...flatOptions, + path, + }) + const localTree = await localArb.loadActual() + + const getLocalManifest = ({ tree, name }) => { + // look up the package name in the current tree inventory, + // if it's found then return that normalized pkg data + const [node] = tree.inventory.query('packageName', name) + + if (node) { + return { + _id: node.pkgid, + ...node.package, + [_localManifest]: true, + } + } + } + // If we do `npm exec foo`, and have a `foo` locally, then we'll // always use that, so we don't really need to fetch the manifest. // So: run npa on each packages entry, and if it is a name with a - // rawSpec==='', then try to readPackageJson at - // node_modules/${name}/package.json, and only pacote fetch if - // that fails. + // rawSpec==='', then try to find that node name in the tree inventory + // and only pacote fetch if that fails. const manis = await Promise.all(packages.map(async p => { const spec = npa(p, path) if (spec.type === 'tag' && spec.rawSpec === '') { - // fall through to the pacote.manifest() approach - try { - const pj = resolve(path, 'node_modules', spec.name, 'package.json') - return await readPackageJson(pj) - } catch (er) {} + const localManifest = getLocalManifest({ + tree: localTree, + name: spec.name, + }) + if (localManifest) { + return localManifest + } } // Force preferOnline to true so we are making sure to pull in the latest // This is especially useful if the user didn't give us a version, and @@ -114,16 +135,9 @@ const exec = async (opts) => { args[0] = getBinFromManifest(manis[0]) } - // figure out whether we need to install stuff, or if local is fine - const localArb = new Arborist({ - ...flatOptions, - path, - }) - const localTree = await localArb.loadActual() - - // do we have all the packages in manifest list? + // are all packages from the manifest list installed? const needInstall = - manis.some(manifest => manifestMissing({ tree: localTree, manifest })) + manis.some(manifest => !manifest[_localManifest]) if (needInstall) { const { npxCache } = flatOptions @@ -135,16 +149,23 @@ const exec = async (opts) => { }) const tree = await arb.loadActual() + // inspect the npx-space installed tree to check if the package is already + // there, if that's the case also check that it's version matches the same + // version expected by the user requested pkg returned by pacote.manifest + const filterMissingPackagesFromInstallDir = (mani) => { + const localManifest = getLocalManifest({ tree, name: mani.name }) + if (localManifest) { + return localManifest.version !== mani.version + } + return true + } + // at this point, we have to ensure that we get the exact same // version, because it's something that has only ever been installed // by npm exec in the cache install directory - const add = manis.filter(mani => manifestMissing({ - tree, - manifest: { - ...mani, - _from: `${mani.name}@${mani.version}`, - }, - })) + const add = manis + .filter(mani => !mani[_localManifest]) + .filter(filterMissingPackagesFromInstallDir) .map(mani => mani._from) .sort((a, b) => a.localeCompare(b, 'en')) diff --git a/workspaces/libnpmexec/lib/manifest-missing.js b/workspaces/libnpmexec/lib/manifest-missing.js deleted file mode 100644 index aec1281e3a4bf..0000000000000 --- a/workspaces/libnpmexec/lib/manifest-missing.js +++ /dev/null @@ -1,19 +0,0 @@ -const manifestMissing = ({ tree, manifest }) => { - // if the tree doesn't have a child by that name/version, return true - // true means we need to install it - const child = tree.children.get(manifest.name) - // if no child, we have to load it - if (!child) { - return true - } - - // if no version/tag specified, allow whatever's there - if (manifest._from === `${manifest.name}@`) { - return false - } - - // otherwise the version has to match what we WOULD get - return child.version !== manifest.version -} - -module.exports = manifestMissing diff --git a/workspaces/libnpmexec/test/manifest-missing.js b/workspaces/libnpmexec/test/manifest-missing.js deleted file mode 100644 index e7ce1c851ab49..0000000000000 --- a/workspaces/libnpmexec/test/manifest-missing.js +++ /dev/null @@ -1,32 +0,0 @@ -const t = require('tap') -const Arborist = require('@npmcli/arborist') - -const manifestMissing = require('../lib/manifest-missing.js') - -t.test('missing version', async t => { - const path = t.testdir({ - node_modules: { - a: { - 'package.json': JSON.stringify({ - name: 'a', - version: '1.0.0', - }), - }, - }, - 'package.json': JSON.stringify({ - name: 'root', - dependencies: { - a: '^1.0.0', - }, - }), - }) - const arb = new Arborist({ - path, - }) - const tree = await arb.loadActual() - const manifest = { - name: 'a', - _from: 'a@', - } - t.notOk(manifestMissing({ tree, manifest }), 'manifest not missing') -}) From ced0acfe5998a5be9313815f76f5c1439a09db78 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 19 Apr 2022 11:29:05 -0700 Subject: [PATCH 069/406] fix: consolidate registryConfig application logic It should happen whenever we read a manifest anyways. Tests were also rewritten to be real. --- lib/commands/publish.js | 31 +- .../test/lib/commands/publish.js.test.cjs | 324 +++-- test/fixtures/mock-npm.js | 2 +- test/lib/commands/publish.js | 1244 +++++++---------- 4 files changed, 715 insertions(+), 886 deletions(-) diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 51861c5aa3554..ff30366938786 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -69,10 +69,6 @@ class Publish extends BaseCommand { const spec = npa(args[0]) let manifest = await this.getManifest(spec, opts) - if (manifest.publishConfig) { - flatten(manifest.publishConfig, opts) - } - // only run scripts for directory type publishes if (spec.type === 'directory' && !ignoreScripts) { await runScript({ @@ -92,12 +88,8 @@ class Publish extends BaseCommand { // so that we send the latest and greatest thing to the registry // note that publishConfig might have changed as well! manifest = await this.getManifest(spec, opts) - if (manifest.publishConfig) { - flatten(manifest.publishConfig, opts) - } - // note that logTar calls log.notice(), so if we ARE in silent mode, - // this will do nothing, but we still want it in the debuglog if it fails. + // JSON already has the package contents if (!json) { logTar(pkgContents, { unicode }) } @@ -197,15 +189,22 @@ class Publish extends BaseCommand { // if it's a directory, read it from the file system // otherwise, get the full metadata from whatever it is - getManifest (spec, opts) { + // XXX can't pacote read the manifest from a directory? + async getManifest (spec, opts) { + let manifest if (spec.type === 'directory') { - return readJson(`${spec.fetchSpec}/package.json`) + manifest = await readJson(`${spec.fetchSpec}/package.json`) + } else { + manifest = await pacote.manifest(spec, { + ...opts, + fullmetadata: true, + fullReadJson: true, + }) + } + if (manifest.publishConfig) { + flatten(manifest.publishConfig, opts) } - return pacote.manifest(spec, { - ...opts, - fullMetadata: true, - fullReadJson: true, - }) + return manifest } } module.exports = Publish diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index dec7727834fa6..c6f757e8a9b2e 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -5,153 +5,251 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/commands/publish.js TAP private workspaces colorless > should output all publishes 1`] = ` +exports[`test/lib/commands/publish.js TAP dry-run > must match snapshot 1`] = ` Array [ - "+ @npmcli/b@1.0.0", + Array [ + "", + ], + Array [ + "", + "package: test-package@1.0.0", + ], + Array [ + "=== Tarball Contents ===", + ], + Array [ + "", + "87B package.json", + ], + Array [ + "=== Tarball Details ===", + ], + Array [ + "", + String( + name: test-package + version: 1.0.0 + filename: test-package-1.0.0.tgz + package size: 160 B + unpacked size: 87 B + shasum:{sha} + integrity:{sha} + total files: 1 + ), + ], + Array [ + "", + "", + ], + Array [ + "", + "Publishing to https://registry.npmjs.org/ (dry-run)", + ], ] ` -exports[`test/lib/commands/publish.js TAP private workspaces colorless > should publish all non-private workspaces 1`] = ` -Array [ - Object { - "_id": "@npmcli/b@1.0.0", - "name": "@npmcli/b", - "readme": "ERROR: No README data found!", - "version": "1.0.0", - }, -] +exports[`test/lib/commands/publish.js TAP has auth for scope configured registry > new package version 1`] = ` ++ @npm/test-package@1.0.0 ` -exports[`test/lib/commands/publish.js TAP private workspaces with color > should output all publishes 1`] = ` +exports[`test/lib/commands/publish.js TAP ignore-scripts > new package version 1`] = ` ++ test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP json > must match snapshot 1`] = ` Array [ - "+ @npmcli/b@1.0.0", + Array [ + "", + "Publishing to https://registry.npmjs.org/", + ], ] ` -exports[`test/lib/commands/publish.js TAP private workspaces with color > should publish all non-private workspaces 1`] = ` +exports[`test/lib/commands/publish.js TAP json > new package json 1`] = ` +{ + "id": "test-package@1.0.0", + "name": "test-package", + "version": "1.0.0", + "size": 160, + "unpackedSize": 87, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "test-package-1.0.0.tgz", + "files": [ + { + "path": "package.json", + "size": 87, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] +} +` + +exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot 1`] = ` ++ test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = ` Array [ - Object { - "_id": "@npmcli/b@1.0.0", - "name": "@npmcli/b", - "readme": "ERROR: No README data found!", - "version": "1.0.0", - }, + Array [ + "", + "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)", + ], ] ` -exports[`test/lib/commands/publish.js TAP workspaces all workspaces > should output all publishes 1`] = ` +exports[`test/lib/commands/publish.js TAP re-loads publishConfig.registry if added during script process > new package version 1`] = ` ++ test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = ` + +` + +exports[`test/lib/commands/publish.js TAP tarball > must match snapshot 1`] = ` Array [ - "+ workspace-a@1.2.3-a", - "+ workspace-b@1.2.3-n", - "+ workspace-n@1.2.3-n", + Array [ + "", + ], + Array [ + "", + "package: test-tar-package@1.0.0", + ], + Array [ + "=== Tarball Contents ===", + ], + Array [ + "", + String( + 26B index.js + 98B package.json + ), + ], + Array [ + "=== Tarball Details ===", + ], + Array [ + "", + String( + name: test-tar-package + version: 1.0.0 + filename: test-tar-package-1.0.0.tgz + package size: 218 B + unpacked size: 124 B + shasum:{sha} + integrity:{sha} + total files: 2 + ), + ], + Array [ + "", + "", + ], + Array [ + "", + "Publishing to https://registry.npmjs.org/", + ], ] ` -exports[`test/lib/commands/publish.js TAP workspaces all workspaces > should publish all workspaces 1`] = ` +exports[`test/lib/commands/publish.js TAP tarball > new package json 1`] = ` ++ test-tar-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > all public workspaces 1`] = ` ++ workspace-a@1.2.3-a ++ workspace-b@1.2.3-n ++ workspace-n@1.2.3-n +` + +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > warns about skipped private workspace in color 1`] = ` Array [ - Object { - "_id": "workspace-a@1.2.3-a", - "name": "workspace-a", - "readme": "ERROR: No README data found!", - "repository": Object { - "type": "git", - "url": "http://repo.workspace-a/", - }, - "version": "1.2.3-a", - }, - Object { - "_id": "workspace-b@1.2.3-n", - "bugs": Object { - "url": "https://github.com/npm/workspace-b/issues", - }, - "homepage": "https://github.com/npm/workspace-b#readme", - "name": "workspace-b", - "readme": "ERROR: No README data found!", - "repository": Object { - "type": "git", - "url": "git+https://github.com/npm/workspace-b.git", - }, - "version": "1.2.3-n", - }, - Object { - "_id": "workspace-n@1.2.3-n", - "name": "workspace-n", - "readme": "ERROR: No README data found!", - "version": "1.2.3-n", - }, + Array [ + "publish", + "Skipping workspace \\u001b[32mworkspace-p\\u001b[39m, marked as \\u001b[1mprivate\\u001b[22m", + ], ] ` -exports[`test/lib/commands/publish.js TAP workspaces json > should output all publishes as json 1`] = ` +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > all public workspaces 1`] = ` ++ workspace-a@1.2.3-a ++ workspace-b@1.2.3-n ++ workspace-n@1.2.3-n +` + +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > warns about skipped private workspace 1`] = ` Array [ - String( - { - "workspace-a": { - "id": "workspace-a@1.2.3-a" - }, - "workspace-b": { - "id": "workspace-b@1.2.3-n" - }, - "workspace-n": { - "id": "workspace-n@1.2.3-n" - } - } - ), + Array [ + "publish", + "Skipping workspace workspace-p, marked as private", + ], ] ` -exports[`test/lib/commands/publish.js TAP workspaces json > should publish all workspaces 1`] = ` -Array [ - Object { - "_id": "workspace-a@1.2.3-a", +exports[`test/lib/commands/publish.js TAP workspaces json > all workspaces in json 1`] = ` +{ + "workspace-a": { + "id": "workspace-a@1.2.3-a", "name": "workspace-a", - "readme": "ERROR: No README data found!", - "repository": Object { - "type": "git", - "url": "http://repo.workspace-a/", - }, "version": "1.2.3-a", + "size": 162, + "unpackedSize": 82, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "workspace-a-1.2.3-a.tgz", + "files": [ + { + "path": "package.json", + "size": 82, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] }, - Object { - "_id": "workspace-b@1.2.3-n", - "bugs": Object { - "url": "https://github.com/npm/workspace-b/issues", - }, - "homepage": "https://github.com/npm/workspace-b#readme", + "workspace-b": { + "id": "workspace-b@1.2.3-n", "name": "workspace-b", - "readme": "ERROR: No README data found!", - "repository": Object { - "type": "git", - "url": "git+https://github.com/npm/workspace-b.git", - }, "version": "1.2.3-n", + "size": 171, + "unpackedSize": 92, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "workspace-b-1.2.3-n.tgz", + "files": [ + { + "path": "package.json", + "size": 92, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] }, - Object { - "_id": "workspace-n@1.2.3-n", + "workspace-n": { + "id": "workspace-n@1.2.3-n", "name": "workspace-n", - "readme": "ERROR: No README data found!", "version": "1.2.3-n", - }, -] -` - -exports[`test/lib/commands/publish.js TAP workspaces one workspace > should output one publish 1`] = ` -Array [ - "+ workspace-a@1.2.3-a", -] + "size": 140, + "unpackedSize": 42, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "workspace-n-1.2.3-n.tgz", + "files": [ + { + "path": "package.json", + "size": 42, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] + } +} ` -exports[`test/lib/commands/publish.js TAP workspaces one workspace > should publish given workspace 1`] = ` -Array [ - Object { - "_id": "workspace-a@1.2.3-a", - "name": "workspace-a", - "readme": "ERROR: No README data found!", - "repository": Object { - "type": "git", - "url": "http://repo.workspace-a/", - }, - "version": "1.2.3-a", - }, -] +exports[`test/lib/commands/publish.js TAP workspaces one workspace - success > single workspace 1`] = ` ++ workspace-a@1.2.3-a ` diff --git a/test/fixtures/mock-npm.js b/test/fixtures/mock-npm.js index b6742a425aa9a..4263dc8fbedc3 100644 --- a/test/fixtures/mock-npm.js +++ b/test/fixtures/mock-npm.js @@ -118,7 +118,7 @@ const LoadMockNpm = async (t, { mockGlobals(t, { 'process.env.HOME': home, 'process.env.npm_config_cache': cache, - ...(globals ? result(globals, { prefix, cache }) : {}), + ...(globals ? result(globals, { prefix, cache, home }) : {}), // Some configs don't work because they can't be set via npm.config.set until // config is loaded. But some config items are needed before that. So this is // an explicit set of configs that must be loaded as env vars. diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index 64eb7c60cb062..b17424b084461 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -1,271 +1,189 @@ const t = require('tap') -const { fake: mockNpm } = require('../../fixtures/mock-npm') -const fs = require('fs') +const { load: loadMockNpm } = require('../../fixtures/mock-npm') +const MockRegistry = require('../../fixtures/mock-registry.js') +const pacote = require('pacote') +const path = require('path') +const fs = require('@npmcli/fs') +const npa = require('npm-package-arg') + +const pkg = 'test-package' +const token = 'test-auth-token' +const auth = { '//registry.npmjs.org/:_authToken': token } +const alternateRegistry = 'https://other.registry.npmjs.org' + +const pkgJson = { + name: pkg, + description: 'npm test package', + version: '1.0.0', +} t.cleanSnapshot = data => { - return data.replace(/^ *"gitHead": .*$\n/gm, '') + return data.replace(/shasum:.*/g, 'shasum:{sha}') + .replace(/integrity:.*/g, 'integrity:{sha}') + .replace(/"shasum": ".*",/g, '"shasum": "{sha}",') + .replace(/"integrity": ".*",/g, '"integrity": "{sha}",') } -const { definitions } = require('../../../lib/utils/config') -const defaults = Object.entries(definitions).reduce((defaults, [key, def]) => { - defaults[key] = def.default - return defaults -}, {}) - -t.test( - /* eslint-disable-next-line max-len */ - 'should publish with libnpmpublish, passing through flatOptions and respecting publishConfig.registry', - async t => { - t.plan(6) - - const registry = 'https://some.registry' - const publishConfig = { registry } - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', - version: '1.0.0', - publishConfig, +t.test('respects publishConfig.registry, runs appropriate scripts', async t => { + const { npm, joinedOutput, prefix } = await loadMockNpm(t, { + config: { + loglevel: 'silent', // prevent scripts from leaking to stdout during the test + [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token', + }, + prefixDir: { + 'package.json': JSON.stringify({ + ...pkgJson, + scripts: { + prepublishOnly: 'touch scripts-prepublishonly', + prepublish: 'touch scripts-prepublish', // should NOT run this one + publish: 'touch scripts-publish', + postpublish: 'touch scripts-postpublish', }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js', { - // verify that we do NOT remove publishConfig if it was there originally - // and then removed during the script/pack process - libnpmpack: async () => { - fs.writeFileSync( - `${testDir}/package.json`, - JSON.stringify({ - name: 'my-cool-pkg', - version: '1.0.0', - }) - ) - return Buffer.from('') - }, - libnpmpublish: { - publish: (manifest, tarData, opts) => { - t.match(manifest, { name: 'my-cool-pkg', version: '1.0.0' }, 'gets manifest') - t.type(tarData, Buffer, 'tarData is a buffer') - t.ok(opts, 'gets opts object') - t.same(opts.customValue, true, 'flatOptions values are passed through') - t.same(opts.registry, registry, 'publishConfig.registry is passed through') + publishConfig: { registry: alternateRegistry }, + }, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + const registry = new MockRegistry({ + tap: t, + registry: alternateRegistry, + authorization: 'test-other-token', + }) + registry.nock.put(`/${pkg}`, body => { + return t.match(body, { + _id: pkg, + name: pkg, + 'dist-tags': { latest: '1.0.0' }, + access: null, + versions: { + '1.0.0': { + name: pkg, + version: '1.0.0', + _id: `${pkg}@1.0.0`, + dist: { + shasum: /\.*/, + tarball: `http:${alternateRegistry.slice(6)}/test-package/-/test-package-1.0.0.tgz`, + }, + publishConfig: { + registry: alternateRegistry, + }, }, }, - }) - const npm = mockNpm({ - flatOptions: { - customValue: true, - workspacesEnabled: true, + _attachments: { + [`${pkg}-1.0.0.tgz`]: {}, }, }) - npm.config.getCredentialsByURI = uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - - await publish.exec([testDir]) - } -) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'new package version') + t.resolveMatch(fs.exists(path.join(prefix, 'scripts-prepublishonly')), true, 'ran prepublishOnly') + t.resolveMatch( + fs.exists(path.join(prefix, 'scripts-prepublish')), + false, + 'did not run prepublish' + ) + t.resolveMatch(fs.exists(path.join(prefix, 'scripts-publish')), true, 'ran publish') + t.resolveMatch(fs.exists(path.join(prefix, 'scripts-postpublish')), true, 'ran postpublish') +}) t.test('re-loads publishConfig.registry if added during script process', async t => { - t.plan(5) - const registry = 'https://some.registry' - const publishConfig = { registry } - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', - version: '1.0.0', - }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js', { - libnpmpack: async () => { - fs.writeFileSync( - `${testDir}/package.json`, - JSON.stringify({ - name: 'my-cool-pkg', - version: '1.0.0', - publishConfig, - }) - ) - return Buffer.from('') - }, - libnpmpublish: { - publish: (manifest, tarData, opts) => { - t.match(manifest, { name: 'my-cool-pkg', version: '1.0.0' }, 'gets manifest') - t.type(tarData, Buffer, 'tarData is a buffer') - t.ok(opts, 'gets opts object') - t.same(opts.registry, registry, 'publishConfig.registry is passed through') - }, + const { joinedOutput, npm } = await loadMockNpm(t, { + config: { + [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token', }, - }) - const npm = mockNpm() - npm.config.getCredentialsByURI = uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - - await publish.exec([testDir]) -}) - -t.test('if loglevel=info and json, should not output package contents', async t => { - t.plan(3) - - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', - version: '1.0.0', - }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js', { - '../../../lib/utils/tar.js': { - getContents: () => ({ - id: 'someid', + prefixDir: { + 'package.json': JSON.stringify({ + ...pkgJson, + scripts: { + prepare: 'cp new.json package.json', + }, + }, null, 2), + 'new.json': JSON.stringify({ + ...pkgJson, + publishConfig: { registry: alternateRegistry }, }), - logTar: () => { - t.fail('logTar is not called in json mode') - }, - }, - libnpmpublish: { - publish: () => { - t.pass('publish called') - }, }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - const npm = mockNpm({ - config: { json: true, loglevel: 'info' }, - output: () => { - t.pass('output is called') - }, - }, t) - npm.config.getCredentialsByURI = uri => { - t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - - await publish.exec([testDir]) -}) - -t.test( - /* eslint-disable-next-line max-len */ - 'if loglevel=silent and dry-run, should not output package contents or publish, should log tarball contents', - async t => { - t.plan(2) - - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', + const registry = new MockRegistry({ + tap: t, + registry: alternateRegistry, + authorization: 'test-other-token', + }) + registry.nock.put(`/${pkg}`, body => { + return t.match(body, { + _id: pkg, + name: pkg, + 'dist-tags': { latest: '1.0.0' }, + access: null, + versions: { + '1.0.0': { + name: pkg, version: '1.0.0', - }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js', { - '../../../lib/utils/tar.js': { - getContents: () => ({ - id: 'someid', - }), - logTar: () => { - t.pass('logTar is called') - }, - }, - libnpmpublish: { - publish: () => { - throw new Error('should not call libnpmpublish in dry run') - }, - }, - }) - const npm = mockNpm({ - config: { 'dry-run': true, loglevel: 'silent' }, - output: () => { - throw new Error('should not output in dry run mode') - }, - }, t) - npm.config.getCredentialsByURI = uri => { - t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - - const publish = new Publish(npm) - - await publish.exec([testDir]) - } -) - -t.test( - /* eslint-disable-next-line max-len */ - 'if loglevel=info and dry-run, should not publish, should log package contents and log tarball contents', - async t => { - t.plan(3) - - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', - version: '1.0.0', - }, - null, - 2 - ), - }) - - const npm = mockNpm({ - config: { 'dry-run': true, loglevel: 'info' }, - output: () => { - t.pass('output fn is called') - }, - }, t) - const registry = npm.config.get('registry') - npm.config.getCredentialsByURI = uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return { /* no token will call log.warn */ } - } - - const Publish = t.mock('../../../lib/commands/publish.js', { - '../../../lib/utils/tar.js': { - getContents: () => ({ - id: 'someid', - }), - logTar: () => { - t.pass('logTar is called') - }, - 'proc-log': { - warn (_, msg) { - t.match(msg, - `This command requires you to be logged in to ${registry} (dry-run)`) + _id: `${pkg}@1.0.0`, + dist: { + shasum: /\.*/, + tarball: `http:${alternateRegistry.slice(6)}/test-package/-/test-package-1.0.0.tgz`, + }, + publishConfig: { + registry: alternateRegistry, }, }, }, - libnpmpublish: { - publish: () => { - throw new Error('should not call libnpmpublish in dry run') - }, + _attachments: { + [`${pkg}-1.0.0.tgz`]: {}, }, }) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'new package version') +}) - const publish = new Publish(npm) +t.test('json', async t => { + const { joinedOutput, npm, logs } = await loadMockNpm(t, { + config: { + json: true, + ...auth, + }, + prefixDir: { + 'package.json': JSON.stringify(pkgJson, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock.put(`/${pkg}`).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(logs.notice) + t.matchSnapshot(joinedOutput(), 'new package json') +}) - await publish.exec([testDir]) - } -) +t.test('dry-run', async t => { + const { joinedOutput, npm, logs } = await loadMockNpm(t, { + config: { + 'dry-run': true, + ...auth, + }, + prefixDir: { + 'package.json': JSON.stringify(pkgJson, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + await npm.exec('publish', []) + t.equal(joinedOutput(), `+ ${pkg}@1.0.0`) + t.matchSnapshot(logs.notice) +}) t.test('shows usage with wrong set of arguments', async t => { t.plan(1) @@ -276,279 +194,174 @@ t.test('shows usage with wrong set of arguments', async t => { }) t.test('throws when invalid tag', async t => { - t.plan(1) - - const Publish = t.mock('../../../lib/commands/publish.js') - const npm = mockNpm({ - config: { tag: '0.0.13' }, + const { npm } = await loadMockNpm(t, { + config: { + tag: '0.0.13', + }, + prefixDir: { + 'package.json': JSON.stringify(pkgJson, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - const publish = new Publish(npm) - await t.rejects( - publish.exec([]), - /Tag name must not be a valid SemVer range: /, - 'throws when tag name is a valid SemVer range' + npm.exec('publish', []), + { message: 'Tag name must not be a valid SemVer range: 0.0.13' } ) }) -t.test('can publish a tarball', async t => { - t.plan(3) - - const testDir = t.testdir({ - tarball: {}, - package: { +t.test('tarball', async t => { + const { npm, joinedOutput, logs, home } = await loadMockNpm(t, { + config: { + 'fetch-retries': 0, + ...auth, + }, + homeDir: { 'package.json': JSON.stringify({ - name: 'my-cool-tarball', - version: '1.2.3', - }), - 'README.md': 'This is my readme', + name: 'test-tar-package', + description: 'this was from a tarball', + version: '1.0.0', + }, null, 2), + 'index.js': 'console.log("hello world"}', }, }) - const tar = require('tar') - tar.c( - { - cwd: testDir, - file: `${testDir}/tarball/package.tgz`, - sync: true, - }, - ['package'] - ) + const tarball = await pacote.tarball(home) + const tarFilename = path.join(home, 'tarball.tgz') + await fs.writeFile(tarFilename, tarball) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock.put('/test-tar-package', body => { + return t.match(body, { + name: 'test-tar-package', + }) + }).reply(200, {}) + await npm.exec('publish', [tarFilename]) + t.matchSnapshot(logs.notice) + t.matchSnapshot(joinedOutput(), 'new package json') +}) - const tarFile = fs.readFileSync(`${testDir}/tarball/package.tgz`) - const Publish = t.mock('../../../lib/commands/publish.js', { - libnpmpublish: { - publish: (manifest, tarData, opts) => { - t.match( - manifest, - { - name: 'my-cool-tarball', - version: '1.2.3', - readme: 'This is my readme', - description: 'This is my readme', - readmeFilename: 'README.md', - }, - 'sent manifest to lib pub' - ) - t.strictSame(tarData, tarFile, 'sent the tarball data to lib pub') - }, +t.test('no auth default registry', async t => { + const { npm } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify(pkgJson, null, 2), }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - const npm = mockNpm() - npm.config.getCredentialsByURI = uri => { - t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - - await publish.exec([`${testDir}/tarball/package.tgz`]) -}) - -t.test('should check auth for default registry', async t => { - t.plan(2) - const npm = mockNpm() - const registry = npm.config.get('registry') - const errorMessage = `This command requires you to be logged in to ${registry}` - const Publish = t.mock('../../../lib/commands/publish.js') - npm.config.getCredentialsByURI = uri => { - t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') - return {} - } - const publish = new Publish(npm) - await t.rejects( - publish.exec([]), - { message: errorMessage, code: 'ENEEDAUTH' }, - 'throws when not logged in' + npm.exec('publish', []), + { + message: 'This command requires you to be logged in to https://registry.npmjs.org/', + code: 'ENEEDAUTH', + } ) }) -t.test('should check auth for configured registry', async t => { - t.plan(2) - const registry = 'https://some.registry' - const errorMessage = 'This command requires you to be logged in to https://some.registry' - const Publish = t.mock('../../../lib/commands/publish.js') - const npm = mockNpm({ - flatOptions: { registry }, +t.test('no auth dry-run', async t => { + const { npm, joinedOutput, logs } = await loadMockNpm(t, { + config: { + 'dry-run': true, + }, + prefixDir: { + 'package.json': JSON.stringify(pkgJson, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - npm.config.getCredentialsByURI = uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return {} - } - const publish = new Publish(npm) - - await t.rejects( - publish.exec([]), - { message: errorMessage, code: 'ENEEDAUTH' }, - 'throws when not logged in' - ) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput()) + t.matchSnapshot(logs.warn, 'warns about auth being needed') }) -t.test('should check auth for scope specific registry', async t => { - t.plan(2) - const registry = 'https://some.registry' - const errorMessage = 'This command requires you to be logged in to https://some.registry' - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: '@npm/my-cool-pkg', - version: '1.0.0', - }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js') - const npm = mockNpm({ - flatOptions: { '@npm:registry': registry }, +t.test('no auth for configured registry', async t => { + const { npm } = await loadMockNpm(t, { + config: { + registry: alternateRegistry, + ...auth, + }, + prefixDir: { + 'package.json': JSON.stringify(pkgJson, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - npm.config.getCredentialsByURI = uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return {} - } - const publish = new Publish(npm) - await t.rejects( - publish.exec([testDir]), - { message: errorMessage, code: 'ENEEDAUTH' }, - 'throws when not logged in' + npm.exec('publish', []), + { + message: `This command requires you to be logged in to ${alternateRegistry}`, + code: 'ENEEDAUTH', + } ) }) -t.test('should use auth for scope specific registry', async t => { - t.plan(3) - const registry = 'https://some.registry' - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: '@npm/my-cool-pkg', - version: '1.0.0', - }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js', { - libnpmpublish: { - publish: (manifest, tarData, opts) => { - t.ok(opts, 'gets opts object') - t.same(opts['@npm:registry'], registry, 'scope specific registry is passed through') - }, +t.test('no auth for scope configured registry', async t => { + const { npm } = await loadMockNpm(t, { + config: { + '@npm:registry': alternateRegistry, + ...auth, }, - }) - const npm = mockNpm({ - flatOptions: { '@npm:registry': registry }, - }) - npm.config.getCredentialsByURI = uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - - await publish.exec([testDir]) -}) - -t.test('read registry only from publishConfig', async t => { - t.plan(3) - - const registry = 'https://some.registry' - const publishConfig = { registry } - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', + prefixDir: { + 'package.json': JSON.stringify({ + name: '@npm/test-package', version: '1.0.0', - publishConfig, - }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js', { - libnpmpublish: { - publish: (manifest, tarData, opts) => { - t.match(manifest, { name: 'my-cool-pkg', version: '1.0.0' }, 'gets manifest') - t.same(opts.registry, registry, 'publishConfig is passed through') - }, + }, null, 2), }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - const npm = mockNpm() - npm.config.getCredentialsByURI = uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - - await publish.exec([testDir]) + await t.rejects( + npm.exec('publish', []), + { + message: `This command requires you to be logged in to ${alternateRegistry}`, + code: 'ENEEDAUTH', + } + ) }) -t.test('able to publish after if encountered multiple configs', async t => { - t.plan(2) - - const registry = 'https://some.registry' - const tag = 'better-tag' - const publishConfig = { registry } - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', +t.test('has auth for scope configured registry', async t => { + const spec = npa('@npm/test-package') + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + '@npm:registry': alternateRegistry, + [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-scope-token', + }, + prefixDir: { + 'package.json': JSON.stringify({ + name: '@npm/test-package', version: '1.0.0', - publishConfig, - }, - null, - 2 - ), - }) - - const configList = [defaults] - configList.unshift( - Object.assign(Object.create(configList[0]), { - registry: `https://other.registry`, - tag: 'some-tag', - }) - ) - configList.unshift(Object.assign(Object.create(configList[0]), { tag })) - - const Publish = t.mock('../../../lib/commands/publish.js', { - libnpmpublish: { - publish: (manifest, tarData, opts) => { - t.same(opts.defaultTag, tag, 'gets option for expected tag') - }, + }, null, 2), }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - const publish = new Publish({ - // what would be flattened by the configList created above - flatOptions: { - defaultTag: 'better-tag', - registry: 'https://other.registry', - }, - output () {}, - config: { - get: key => configList[0][key], - list: configList, - getCredentialsByURI: uri => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, + const registry = new MockRegistry({ + tap: t, + registry: alternateRegistry, + authorization: 'test-scope-token', }) - - await publish.exec([testDir]) + registry.nock.put(`/${spec.escapedName}`, body => { + return t.match(body, { name: '@npm/test-package' }) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'new package version') }) t.test('workspaces', t => { - const testDir = t.testdir({ + const dir = { 'package.json': JSON.stringify( { - name: 'my-cool-pkg', - version: '1.0.0', - workspaces: ['workspace-a', 'workspace-b', 'workspace-c'], - }, - null, - 2 - ), + ...pkgJson, + workspaces: ['workspace-a', 'workspace-b', 'workspace-c', 'workspace-p'], + }, null, 2), 'workspace-a': { 'package.json': JSON.stringify({ name: 'workspace-a', @@ -569,304 +382,223 @@ t.test('workspaces', t => { version: '1.2.3-n', }), }, - }) - - const publishes = [] - const outputs = [] - t.beforeEach(() => { - npm.config.set('json', false) - outputs.length = 0 - publishes.length = 0 - }) - const Publish = t.mock('../../../lib/commands/publish.js', { - '../../../lib/utils/tar.js': { - getContents: manifest => ({ - id: manifest._id, + 'workspace-p': { + 'package.json': JSON.stringify({ + name: 'workspace-p', + version: '1.2.3-p', + private: true, }), - logTar: () => {}, }, - libnpmpublish: { - publish: (manifest, tarballData, opts) => { - publishes.push(manifest) - }, - }, - }) - const npm = mockNpm({ - output: o => { - outputs.push(o) - }, - }) - npm.localPrefix = testDir - npm.config.getCredentialsByURI = uri => { - return { token: 'some.registry.token' } } - const publish = new Publish(npm) - t.test('all workspaces', async t => { - await publish.execWorkspaces([], []) - t.matchSnapshot(publishes, 'should publish all workspaces') - t.matchSnapshot(outputs, 'should output all publishes') - }) - - t.test('one workspace', async t => { - await publish.execWorkspaces([], ['workspace-a']) - t.matchSnapshot(publishes, 'should publish given workspace') - t.matchSnapshot(outputs, 'should output one publish') - }) - - t.test('invalid workspace', async t => { - await t.rejects(publish.execWorkspaces([], ['workspace-x']), /No workspaces found/) - await t.rejects(publish.execWorkspaces([], ['workspace-x']), /workspace-x/) - }) - - t.test('json', async t => { - npm.config.set('json', true) - await publish.execWorkspaces([], []) - t.matchSnapshot(publishes, 'should publish all workspaces') - t.matchSnapshot(outputs, 'should output all publishes as json') - }) - t.end() -}) - -t.test('private workspaces', async t => { - const testDir = t.testdir({ - 'package.json': JSON.stringify({ - name: 'workspaces-project', - version: '1.0.0', - workspaces: ['packages/*'], - }), - packages: { - a: { - 'package.json': JSON.stringify({ - name: '@npmcli/a', - version: '1.0.0', - private: true, - }), + t.test('all workspaces - no color', async t => { + const { npm, joinedOutput, logs } = await loadMockNpm(t, { + config: { + color: false, + ...auth, + workspaces: true, }, - b: { - 'package.json': JSON.stringify({ - name: '@npmcli/b', - version: '1.0.0', - }), - }, - }, - }) - - const publishes = [] - const outputs = [] - t.beforeEach(() => { - npm.config.set('json', false) - outputs.length = 0 - publishes.length = 0 - }) - const mocks = { - '../../../lib/utils/tar.js': { - getContents: manifest => ({ - id: manifest._id, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, }), - logTar: () => {}, - }, - libnpmpublish: { - publish: (manifest, tarballData, opts) => { - if (manifest.private) { - throw Object.assign(new Error('private pkg'), { code: 'EPRIVATE' }) - } - publishes.push(manifest) - }, - }, - } - const npm = mockNpm({ - config: { loglevel: 'info' }, - output: o => { - outputs.push(o) - }, - }, t) - npm.localPrefix = testDir - npm.config.getCredentialsByURI = uri => { - return { token: 'some.registry.token' } - } - - t.test('with color', async t => { - t.plan(4) - - const Publish = t.mock('../../../lib/commands/publish.js', { - ...mocks, - 'proc-log': { - notice () {}, - verbose () {}, - warn (title, msg) { - t.equal(title, 'publish', 'should use publish warn title') - t.match( - msg, - /* eslint-disable-next-line max-len */ - 'Skipping workspace \u001b[32m@npmcli/a\u001b[39m, marked as \u001b[1mprivate\u001b[22m', - 'should display skip private workspace warn msg' - ) - }, - }, + prefixDir: dir, }) - const publish = new Publish(npm) - - npm.color = true - await publish.execWorkspaces([], []) - t.matchSnapshot(publishes, 'should publish all non-private workspaces') - t.matchSnapshot(outputs, 'should output all publishes') - npm.color = false + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock + .put('/workspace-a', body => { + return t.match(body, { name: 'workspace-a' }) + }).reply(200, {}) + .put('/workspace-b', body => { + return t.match(body, { name: 'workspace-b' }) + }).reply(200, {}) + .put('/workspace-n', body => { + return t.match(body, { name: 'workspace-n' }) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'all public workspaces') + t.matchSnapshot(logs.warn, 'warns about skipped private workspace') + }) + + t.test('all workspaces - color', async t => { + const { npm, joinedOutput, logs } = await loadMockNpm(t, { + config: { + ...auth, + color: 'always', + workspaces: true, + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + prefixDir: dir, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock + .put('/workspace-a', body => { + return t.match(body, { name: 'workspace-a' }) + }).reply(200, {}) + .put('/workspace-b', body => { + return t.match(body, { name: 'workspace-b' }) + }).reply(200, {}) + .put('/workspace-n', body => { + return t.match(body, { name: 'workspace-n' }) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'all public workspaces') + t.matchSnapshot(logs.warn, 'warns about skipped private workspace in color') + }) + + t.test('one workspace - success', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + workspace: ['workspace-a'], + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + prefixDir: dir, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock + .put('/workspace-a', body => { + return t.match(body, { name: 'workspace-a' }) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'single workspace') + }) + + t.test('one workspace - failure', async t => { + const { npm } = await loadMockNpm(t, { + config: { + ...auth, + workspace: ['workspace-a'], + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + prefixDir: dir, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock + .put('/workspace-a', body => { + return t.match(body, { name: 'workspace-a' }) + }).reply(404, {}) + await t.rejects(npm.exec('publish', []), { code: 'E404' }) }) - t.test('colorless', async t => { - t.plan(4) - - const Publish = t.mock('../../../lib/commands/publish.js', { - ...mocks, - 'proc-log': { - notice () {}, - verbose () {}, - warn (title, msg) { - t.equal(title, 'publish', 'should use publish warn title') - t.equal( - msg, - 'Skipping workspace @npmcli/a, marked as private', - 'should display skip private workspace warn msg' - ) - }, + t.test('invalid workspace', async t => { + const { npm } = await loadMockNpm(t, { + config: { + ...auth, + workspace: ['workspace-x'], }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + prefixDir: dir, }) - const publish = new Publish(npm) - - await publish.execWorkspaces([], []) - t.matchSnapshot(publishes, 'should publish all non-private workspaces') - t.matchSnapshot(outputs, 'should output all publishes') + await t.rejects( + npm.exec('publish', []), + { message: 'No workspaces found:\n --workspace=workspace-x' } + ) }) - t.test('unexpected error', async t => { - t.plan(2) - - const Publish = t.mock('../../../lib/commands/publish.js', { - ...mocks, - libnpmpublish: { - publish: (manifest, tarballData, opts) => { - if (manifest.private) { - throw new Error('ERR') - } - publishes.push(manifest) - }, - }, - 'proc-log': { - notice (__, msg) { - t.match(msg, 'Publishing to https://registry.npmjs.org/') - }, - verbose () {}, - }, + t.test('json', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + workspaces: true, + json: true, + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + prefixDir: dir, }) - const publish = new Publish(npm) - - await t.rejects(publish.execWorkspaces([], []), /ERR/, 'should throw unexpected error') + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock + .put('/workspace-a', body => { + return t.match(body, { name: 'workspace-a' }) + }).reply(200, {}) + .put('/workspace-b', body => { + return t.match(body, { name: 'workspace-b' }) + }).reply(200, {}) + .put('/workspace-n', body => { + return t.match(body, { name: 'workspace-n' }) + }).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'all workspaces in json') }) - t.end() }) -t.test('runs correct lifecycle scripts', async t => { - t.plan(5) - - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', - version: '1.0.0', +t.test('ignore-scripts', async t => { + const { npm, joinedOutput, prefix } = await loadMockNpm(t, { + config: { + ...auth, + 'ignore-scripts': true, + }, + prefixDir: { + 'package.json': JSON.stringify({ + ...pkgJson, scripts: { - prepublishOnly: 'echo test prepublishOnly', - prepublish: 'echo test prepublish', // should NOT run this one - publish: 'echo test publish', - postpublish: 'echo test postpublish', + prepublishOnly: 'touch scripts-prepublishonly', + prepublish: 'touch scripts-prepublish', // should NOT run this one + publish: 'touch scripts-publish', + postpublish: 'touch scripts-postpublish', }, - }, - null, - 2 - ), - }) - - const scripts = [] - const Publish = t.mock('../../../lib/commands/publish.js', { - '@npmcli/run-script': args => { - scripts.push(args) - }, - '../../../lib/utils/tar.js': { - getContents: () => ({ - id: 'someid', - }), - logTar: () => { - t.pass('logTar is called') - }, - }, - libnpmpublish: { - publish: () => { - t.pass('publish called') - }, + }, null, 2), }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - const npm = mockNpm({ - config: { loglevel: 'info' }, - output: () => { - t.pass('output is called') - }, - }, t) - npm.config.getCredentialsByURI = uri => { - t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - await publish.exec([testDir]) - t.same( - scripts.map(s => s.event), - ['prepublishOnly', 'publish', 'postpublish'], - 'runs only expected scripts, in order' + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + registry.nock.put(`/${pkg}`).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'new package version') + t.resolveMatch( + fs.exists(path.join(prefix, 'scripts-prepublishonly')), + false, + 'did not run prepublishOnly' + ) + t.resolveMatch( + fs.exists(path.join(prefix, 'scripts-prepublish')), + false, + 'did not run prepublish' + ) + t.resolveMatch( + fs.exists(path.join(prefix, 'scripts-publish')), + false, + 'did not run publish' + ) + t.resolveMatch( + fs.exists(path.join(prefix, 'scripts-postpublish')), + false, + 'did not run postpublish' ) -}) - -t.test('does not run scripts on --ignore-scripts', async t => { - t.plan(4) - - const testDir = t.testdir({ - 'package.json': JSON.stringify( - { - name: 'my-cool-pkg', - version: '1.0.0', - }, - null, - 2 - ), - }) - - const Publish = t.mock('../../../lib/commands/publish.js', { - '@npmcli/run-script': () => { - t.fail('should not call run-script') - }, - '../../../lib/utils/tar.js': { - getContents: () => ({ - id: 'someid', - }), - logTar: () => { - t.pass('logTar is called') - }, - }, - libnpmpublish: { - publish: () => { - t.pass('publish called') - }, - }, - }) - const npm = mockNpm({ - config: { 'ignore-scripts': true, loglevel: 'info' }, - output: () => { - t.pass('output is called') - }, - }, t) - npm.config.getCredentialsByURI = uri => { - t.same(uri, npm.config.get('registry'), 'gets credentials for expected registry') - return { token: 'some.registry.token' } - } - const publish = new Publish(npm) - await publish.exec([testDir]) }) From 21375c6c356e9beddbc96720b1d03ea2db05be0e Mon Sep 17 00:00:00 2001 From: Gar Date: Sun, 17 Apr 2022 09:36:31 -0700 Subject: [PATCH 070/406] chore: add fallback audit to tests --- .../test/lib/commands/audit.js.test.cjs | 27 ++++-- test/lib/commands/audit.js | 90 ++++++++++++++++--- 2 files changed, 97 insertions(+), 20 deletions(-) diff --git a/tap-snapshots/test/lib/commands/audit.js.test.cjs b/tap-snapshots/test/lib/commands/audit.js.test.cjs index d98c16f7905a5..c3680933e6a79 100644 --- a/tap-snapshots/test/lib/commands/audit.js.test.cjs +++ b/tap-snapshots/test/lib/commands/audit.js.test.cjs @@ -5,7 +5,7 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/commands/audit.js TAP audit fix > lockfile has test-dep-a@1.0.1 1`] = ` +exports[`test/lib/commands/audit.js TAP audit fix - bulk endpoint > lockfile has test-dep-a@1.0.1 1`] = ` { "name": "test-dep", "version": "1.0.0", @@ -34,13 +34,28 @@ exports[`test/lib/commands/audit.js TAP audit fix > lockfile has test-dep-a@1.0. ` -exports[`test/lib/commands/audit.js TAP audit fix > must match snapshot 1`] = ` +exports[`test/lib/commands/audit.js TAP audit fix - bulk endpoint > must match snapshot 1`] = ` added 1 package, and audited 2 packages in xxx found 0 vulnerabilities ` +exports[`test/lib/commands/audit.js TAP fallback audit > must match snapshot 1`] = ` +# npm audit report + +test-dep-a 1.0.0 +Severity: high +Test advisory 100 - https://github.com/advisories/GHSA-100 +fix available via \`npm audit fix\` +node_modules/test-dep-a + +1 high severity vulnerability + +To address all issues, run: + npm audit fix +` + exports[`test/lib/commands/audit.js TAP json audit > must match snapshot 1`] = ` { "auditReportVersion": 2, @@ -98,14 +113,14 @@ exports[`test/lib/commands/audit.js TAP json audit > must match snapshot 1`] = ` exports[`test/lib/commands/audit.js TAP normal audit > must match snapshot 1`] = ` # npm audit report -test-dep-a * +test-dep-a 1.0.0 Severity: high Test advisory 100 - https://github.com/advisories/GHSA-100 -No fix available +fix available via \`npm audit fix\` node_modules/test-dep-a 1 high severity vulnerability -Some issues need review, and may require choosing -a different dependency. +To address all issues, run: + npm audit fix ` diff --git a/test/lib/commands/audit.js b/test/lib/commands/audit.js index 1afb8d333b7ce..da6de4774e6b8 100644 --- a/test/lib/commands/audit.js +++ b/test/lib/commands/audit.js @@ -2,9 +2,9 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm') const MockRegistry = require('../../fixtures/mock-registry.js') -const util = require('util') const zlib = require('zlib') -const gzip = util.promisify(zlib.gzip) +const gzip = zlib.gzipSync +const gunzip = zlib.gunzipSync const path = require('path') const fs = require('fs') @@ -43,7 +43,14 @@ const tree = { }, }, }), - 'test-dep-a': { + 'test-dep-a-vuln': { + 'package.json': JSON.stringify({ + name: 'test-dep-a', + version: '1.0.0', + }), + 'vulnerable.txt': 'vulnerable test-dep-a', + }, + 'test-dep-a-fixed': { 'package.json': JSON.stringify({ name: 'test-dep-a', version: '1.0.1', @@ -66,8 +73,11 @@ t.test('normal audit', async t => { packuments: [{ version: '1.0.0' }, { version: '1.0.1' }], }) await registry.package({ manifest }) - const advisory = registry.advisory({ id: 100 }) - const bulkBody = await gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] })) + const advisory = registry.advisory({ + id: 100, + vulnerable_versions: '<1.0.1', + }) + const bulkBody = gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] })) registry.nock.post('/-/npm/v1/security/advisories/bulk', bulkBody) .reply(200, { 'test-dep-a': [advisory], @@ -79,6 +89,55 @@ t.test('normal audit', async t => { t.matchSnapshot(joinedOutput()) }) +t.test('fallback audit ', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: tree, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: 'test-dep-a', + packuments: [{ version: '1.0.0' }, { version: '1.0.1' }], + }) + await registry.package({ manifest }) + const advisory = registry.advisory({ + id: 100, + module_name: 'test-dep-a', + vulnerable_versions: '<1.0.1', + findings: [{ version: '1.0.0', paths: ['test-dep-a'] }], + }) + registry.nock + .post('/-/npm/v1/security/advisories/bulk').reply(404) + .post('/-/npm/v1/security/audits/quick', body => { + const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex'))) + return t.match(unzipped, { + name: 'test-dep', + version: '1.0.0', + requires: { 'test-dep-a': '*' }, + dependencies: { 'test-dep-a': { version: '1.0.0' } }, + }) + }).reply(200, { + actions: [], + muted: [], + advisories: { + 100: advisory, + }, + metadata: { + vulnerabilities: { info: 0, low: 0, moderate: 0, high: 1, critical: 0 }, + dependencies: 1, + devDependencies: 0, + optionalDependencies: 0, + totalDependencies: 1, + }, + }) + await npm.exec('audit', []) + t.ok(process.exitCode, 'would have exited uncleanly') + process.exitCode = 0 + t.matchSnapshot(joinedOutput()) +}) + t.test('json audit', async t => { const { npm, joinedOutput } = await loadMockNpm(t, { prefixDir: tree, @@ -97,7 +156,7 @@ t.test('json audit', async t => { }) await registry.package({ manifest }) const advisory = registry.advisory({ id: 100 }) - const bulkBody = await gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] })) + const bulkBody = gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] })) registry.nock.post('/-/npm/v1/security/advisories/bulk', bulkBody) .reply(200, { 'test-dep-a': [advisory], @@ -109,7 +168,7 @@ t.test('json audit', async t => { t.matchSnapshot(joinedOutput()) }) -t.test('audit fix', async t => { +t.test('audit fix - bulk endpoint', async t => { const { npm, joinedOutput } = await loadMockNpm(t, { prefixDir: tree, }) @@ -124,20 +183,23 @@ t.test('audit fix', async t => { await registry.package({ manifest, tarballs: { - '1.0.1': path.join(npm.prefix, 'test-dep-a'), + '1.0.1': path.join(npm.prefix, 'test-dep-a-fixed'), }, }) const advisory = registry.advisory({ id: 100, vulnerable_versions: '1.0.0' }) - // Can't validate this request body because it changes with each node - // version/npm version and nock's body validation is not async, while - // zlib.gunzip is - registry.nock.post('/-/npm/v1/security/advisories/bulk') + registry.nock.post('/-/npm/v1/security/advisories/bulk', body => { + const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex'))) + return t.same(unzipped, { 'test-dep-a': ['1.0.0'] }) + }) .reply(200, { // first audit 'test-dep-a': [advisory], }) - .post('/-/npm/v1/security/advisories/bulk') + .post('/-/npm/v1/security/advisories/bulk', body => { + const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex'))) + return t.same(unzipped, { 'test-dep-a': ['1.0.1'] }) + }) .reply(200, { // after fix - 'test-dep-a': [advisory], + 'test-dep-a': [], }) await npm.exec('audit', ['fix']) t.matchSnapshot(joinedOutput()) From 8cf4fc41fe3624746f2c8858c47ab0802903ee07 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Thu, 14 Apr 2022 15:38:46 -0700 Subject: [PATCH 071/406] chore(changelog): dont show commit body by default & add extra pr check We don't usually include the commit body in the release notes, so this removes it from the output by default. It's now behind the `--format=long` flag, and the command can be rerun with that in case we need the full commit body sometimes. Also do an extra check for PR references in titles, since squashed PRs don't always include the `associatedPullRequests`. --- scripts/changelog.js | 50 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/scripts/changelog.js b/scripts/changelog.js index f91e28d5a6e6f..1d8db9272fefe 100644 --- a/scripts/changelog.js +++ b/scripts/changelog.js @@ -97,7 +97,7 @@ const assertArgs = (args) => { return process.exit(0) } - if (args.unsafe) { + if (args.force) { // just to make manual testing easier return args } @@ -109,7 +109,7 @@ const assertArgs = (args) => { const current = exec(`git rev-parse --abbrev-ref HEAD`) if (current !== args.branch) { - throw new Error(`Must be on branch "${args.branch}"`) + throw new Error(`Must be on branch "${args.branch}", rerun with --force to override`) } const localLog = exec(`git log ${remoteBranch}..HEAD`).length > 0 @@ -130,10 +130,11 @@ const parseArgs = (argv) => { branch: 'latest', remote: 'origin', type: 'md', // or 'gh' + format: 'short', // or 'long' write: false, read: false, help: false, - unsafe: false, + force: false, } for (const arg of argv) { @@ -270,6 +271,29 @@ const generateRelease = async (args) => { let [title, ...body] = message.split('\n') const prs = commit.associatedPullRequests.nodes.filter((pull) => pull.merged) + + // external squashed PRs dont get the associated pr node set + // so we try to grab it from the end of the commit title + // since thats where it goes by default + const [, titleNumber] = title.match(/\s+\(#(\d+)\)$/) || [] + console.log(prs, titleNumber) + if (titleNumber && !prs.find((pr) => pr.number === +titleNumber)) { + console.log('no title') + try { + // it could also reference an issue so we do one extra check + // to make sure it is really a pr that has been merged + const realPr = JSON.parse(exec(`gh pr view ${titleNumber} --json url,number,state`, { + stdio: 'pipe', + })) + if (realPr.state === 'MERGED') { + prs.push(realPr) + } + } catch { + // maybe an issue or something else went wrong + // not super important so keep going + } + } + for (const pr of prs) { title = title.replace(new RegExp(`\\s*\\(#${pr.number}\\)`, 'g'), '') } @@ -343,7 +367,8 @@ const generateRelease = async (args) => { } output.group(groupCommit) - if (commit.body && commit.body.length) { + // only optionally add full commit bodies to changelog + if (commit.body && commit.body.length && args.format === 'long') { output.log(commit.body) } output.groupEnd() @@ -378,13 +403,18 @@ const main = async (argv) => { // otherwise fetch the requested release from github const { release, version, date } = await generateRelease(args) - try { - exec(`node scripts/release-manager.js --update --version=${version.slice(1)} --date=${date}`) - } catch { - // optionally update release manager issue - } - if (args.write) { + // only try and run release manager issue update on write since that signals + // the first time we know the version of the release + try { + exec( + `node scripts/release-manager.js --update --version=${version.slice(1)} --date=${date}`, { + stdio: 'pipe', + }) + } catch (e) { + console.error(`Updating release manager issue failed: ${e.stderr}`) + } + const { release: existing, changelog } = findRelease(args, version) fs.writeFileSync( args.file, From f3d7fff82dfb742704abfeb58b178a35702c0a8f Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Thu, 14 Apr 2022 15:03:12 -0700 Subject: [PATCH 072/406] chore: fix nodejs pr action --- .github/workflows/create-cli-deps-pr.yml | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/create-cli-deps-pr.yml b/.github/workflows/create-cli-deps-pr.yml index c78703ac0b3e4..1a1415a7bcb63 100644 --- a/.github/workflows/create-cli-deps-pr.yml +++ b/.github/workflows/create-cli-deps-pr.yml @@ -8,9 +8,8 @@ on: required: true default: 'latest' dryRun: - description: "Do a dry run" - required: true - default: false + description: "Do a dry run?" + default: '' jobs: create-pull-request: @@ -28,7 +27,7 @@ jobs: git config --global user.email "npm team" git config --global user.name "ops+robot@npmjs.com" - name: Sync upstream changes - uses: aormsby/Fork-Sync-With-Upstream-action@v3 + uses: aormsby/Fork-Sync-With-Upstream-action@v3.2 with: target_sync_branch: master target_repo_token: ${{ secrets.NPM_ROBOT_USER_PAT }} @@ -39,6 +38,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.NPM_ROBOT_USER_PAT }} run: | + base_dir="$( pwd )"/ dry_run="${{ github.event.inputs.dryRun }}" npm_version="${{ github.event.inputs.npmVersion }}" npm_tag="" @@ -68,8 +68,7 @@ jobs: make release echo "Removing old npm" - base_dir="$( pwd )"/ - deps_dir="$base_dir"deps/ + deps_dir="$base_dir"deps/ cd "$deps_dir" rm -rf npm/ @@ -83,18 +82,16 @@ jobs: git add -A deps/npm git commit -m "$message" git rebase --whitespace=fix master - git push origin "$npm_branch" - - gh_release=`gh release view "$npm_vtag" -R npm/cli --json body -q ".body"` if [[ "$dry_run" == "true" ]]; then - echo $gh_release + git status + git show --summary echo $message echo $npm_branch echo $base_branch echo $npm_vtag else - gh pr create -R nodejs/node -B "$base_branch" -H "npm:$npm_branch" -t "$message" -b "$gh_release" + git push origin "$npm_branch" + gh release view "$npm_vtag" -R npm/cli --json body -q ".body" | \ + gh pr create -R nodejs/node -B "$base_branch" -H "npm:$npm_branch" -t "$message" -F - fi - - \ No newline at end of file From b06e89f434fe8f104e71d4d8b5c98f1e866efdfa Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Mon, 4 Apr 2022 18:39:30 -0400 Subject: [PATCH 073/406] fix(install): do not install invalid package name Throws an usage error if finding an invalid argument in global install. Fixes: https://github.com/npm/cli/issues/3029 --- lib/commands/install.js | 6 ++++++ test/lib/commands/install.js | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/commands/install.js b/lib/commands/install.js index 0a5c827bcc97b..d1f6d1481dddc 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -139,6 +139,12 @@ class Install extends ArboristWorkspaceCmd { args = ['.'] } + // throw usage error if trying to install empty package + // name to global space, e.g: `npm i -g ""` + if (where === globalTop && !args.every(Boolean)) { + throw this.usageError() + } + const opts = { ...this.npm.flatOptions, auditLevel: null, diff --git a/test/lib/commands/install.js b/test/lib/commands/install.js index afb6adb4fb0a5..9b2d52f6edd21 100644 --- a/test/lib/commands/install.js +++ b/test/lib/commands/install.js @@ -139,6 +139,23 @@ t.test('should install globally using Arborist', async t => { t.strictSame(SCRIPTS, [], 'no scripts when installing globally') }) +t.test('should not install invalid global package name', async t => { + const { npm } = await loadMockNpm(t, { + '@npmcli/run-script': () => {}, + '../../lib/utils/reify-finish.js': async () => {}, + '@npmcli/arborist': function (args) { + throw new Error('should not reify') + }, + }) + npm.config.set('global', true) + npm.globalPrefix = path.resolve(t.testdir({})) + await t.rejects( + npm.exec('install', ['']), + /Usage:/, + 'should not install invalid package name' + ) +}) + t.test('npm i -g npm engines check success', async t => { const { npm } = await loadMockNpm(t, { '../../lib/utils/reify-finish.js': async () => {}, From 8da28b403f32d2e99c842893bdc40429b8ffa9a7 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 30 Mar 2022 07:09:57 -0700 Subject: [PATCH 074/406] fix: remove lib/utils/read-package-name.js This code wasn't doing anything special, just dereferencing `name` from a packument. There is no need for this to exist. Most of the tests were able to handle having this go away, except for `npm owner` which had to have its tests rewritten to be real, which of course surfaced bugs along the way of behavior that was incorrectly being tested. `npm owner` needs some love to clean up its UX, it throws or returns inconsistently. I did fix it so that if there is no package.json in cwd it errored as expected instead of throwing `ENOENT` which is what it did before. --- lib/commands/diff.js | 11 +- lib/commands/dist-tag.js | 9 +- lib/commands/owner.js | 64 +- .../test/lib/commands/owner.js.test.cjs | 20 - test/fixtures/mock-registry.js | 15 +- test/lib/commands/diff.js | 2 - test/lib/commands/owner.js | 994 +++++++----------- test/lib/utils/read-package-name.js | 33 - 8 files changed, 426 insertions(+), 722 deletions(-) delete mode 100644 tap-snapshots/test/lib/commands/owner.js.test.cjs delete mode 100644 test/lib/utils/read-package-name.js diff --git a/lib/commands/diff.js b/lib/commands/diff.js index ff942cc44e946..11ee78265e62a 100644 --- a/lib/commands/diff.js +++ b/lib/commands/diff.js @@ -6,7 +6,7 @@ const Arborist = require('@npmcli/arborist') const pacote = require('pacote') const pickManifest = require('npm-pick-manifest') const log = require('../utils/log-shim') -const readPackageName = require('../utils/read-package-name.js') +const readPackage = require('read-package-json-fast') const BaseCommand = require('../base-command.js') class Diff extends BaseCommand { @@ -81,7 +81,8 @@ class Diff extends BaseCommand { async packageName (path) { let name try { - name = await readPackageName(this.prefix) + const pkg = await readPackage(resolve(this.prefix, 'package.json')) + name = pkg.name } catch (e) { log.verbose('diff', 'could not read project dir package.json') } @@ -114,7 +115,8 @@ class Diff extends BaseCommand { let noPackageJson let pkgName try { - pkgName = await readPackageName(this.prefix) + const pkg = await readPackage(resolve(this.prefix, 'package.json')) + pkgName = pkg.name } catch (e) { log.verbose('diff', 'could not read project dir package.json') noPackageJson = true @@ -225,7 +227,8 @@ class Diff extends BaseCommand { if (semverA && semverB) { let pkgName try { - pkgName = await readPackageName(this.prefix) + const pkg = await readPackage(resolve(this.prefix, 'package.json')) + pkgName = pkg.name } catch (e) { log.verbose('diff', 'could not read project dir package.json') } diff --git a/lib/commands/dist-tag.js b/lib/commands/dist-tag.js index 3b82c5194cca8..42cad80df0073 100644 --- a/lib/commands/dist-tag.js +++ b/lib/commands/dist-tag.js @@ -1,9 +1,10 @@ const npa = require('npm-package-arg') +const path = require('path') const regFetch = require('npm-registry-fetch') const semver = require('semver') const log = require('../utils/log-shim') const otplease = require('../utils/otplease.js') -const readPackageName = require('../utils/read-package-name.js') +const readPackage = require('read-package-json-fast') const BaseCommand = require('../base-command.js') class DistTag extends BaseCommand { @@ -150,12 +151,12 @@ class DistTag extends BaseCommand { if (this.npm.config.get('global')) { throw this.usageError() } - const pkg = await readPackageName(this.npm.prefix) - if (!pkg) { + const { name } = await readPackage(path.resolve(this.npm.prefix, 'package.json')) + if (!name) { throw this.usageError() } - return this.list(pkg, opts) + return this.list(name, opts) } spec = npa(spec) diff --git a/lib/commands/owner.js b/lib/commands/owner.js index 07f71c5974768..285b06be8e5fe 100644 --- a/lib/commands/owner.js +++ b/lib/commands/owner.js @@ -3,8 +3,18 @@ const npmFetch = require('npm-registry-fetch') const pacote = require('pacote') const log = require('../utils/log-shim') const otplease = require('../utils/otplease.js') -const readLocalPkgName = require('../utils/read-package-name.js') +const readPackageJsonFast = require('read-package-json-fast') const BaseCommand = require('../base-command.js') +const { resolve } = require('path') + +const readJson = async (pkg) => { + try { + const json = await readPackageJsonFast(pkg) + return json + } catch { + return {} + } +} class Owner extends BaseCommand { static description = 'Manage package owners' @@ -41,12 +51,12 @@ class Owner extends BaseCommand { if (this.npm.config.get('global')) { return [] } - const pkgName = await readLocalPkgName(this.npm.prefix) - if (!pkgName) { + const { name } = await readJson(resolve(this.npm.prefix, 'package.json')) + if (!name) { return [] } - const spec = npa(pkgName) + const spec = npa(name) const data = await pacote.packument(spec, { ...this.npm.flatOptions, fullMetadata: true, @@ -96,12 +106,12 @@ class Owner extends BaseCommand { if (this.npm.config.get('global')) { throw this.usageError() } - const pkgName = await readLocalPkgName(this.npm.prefix) - if (!pkgName) { + const { name } = await readJson(resolve(this.npm.prefix, 'package.json')) + if (!name) { throw this.usageError() } - return pkgName + return name } return pkg } @@ -125,15 +135,6 @@ class Owner extends BaseCommand { throw err } - if (!u || !u.name || u.error) { - throw Object.assign( - new Error( - "Couldn't get user data for " + user + ': ' + JSON.stringify(u) - ), - { code: 'EOWNERUSER' } - ) - } - // normalize user data u = { name: u.name, email: u.email } @@ -177,32 +178,31 @@ class Owner extends BaseCommand { } const dataPath = `/${spec.escapedName}/-rev/${encodeURIComponent(data._rev)}` - const res = await otplease(this.npm.flatOptions, opts => { - return npmFetch.json(dataPath, { - ...opts, - method: 'PUT', - body: { - _id: data._id, - _rev: data._rev, - maintainers, - }, - spec, + try { + const res = await otplease(this.npm.flatOptions, opts => { + return npmFetch.json(dataPath, { + ...opts, + method: 'PUT', + body: { + _id: data._id, + _rev: data._rev, + maintainers, + }, + spec, + }) }) - }) - - if (!res.error) { if (addOrRm === 'add') { this.npm.output(`+ ${user} (${spec.name})`) } else { this.npm.output(`- ${user} (${spec.name})`) } - } else { + return res + } catch (err) { throw Object.assign( - new Error('Failed to update package: ' + JSON.stringify(res)), + new Error('Failed to update package: ' + JSON.stringify(err.message)), { code: 'EOWNERMUTATE' } ) } - return res } } diff --git a/tap-snapshots/test/lib/commands/owner.js.test.cjs b/tap-snapshots/test/lib/commands/owner.js.test.cjs deleted file mode 100644 index f3d7335e47307..0000000000000 --- a/tap-snapshots/test/lib/commands/owner.js.test.cjs +++ /dev/null @@ -1,20 +0,0 @@ -/* IMPORTANT - * This snapshot file is auto-generated, but designed for humans. - * It should be checked into source control and tracked carefully. - * Re-generate by setting TAP_SNAPSHOT=1 and running tests. - * Make sure to inspect the output below. Do not ignore changes! - */ -'use strict' -exports[`test/lib/commands/owner.js TAP owner ls > should output owners of 1`] = ` -nlf -ruyadorno -darcyclarke -isaacs -` - -exports[`test/lib/commands/owner.js TAP owner ls no args > should output owners of cwd package 1`] = ` -nlf -ruyadorno -darcyclarke -isaacs -` diff --git a/test/fixtures/mock-registry.js b/test/fixtures/mock-registry.js index 8b847213f33a7..5e39dcf48315a 100644 --- a/test/fixtures/mock-registry.js +++ b/test/fixtures/mock-registry.js @@ -5,6 +5,7 @@ * for tests against any registry data. */ const pacote = require('pacote') +const npa = require('npm-package-arg') class MockRegistry { #tap #nock @@ -84,6 +85,16 @@ class MockRegistry { ).reply(200) } + couchuser ({ username, body, responseCode = 200 }) { + if (body) { + this.nock = this.nock.get(`/-/user/org.couchdb.user:${encodeURIComponent(username)}`) + .reply(responseCode, body) + } else { + this.nock = this.nock.get(`/-/user/org.couchdb.user:${encodeURIComponent(username)}`) + .reply(responseCode, { _id: `org.couchdb.user:${username}`, email: '', name: username }) + } + } + couchlogin ({ username, password, email, otp, token = 'npm_default-test-token' }) { this.nock = this.nock .post('/-/v1/login').reply(401, { error: 'You must be logged in to publish packages.' }) @@ -156,7 +167,8 @@ class MockRegistry { async package ({ manifest, times = 1, query, tarballs }) { let nock = this.nock - nock = nock.get(`/${manifest.name}`).times(times) + const spec = npa(manifest.name) + nock = nock.get(`/${spec.escapedName}`).times(times) if (query) { nock = nock.query(query) } @@ -203,6 +215,7 @@ class MockRegistry { dist: { tarball: `${this.#registry}/${name}/-/${name}-${packument.version}.tgz`, }, + maintainers: [], ...packument, } manifest.time[packument.version] = new Date() diff --git a/test/lib/commands/diff.js b/test/lib/commands/diff.js index c2b1a935da874..0adaa6568d8f7 100644 --- a/test/lib/commands/diff.js +++ b/test/lib/commands/diff.js @@ -417,7 +417,6 @@ t.test('single arg', t => { const Diff = t.mock('../../../lib/commands/diff.js', { ...mocks, - '../../../lib/utils/read-package-name.js': async () => 'my-project', pacote: { packument: spec => { t.equal(spec.name, 'lorem', 'should have expected spec name') @@ -455,7 +454,6 @@ t.test('single arg', t => { const Diff = t.mock('../../../lib/commands/diff.js', { ...mocks, - '../../../lib/utils/read-package-name.js': async () => 'my-project', '@npmcli/arborist': class { constructor () { throw new Error('ERR') diff --git a/test/lib/commands/owner.js b/test/lib/commands/owner.js index eadfa2bf08b56..d80ce36fece98 100644 --- a/test/lib/commands/owner.js +++ b/test/lib/commands/owner.js @@ -1,760 +1,502 @@ const t = require('tap') -const { fake: mockNpm } = require('../../fixtures/mock-npm.js') +const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') +const MockRegistry = require('../../fixtures/mock-registry.js') -let result = '' -let readPackageNamePrefix = null -let readPackageNameResponse = null +const npa = require('npm-package-arg') +const packageName = '@npmcli/test-package' +const spec = npa(packageName) +const auth = { '//registry.npmjs.org/:_authToken': 'test-auth-token' } -const noop = () => null +const maintainers = [ + { email: 'test-user-a@npmjs.org', name: 'test-user-a' }, + { email: 'test-user-b@npmjs.org', name: 'test-user-b' }, +] -const npm = mockNpm({ - output: (msg) => { - result = result ? `${result}\n${msg}` : msg - }, +t.test('owner no args', async t => { + const { npm } = await loadMockNpm(t) + await t.rejects( + npm.exec('owner', []), + { code: 'EUSAGE' }, + 'rejects with usage' + ) }) -const npmFetch = { json: noop } -const log = { error: noop, info: noop, verbose: noop } -const pacote = { packument: noop } - -const mocks = { - 'proc-log': log, - 'npm-registry-fetch': npmFetch, - pacote, - '../../../lib/utils/read-package-name.js': async (prefix) => { - readPackageNamePrefix = prefix - return readPackageNameResponse - }, -} - -const npmcliMaintainers = [ - { email: 'quitlahok@gmail.com', name: 'nlf' }, - { email: 'ruyadorno@hotmail.com', name: 'ruyadorno' }, - { email: 'darcy@darcyclarke.me', name: 'darcyclarke' }, - { email: 'i@izs.me', name: 'isaacs' }, -] - -const Owner = t.mock('../../../lib/commands/owner.js', mocks) -const owner = new Owner(npm) +t.test('owner ls no args', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: packageName }), + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -t.test('owner no args', async t => { - result = '' - t.teardown(() => { - result = '' + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], }) + registry.package({ manifest }) - await t.rejects( - owner.exec([]), - owner.usage) + await npm.exec('owner', ['ls']) + t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) }) -t.test('owner ls no args', async t => { - t.plan(4) - - result = '' - - readPackageNameResponse = '@npmcli/map-workspaces' - pacote.packument = async (spec, opts) => { - t.equal(spec.name, '@npmcli/map-workspaces', 'should use expect pkg name') - t.match( - opts, - { - ...npm.flatOptions, - fullMetadata: true, - }, - 'should forward expected options to pacote.packument' - ) - return { maintainers: npmcliMaintainers } - } - t.teardown(() => { - npm.prefix = null - result = '' - pacote.packument = noop - readPackageNameResponse = null - }) - npm.prefix = 'test-npm-prefix' - - await owner.exec(['ls']) - t.matchSnapshot(result, 'should output owners of cwd package') - t.equal(readPackageNamePrefix, 'test-npm-prefix', 'read-package-name gets npm.prefix') +t.test('local package.json has no name', async t => { + const { npm } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ hello: 'world' }), + }, + }) + await t.rejects( + npm.exec('owner', ['ls']), + { code: 'EUSAGE' } + ) }) t.test('owner ls global', async t => { - t.teardown(() => { - npm.config.set('global', false) + const { npm } = await loadMockNpm(t, { + config: { global: true }, }) - npm.config.set('global', true) await t.rejects( - owner.exec(['ls']), - owner.usage + npm.exec('owner', ['ls']), + { code: 'EUSAGE' }, + 'rejects with usage' ) }) t.test('owner ls no args no cwd package', async t => { - result = '' - t.teardown(() => { - result = '' - log.error = noop - }) + const { npm } = await loadMockNpm(t) await t.rejects( - owner.exec(['ls']), - owner.usage + npm.exec('owner', ['ls']) ) }) t.test('owner ls fails to retrieve packument', async t => { - t.plan(4) - - result = '' - readPackageNameResponse = '@npmcli/map-workspaces' - pacote.packument = () => { - throw new Error('ERR') - } - log.error = (title, msg, pkgName) => { - t.equal(title, 'owner ls', 'should list npm owner ls title') - t.equal(msg, "Couldn't get owner data", 'should use expected msg') - t.equal(pkgName, '@npmcli/map-workspaces', 'should use pkg name') - } - t.teardown(() => { - result = '' - log.error = noop - pacote.packument = noop - }) - - await t.rejects( - owner.exec(['ls']), - /ERR/, - 'should throw unknown error' - ) + const { npm, logs } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: packageName }), + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + registry.nock.get(`/${spec.escapedName}`).reply(404) + await t.rejects(npm.exec('owner', ['ls'])) + t.match(logs.error, [['owner ls', "Couldn't get owner data", '@npmcli/test-package']]) }) t.test('owner ls ', async t => { - t.plan(3) - - result = '' - pacote.packument = async (spec, opts) => { - t.equal(spec.name, '@npmcli/map-workspaces', 'should use expect pkg name') - t.match( - opts, - { - ...npm.flatOptions, - fullMetadata: true, - }, - 'should forward expected options to pacote.packument' - ) - return { maintainers: npmcliMaintainers } - } - t.teardown(() => { - result = '' - pacote.packument = noop - }) - - await owner.exec(['ls', '@npmcli/map-workspaces']) - t.matchSnapshot(result, 'should output owners of ') + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.package({ manifest }) + + await npm.exec('owner', ['ls', packageName]) + t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) }) t.test('owner ls no maintainers', async t => { - result = '' - pacote.packument = async (spec, opts) => { - return { maintainers: [] } - } - t.teardown(() => { - result = '' - pacote.packument = noop + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) + const manifest = registry.manifest({ + name: packageName, + versions: ['1.0.0'], + }) + registry.package({ manifest }) - await owner.exec(['ls', '@npmcli/map-workspaces']) - t.equal(result, 'no admin found', 'should output no admint found msg') + await npm.exec('owner', ['ls', packageName]) + t.equal(joinedOutput(), 'no admin found') }) t.test('owner add ', async t => { - t.plan(8) - - result = '' - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:foo') { - t.ok('should request user info') - t.match(opts, { ...npm.flatOptions }, 'should use expected opts') - return { - _id: 'org.couchdb.user:foo', - email: 'foo@github.com', - name: 'foo', - } - } else if (uri === '/@npmcli%2fmap-workspaces/-rev/1-foobaaa1') { - t.ok('should put changed owner') - t.match(opts, { - ...npm.flatOptions, - method: 'PUT', - body: { - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, - }, - spec: { - name: '@npmcli/map-workspaces', - }, - }, 'should use expected opts') - t.same( - opts.body.maintainers, - [ - ...npmcliMaintainers, - { - name: 'foo', - email: 'foo@github.com', - }, - ], - 'should contain expected new owners, adding requested user' - ) - return {} - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => { - t.equal(spec.name, '@npmcli/map-workspaces', 'should use expect pkg name') - t.match( - opts, - { - ...npm.flatOptions, - fullMetadata: true, - }, - 'should forward expected options to pacote.packument' - ) - return { - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, - } - } - t.teardown(() => { - result = '' - npmFetch.json = noop - pacote.packument = noop - }) - - await owner.exec(['add', 'foo', '@npmcli/map-workspaces']) - t.equal(result, '+ foo (@npmcli/map-workspaces)', 'should output add result') + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { ...auth }, + }) + const username = 'foo' + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) + registry.nock.put(`/${spec.escapedName}/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: [ + ...manifest.maintainers, + { name: username, email: '' }, + ], + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['add', username, packageName]) + t.equal(joinedOutput(), `+ ${username} (${packageName})`) }) t.test('owner add cwd package', async t => { - result = '' - readPackageNameResponse = '@npmcli/map-workspaces' - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:foo') { - return { - _id: 'org.couchdb.user:foo', - email: 'foo@github.com', - name: 'foo', - } - } else if (uri === '/@npmcli%2fmap-workspaces/-rev/1-foobaaa1') { - return {} - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => ({ - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, - }) - t.teardown(() => { - result = '' - readPackageNameResponse = null - npmFetch.json = noop - pacote.packument = noop - }) - - await owner.exec(['add', 'foo']) - t.equal(result, '+ foo (@npmcli/map-workspaces)', 'should output add result') + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: packageName }), + }, + config: { ...auth }, + }) + const username = 'foo' + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) + registry.nock.put(`/${spec.escapedName}/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: [ + ...manifest.maintainers, + { name: username, email: '' }, + ], + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['add', username]) + t.equal(joinedOutput(), `+ ${username} (${packageName})`) }) t.test('owner add already an owner', async t => { - t.plan(2) - - result = '' - log.info = (title, msg) => { - t.equal(title, 'owner add', 'should use expected title') - t.equal( - msg, - 'Already a package owner: ruyadorno ', - 'should log already package owner info message' - ) - } - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:ruyadorno') { - return { - _id: 'org.couchdb.user:ruyadorno', - email: 'ruyadorno@hotmail.com', - name: 'ruyadorno', - } - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => { - return { - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, - } - } - t.teardown(() => { - result = '' - log.info = noop - npmFetch.json = noop - pacote.packument = noop - }) - - await owner.exec(['add', 'ruyadorno', '@npmcli/map-workspaces']) + const { npm, joinedOutput, logs } = await loadMockNpm(t, { + config: { ...auth }, + }) + const username = maintainers[0].name + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) + await npm.exec('owner', ['add', username, packageName]) + t.equal(joinedOutput(), '') + t.match( + logs.info, + [['owner add', 'Already a package owner: test-user-a ']] + ) }) t.test('owner add fails to retrieve user', async t => { - result = '' - readPackageNameResponse = - npmFetch.json = async (uri, opts) => { - // retrieve borked user info from couchdb request - if (uri === '/-/user/org.couchdb.user:foo') { - return { ok: false } - } else if (uri === '/@npmcli%2fmap-workspaces/-rev/1-foobaaa1') { - return {} - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => ({ - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, + const { npm, logs } = await loadMockNpm(t, { + config: { ...auth }, }) - t.teardown(() => { - result = '' - readPackageNameResponse = null - npmFetch.json = noop - pacote.packument = noop + const username = 'foo' + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - - await t.rejects( - owner.exec(['add', 'foo', '@npmcli/map-workspaces']), - { code: 'EOWNERUSER', message: /Couldn't get user data for foo: {"ok":false}/ }, - 'should throw user data error' - ) + registry.couchuser({ username, responseCode: 404, body: {} }) + await t.rejects(npm.exec('owner', ['add', username, packageName])) + t.match(logs.error, [['owner mutate', `Error getting user data for ${username}`]]) }) t.test('owner add fails to PUT updates', async t => { - result = '' - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:foo') { - return { - _id: 'org.couchdb.user:foo', - email: 'foo@github.com', - name: 'foo', - } - } else if (uri === '/@npmcli%2fmap-workspaces/-rev/1-foobaaa1') { - return { - error: { - status: '418', - message: "I'm a teapot", - }, - } - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => ({ - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, + const { npm } = await loadMockNpm(t, { + config: { ...auth }, }) - t.teardown(() => { - result = '' - npmFetch.json = noop - pacote.packument = noop - }) - - await t.rejects( - owner.exec(['add', 'foo', '@npmcli/map-workspaces']), - { code: 'EOWNERMUTATE', message: /Failed to update package/ }, - 'should throw failed to update package error' - ) -}) - -t.test('owner add fails to retrieve user info', async t => { - t.plan(3) - - result = '' - log.error = (title, msg) => { - t.equal(title, 'owner mutate', 'should use expected title') - t.equal(msg, 'Error getting user data for foo') - } - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:foo') { - throw Object.assign( - new Error("I'm a teapot"), - { status: 418 } - ) - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => ({ - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, + const username = 'foo' + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - t.teardown(() => { - result = '' - log.error = noop - npmFetch.json = noop - pacote.packument = noop + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], }) - + registry.couchuser({ username }) + registry.package({ manifest }) + registry.nock.put(`/${spec.escapedName}/-rev/${manifest._rev}`).reply(404, {}) await t.rejects( - owner.exec(['add', 'foo', '@npmcli/map-workspaces']), - "I'm a teapot", - 'should throw server error response' + npm.exec('owner', ['add', username, packageName]), + { code: 'EOWNERMUTATE' } ) }) t.test('owner add no previous maintainers property from server', async t => { - result = '' - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:foo') { - return { - _id: 'org.couchdb.user:foo', - email: 'foo@github.com', - name: 'foo', - } - } else if (uri === '/@npmcli%2fno-owners-pkg/-rev/1-foobaaa1') { - return {} - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => { - return { - _rev: '1-foobaaa1', - maintainers: null, - } - } - t.teardown(() => { - result = '' - npmFetch.json = noop - pacote.packument = noop - }) - - await owner.exec(['add', 'foo', '@npmcli/no-owners-pkg']) - t.equal(result, '+ foo (@npmcli/no-owners-pkg)', 'should output add result') + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { ...auth }, + }) + const username = 'foo' + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers: undefined, version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) + registry.nock.put(`/${spec.escapedName}/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: [{ name: username, email: '' }], + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['add', username, packageName]) + t.equal(joinedOutput(), `+ ${username} (${packageName})`) }) t.test('owner add no user', async t => { - result = '' - t.teardown(() => { - result = '' - }) + const { npm } = await loadMockNpm(t) await t.rejects( - owner.exec(['add']), - owner.usage + npm.exec('owner', ['add']), + { code: 'EUSAGE' } ) }) -t.test('owner add no pkg global', async t => { - t.teardown(() => { - npm.config.set('global', false) +t.test('owner add no pkg global', async t => { + const { npm } = await loadMockNpm(t, { + config: { global: true }, }) - npm.config.set('global', true) await t.rejects( - owner.exec(['add', 'gar']), - owner.usage + npm.exec('owner', ['add', 'foo']), + { code: 'EUSAGE' } ) }) t.test('owner add no cwd package', async t => { - result = '' - t.teardown(() => { - result = '' - }) + const { npm } = await loadMockNpm(t) await t.rejects( - owner.exec(['add', 'foo']), - owner.usage + npm.exec('owner', ['add', 'foo']), + { code: 'EUSAGE' } ) }) t.test('owner rm ', async t => { - t.plan(8) - - result = '' - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:ruyadorno') { - t.ok('should request user info') - t.match(opts, { ...npm.flatOptions }, 'should use expected opts') - return { - _id: 'org.couchdb.user:ruyadorno', - email: 'ruyadorno@hotmail.com', - name: 'ruyadorno', - } - } else if (uri === '/@npmcli%2fmap-workspaces/-rev/1-foobaaa1') { - t.ok('should put changed owner') - t.match(opts, { - ...npm.flatOptions, - method: 'PUT', - body: { - _rev: '1-foobaaa1', - }, - spec: { - name: '@npmcli/map-workspaces', - }, - }, 'should use expected opts') - t.same( - opts.body.maintainers, - npmcliMaintainers.filter(m => m.name !== 'ruyadorno'), - 'should contain expected new owners, removing requested user' - ) - return {} - } else { - t.fail(`unexpected fetch json call to: ${uri}`) - } - } - pacote.packument = async (spec, opts) => { - t.equal(spec.name, '@npmcli/map-workspaces', 'should use expect pkg name') - t.match( - opts, - { - ...npm.flatOptions, - fullMetadata: true, - }, - 'should forward expected options to pacote.packument' - ) - return { - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, - } - } - t.teardown(() => { - result = '' - npmFetch.json = noop - pacote.packument = noop - }) - - await owner.exec(['rm', 'ruyadorno', '@npmcli/map-workspaces']) - t.equal(result, '- ruyadorno (@npmcli/map-workspaces)', 'should output rm result') + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { ...auth }, + }) + const username = maintainers[0].name + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) + registry.nock.put(`/${spec.escapedName}/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: maintainers.slice(1), + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['rm', username, packageName]) + t.equal(joinedOutput(), `- ${username} (${packageName})`) }) t.test('owner rm not a current owner', async t => { - t.plan(2) - - result = '' - log.info = (title, msg) => { - t.equal(title, 'owner rm', 'should log expected title') - t.equal(msg, 'Not a package owner: foo', 'should log.info not a package owner msg') - } - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:foo') { - return { - _id: 'org.couchdb.user:foo', - email: 'foo@github.com', - name: 'foo', - } - } else if (uri === '/@npmcli%2fmap-workspaces/-rev/1-foobaaa1') { - return {} - } else { - t.fail(`unexpected fetch json call to: ${uri}`) - } - } - pacote.packument = async (spec, opts) => { - return { - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, - } - } - t.teardown(() => { - result = '' - log.info = noop - npmFetch.json = noop - pacote.packument = noop - }) - - await owner.exec(['rm', 'foo', '@npmcli/map-workspaces']) + const { npm, logs } = await loadMockNpm(t, { + config: { ...auth }, + }) + const username = 'foo' + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) + await npm.exec('owner', ['rm', username, packageName]) + t.match(logs.info, [['owner rm', `Not a package owner: ${username}`]]) }) t.test('owner rm cwd package', async t => { - result = '' - readPackageNameResponse = '@npmcli/map-workspaces' - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:ruyadorno') { - return { - _id: 'org.couchdb.user:ruyadorno', - email: 'ruyadorno@hotmail.com', - name: 'ruyadorno', - } - } else if (uri === '/@npmcli%2fmap-workspaces/-rev/1-foobaaa1') { - return {} - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => ({ - _rev: '1-foobaaa1', - maintainers: npmcliMaintainers, - }) - t.teardown(() => { - result = '' - readPackageNameResponse = null - npmFetch.json = noop - pacote.packument = noop - }) - - await owner.exec(['rm', 'ruyadorno']) - t.equal(result, '- ruyadorno (@npmcli/map-workspaces)', 'should output rm result') + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: packageName }), + }, + config: { ...auth }, + }) + const username = maintainers[0].name + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) + registry.nock.put(`/${spec.escapedName}/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: maintainers.slice(1), + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['rm', username]) + t.equal(joinedOutput(), `- ${username} (${packageName})`) }) t.test('owner rm only user', async t => { - result = '' - readPackageNameResponse = 'ipt' - npmFetch.json = async (uri, opts) => { - // retrieve user info from couchdb request - if (uri === '/-/user/org.couchdb.user:ruyadorno') { - return { - _id: 'org.couchdb.user:ruyadorno', - email: 'ruyadorno@hotmail.com', - name: 'ruyadorno', - } - } else { - t.fail(`unexpected fetch json call to uri: ${uri}`) - } - } - pacote.packument = async (spec, opts) => ({ - _rev: '1-foobaaa1', - maintainers: [{ - name: 'ruyadorno', - email: 'ruyadorno@hotmail.com', - }], - }) - t.teardown(() => { - result = '' - readPackageNameResponse = null - npmFetch.json = noop - pacote.packument = noop - }) - + const { npm } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: packageName }), + }, + config: { ...auth }, + }) + const username = maintainers[0].name + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers: maintainers.slice(0, 1), version: '1.0.0' }], + }) + registry.couchuser({ username }) + registry.package({ manifest }) await t.rejects( - owner.exec(['rm', 'ruyadorno']), - { code: 'EOWNERRM', message: 'Cannot remove all owners of a package. Add someone else first.' }, - 'should throw unable to remove unique owner message' + npm.exec('owner', ['rm', username]), + { + code: 'EOWNERRM', + message: 'Cannot remove all owners of a package. Add someone else first.', + } ) }) t.test('owner rm no user', async t => { - result = '' - t.teardown(() => { - result = '' - }) - + const { npm } = await loadMockNpm(t) await t.rejects( - owner.exec(['rm']), - owner.usage + npm.exec('owner', ['rm']), + { code: 'EUSAGE' } ) }) t.test('owner rm no pkg global', async t => { - t.teardown(() => { - npm.config.set('global', false) + const { npm } = await loadMockNpm(t, { + config: { global: true }, }) - npm.config.set('global', true) - await t.rejects( - owner.exec(['rm', 'foo']), - owner.usage + npm.exec('owner', ['rm', 'foo']), + { code: 'EUSAGE' } ) }) t.test('owner rm no cwd package', async t => { - result = '' - t.teardown(() => { - result = '' - }) - + const { npm } = await loadMockNpm(t) await t.rejects( - owner.exec(['rm', 'foo']), - owner.usage + npm.exec('owner', ['rm', 'foo']), + { code: 'EUSAGE' } ) }) t.test('completion', async t => { - const testComp = async (argv, expect) => { - const res = await owner.completion({ conf: { argv: { remain: argv } } }) - t.strictSame(res, expect, argv.join(' ')) - } - - await Promise.all([ - testComp(['npm', 'foo'], []), - testComp(['npm', 'owner'], ['add', 'rm', 'ls']), - testComp(['npm', 'owner', 'add'], []), - testComp(['npm', 'owner', 'ls'], []), - testComp(['npm', 'owner', 'rm', 'foo'], []), - ]) - - // npm owner rm completion is async - t.test('completion npm owner rm', async t => { - t.plan(2) - readPackageNameResponse = '@npmcli/map-workspaces' - pacote.packument = async spec => { - t.equal(spec.name, readPackageNameResponse, 'should use package spec') - return { - maintainers: npmcliMaintainers, - } + t.test('basic commands', async t => { + const { npm } = await loadMockNpm(t) + const owner = await npm.cmd('owner') + const testComp = async (argv, expect) => { + const res = await owner.completion({ conf: { argv: { remain: argv } } }) + t.strictSame(res, expect, argv.join(' ')) } - t.teardown(() => { - readPackageNameResponse = null - pacote.packument = noop - }) + await Promise.all([ + testComp(['npm', 'foo'], []), + testComp(['npm', 'owner'], ['add', 'rm', 'ls']), + testComp(['npm', 'owner', 'add'], []), + testComp(['npm', 'owner', 'ls'], []), + testComp(['npm', 'owner', 'rm', 'foo'], []), + ]) + }) + + t.test('completion npm owner rm', async t => { + const { npm } = await loadMockNpm(t, { + prefixDir: { 'package.json': JSON.stringify({ name: packageName }) }, + }) + const owner = await npm.cmd('owner') + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.package({ manifest }) const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) - t.strictSame(res, - ['nlf', 'ruyadorno', 'darcyclarke', 'isaacs'], - 'should return list of current owners' - ) + t.strictSame(res, maintainers.map(m => m.name), 'should return list of current owners') }) t.test('completion npm owner rm no cwd package', async t => { + const { npm } = await loadMockNpm(t) + const owner = await npm.cmd('owner') const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, [], 'should have no owners to autocomplete if not cwd package') - t.end() }) t.test('completion npm owner rm global', async t => { - t.teardown(() => { - npm.config.set('global', false) + const { npm } = await loadMockNpm(t, { + config: { global: true }, }) - npm.config.set('global', true) + const owner = await npm.cmd('owner') const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, [], 'should have no owners to autocomplete if global') - t.end() }) t.test('completion npm owner rm no owners found', async t => { - t.plan(2) - readPackageNameResponse = '@npmcli/map-workspaces' - pacote.packument = async spec => { - t.equal(spec.name, readPackageNameResponse, 'should use package spec') - return { - maintainers: [], - } - } - t.teardown(() => { - readPackageNameResponse = null - pacote.packument = noop + const { npm } = await loadMockNpm(t, { + prefixDir: { 'package.json': JSON.stringify({ name: packageName }) }, }) + const owner = await npm.cmd('owner') + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: packageName, + packuments: [{ maintainers: [], version: '1.0.0' }], + }) + registry.package({ manifest }) const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, [], 'should return no owners if not found') }) - - t.end() }) diff --git a/test/lib/utils/read-package-name.js b/test/lib/utils/read-package-name.js deleted file mode 100644 index a1a1b4a1504dc..0000000000000 --- a/test/lib/utils/read-package-name.js +++ /dev/null @@ -1,33 +0,0 @@ -const t = require('tap') - -const readPackageName = require('../../../lib/utils/read-package-name.js') - -t.test('read local package.json', async (t) => { - const prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: 'my-local-package', - version: '1.0.0', - }), - }) - const packageName = await readPackageName(prefix) - t.equal( - packageName, - 'my-local-package', - 'should retrieve current package name' - ) -}) - -t.test('read local scoped-package.json', async (t) => { - const prefix = t.testdir({ - 'package.json': JSON.stringify({ - name: '@my-scope/my-local-package', - version: '1.0.0', - }), - }) - const packageName = await readPackageName(prefix) - t.equal( - packageName, - '@my-scope/my-local-package', - 'should retrieve scoped package name' - ) -}) From 6253d1968d8390ea6b16604ff3abb5e6509349c9 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Wed, 30 Mar 2022 16:37:27 -0400 Subject: [PATCH 075/406] fix(exec): workspaces support Fixes the proper path location to use when targetting specific workspaces. Fixes: https://github.com/npm/cli/issues/3520 Relates to: https://github.com/npm/statusboard/issues/403 --- lib/commands/exec.js | 8 +- test/lib/commands/exec.js | 156 ++++++++++++++++++---------- workspaces/libnpmexec/test/index.js | 76 ++++++++++++++ 3 files changed, 183 insertions(+), 57 deletions(-) diff --git a/lib/commands/exec.js b/lib/commands/exec.js index 5e6a94296d287..f764cea528adb 100644 --- a/lib/commands/exec.js +++ b/lib/commands/exec.js @@ -48,10 +48,8 @@ class Exec extends BaseCommand { static ignoreImplicitWorkspace = false static isShellout = true - async exec (_args, { locationMsg, path, runPath } = {}) { - if (!path) { - path = this.npm.localPrefix - } + async exec (_args, { locationMsg, runPath } = {}) { + const path = this.npm.localPrefix if (!runPath) { runPath = process.cwd() @@ -95,7 +93,7 @@ class Exec extends BaseCommand { for (const path of this.workspacePaths) { const locationMsg = await getLocationMsg({ color, path }) - await this.exec(args, { locationMsg, path, runPath: path }) + await this.exec(args, { locationMsg, runPath: path }) } } } diff --git a/test/lib/commands/exec.js b/test/lib/commands/exec.js index 6b57bf6666e1e..05b9b7b0cce84 100644 --- a/test/lib/commands/exec.js +++ b/test/lib/commands/exec.js @@ -1334,10 +1334,11 @@ t.test('forward legacyPeerDeps opt', async t => { ) }) -t.test('workspaces', t => { +t.test('workspaces', async t => { npm.localPrefix = t.testdir({ node_modules: { '.bin': { + a: '', foo: '', }, }, @@ -1365,68 +1366,119 @@ t.test('workspaces', t => { }) PROGRESS_IGNORED = true - npm.localBin = resolve(npm.localPrefix, 'node_modules/.bin') + npm.localBin = resolve(npm.localPrefix, 'node_modules', '.bin') - t.test('with args, run scripts in the context of a workspace', async t => { - await exec.execWorkspaces(['foo', 'one arg', 'two arg'], ['a', 'b']) + // with arg matching existing bin, run scripts in the context of a workspace + await exec.execWorkspaces(['foo', 'one arg', 'two arg'], ['a', 'b']) - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { - PATH: [npm.localBin, process.env.PATH].join(delimiter), - }, - stdio: 'inherit', + t.match(RUN_SCRIPTS, [ + { + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: npm.localPrefix, + stdioString: true, + event: 'npx', + env: { + PATH: [npm.localBin, process.env.PATH].join(delimiter), }, - ]) - }) + stdio: 'inherit', + }, + { + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: npm.localPrefix, + stdioString: true, + event: 'npx', + env: { + PATH: [npm.localBin, process.env.PATH].join(delimiter), + }, + stdio: 'inherit', + }, + ], 'should run with multiple args across multiple workspaces') - t.test('no args, spawn interactive shell', async t => { - CI_NAME = null - process.stdin.isTTY = true + // clean up + RUN_SCRIPTS.length = 0 - await exec.execWorkspaces([], ['a']) + // with packages, run scripts in the context of a workspace + config.package = ['foo'] + config.call = 'foo' + config.yes = false - t.strictSame(LOG_WARN, []) - t.strictSame( - npm._mockOutputs, + ARB_ACTUAL_TREE[npm.localPrefix] = { + children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + } + + await exec.execWorkspaces([], ['a', 'b']) + + // path should point to the workspace folder + t.match(RUN_SCRIPTS, [ + { + pkg: { scripts: { npx: 'foo' } }, + args: [], + banner: false, + path: resolve(npm.localPrefix, 'packages', 'a'), + stdioString: true, + event: 'npx', + stdio: 'inherit', + }, + { + pkg: { scripts: { npx: 'foo' } }, + args: [], + banner: false, + path: resolve(npm.localPrefix, 'packages', 'b'), + stdioString: true, + event: 'npx', + stdio: 'inherit', + }, + ], 'should run without args in multiple workspaces') + + t.match(ARB_CTOR, [ + { path: npm.localPrefix }, + { path: npm.localPrefix }, + ]) + + // no args, spawn interactive shell + CI_NAME = null + config.package = [] + config.call = '' + process.stdin.isTTY = true + + await exec.execWorkspaces([], ['a']) + + t.strictSame(LOG_WARN, []) + t.strictSame( + npm._mockOutputs, + [ [ - [ - `\nEntering npm script environment in workspace a@1.0.0 at location:\n${resolve( - npm.localPrefix, - 'packages/a' - )}\nType 'exit' or ^D when finished\n`, - ], + `\nEntering npm script environment in workspace a@1.0.0 at location:\n${resolve( + npm.localPrefix, + 'packages/a' + )}\nType 'exit' or ^D when finished\n`, ], - 'printed message about interactive shell' - ) + ], + 'printed message about interactive shell' + ) - npm.color = true - flatOptions.color = true - npm._mockOutputs.length = 0 - await exec.execWorkspaces([], ['a']) + npm.color = true + flatOptions.color = true + npm._mockOutputs.length = 0 + await exec.execWorkspaces([], ['a']) - t.strictSame(LOG_WARN, []) - t.strictSame( - npm._mockOutputs, + t.strictSame(LOG_WARN, []) + t.strictSame( + npm._mockOutputs, + [ [ - [ + /* eslint-disable-next-line max-len */ + `\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m in workspace \u001b[32ma@1.0.0\u001b[39m at location:\u001b[0m\n\u001b[0m\u001b[2m${resolve( + npm.localPrefix, + 'packages/a' /* eslint-disable-next-line max-len */ - `\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m in workspace \u001b[32ma@1.0.0\u001b[39m at location:\u001b[0m\n\u001b[0m\u001b[2m${resolve( - npm.localPrefix, - 'packages/a' - /* eslint-disable-next-line max-len */ - )}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`, - ], + )}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`, ], - 'printed message about interactive shell' - ) - }) - - t.end() + ], + 'printed message about interactive shell' + ) }) diff --git a/workspaces/libnpmexec/test/index.js b/workspaces/libnpmexec/test/index.js index bd1b67cec3a5d..834dcff0a1ff6 100644 --- a/workspaces/libnpmexec/test/index.js +++ b/workspaces/libnpmexec/test/index.js @@ -121,6 +121,82 @@ t.test('local pkg, must not fetch manifest for avail pkg', async t => { t.equal(res, 'LOCAL PKG', 'should run local pkg bin script') }) +t.test('multiple local pkgs', async t => { + const foo = { + name: '@ruyadorno/create-foo', + version: '2.0.0', + bin: { + 'create-foo': './index.js', + }, + } + const bar = { + name: '@ruyadorno/create-bar', + version: '2.0.0', + bin: { + 'create-bar': './index.js', + }, + } + const path = t.testdir({ + cache: {}, + npxCache: {}, + node_modules: { + '.bin': {}, + '@ruyadorno': { + 'create-foo': { + 'package.json': JSON.stringify(foo), + 'index.js': `#!/usr/bin/env node + require('fs').writeFileSync(process.argv.slice(2)[0], 'foo')`, + }, + 'create-bar': { + 'package.json': JSON.stringify(bar), + 'index.js': `#!/usr/bin/env node + require('fs').writeFileSync(process.argv.slice(2)[0], 'bar')`, + }, + }, + }, + 'package.json': JSON.stringify({ + name: 'pkg', + dependencies: { + '@ruyadorno/create-foo': '^2.0.0', + '@ruyadorno/create-bar': '^2.0.0', + }, + }), + }) + const runPath = path + const cache = resolve(path, 'cache') + const npxCache = resolve(path, 'npxCache') + + const setupBins = async (pkg) => { + const executable = + resolve(path, `node_modules/${pkg.name}/index.js`) + fs.chmodSync(executable, 0o775) + + await binLinks({ + path: resolve(path, `node_modules/${pkg.name}`), + pkg, + }) + } + + await Promise.all([foo, bar] + .map(setupBins)) + + await libexec({ + ...baseOpts, + localBin: resolve(path, 'node_modules/.bin'), + cache, + npxCache, + packages: ['@ruyadorno/create-foo', '@ruyadorno/create-bar'], + call: 'create-foo resfile && create-bar bar', + path, + runPath, + }) + + const resFoo = fs.readFileSync(resolve(path, 'resfile')).toString() + t.equal(resFoo, 'foo', 'should run local pkg bin script') + const resBar = fs.readFileSync(resolve(path, 'bar')).toString() + t.equal(resBar, 'bar', 'should run local pkg bin script') +}) + t.test('local file system path', async t => { const path = t.testdir({ cache: {}, From 252a02cc2dd3a9a4237296e36e8455351a61b418 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Wed, 20 Apr 2022 16:45:02 -0400 Subject: [PATCH 076/406] chore(exec): fix tests --- test/lib/commands/exec.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/lib/commands/exec.js b/test/lib/commands/exec.js index 05b9b7b0cce84..d6e598d568d5b 100644 --- a/test/lib/commands/exec.js +++ b/test/lib/commands/exec.js @@ -1365,6 +1365,7 @@ t.test('workspaces', async t => { }), }) + const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } PROGRESS_IGNORED = true npm.localBin = resolve(npm.localPrefix, 'node_modules', '.bin') @@ -1407,7 +1408,11 @@ t.test('workspaces', async t => { config.yes = false ARB_ACTUAL_TREE[npm.localPrefix] = { - children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]), + inventory: { + query () { + return new Set([{ ...pkg, package: pkg }]) + }, + }, } await exec.execWorkspaces([], ['a', 'b']) From a677f49e29ee9d472c8c9aa1c9eb3d5d8b4ee4a9 Mon Sep 17 00:00:00 2001 From: Marco Tizzoni Date: Wed, 20 Apr 2022 23:07:02 +0200 Subject: [PATCH 077/406] fix: Use node in and fallback to PATH if not found (#4778) Co-authored-by: Marco Tizzoni --- bin/npx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/npx b/bin/npx index 4b58a104b9e42..a34e3459b5a70 100755 --- a/bin/npx +++ b/bin/npx @@ -12,6 +12,9 @@ case `uname` in esac NODE_EXE="$basedir/node.exe" +if ! [ -x "$NODE_EXE" ]; then + NODE_EXE="$basedir/node" +fi if ! [ -x "$NODE_EXE" ]; then NODE_EXE=node fi From c07778e0ac15122be398e1b24e2a4f138554435a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Apr 2022 14:21:46 -0700 Subject: [PATCH 078/406] chore(latest): release arborist 5.1.0 (#4779) * chore(latest): release arborist 5.1.0 * deps: @npmcli/arborist@5.1.0 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: npm cli ops bot --- package-lock.json | 2 +- workspaces/arborist/CHANGELOG.md | 12 ++++++++++++ workspaces/arborist/package.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a2f0677d3414d..59e4e90b07903 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9749,7 +9749,7 @@ }, "workspaces/arborist": { "name": "@npmcli/arborist", - "version": "5.0.6", + "version": "5.1.0", "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", diff --git a/workspaces/arborist/CHANGELOG.md b/workspaces/arborist/CHANGELOG.md index 2bc09164227ad..c1ab55234607c 100644 --- a/workspaces/arborist/CHANGELOG.md +++ b/workspaces/arborist/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [5.1.0](https://github.com/npm/cli/compare/arborist-v5.0.6...arborist-v5.1.0) (2022-04-19) + + +### Features + +* **arborist:** add support for installLinks ([0ebadf5](https://github.com/npm/cli/commit/0ebadf5b603368557e9e837a46ea5c59c2677a81)) + + +### Bug Fixes + +* **arborist:** when replacing a Link with a Node, make sure to remove the Link target from the root ([3d96494](https://github.com/npm/cli/commit/3d964940f410052918e37a9b05818fe9dc4cd86a)) + ### [5.0.6](https://github.com/npm/cli/compare/arborist-v5.0.5...arborist-v5.0.6) (2022-04-13) diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index 01e3db329ad50..a4d29f14e5726 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "5.0.6", + "version": "5.1.0", "description": "Manage node_modules trees", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", From 52fd23bf05d5017b05ba67e1c1a94e2244e91093 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 20 Apr 2022 14:23:05 -0700 Subject: [PATCH 079/406] chore(latest): release libnpmexec 4.0.4 (#4780) * chore(latest): release libnpmexec 4.0.4 * deps: libnpmexec@4.0.4 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: npm cli ops bot --- package-lock.json | 2 +- workspaces/libnpmexec/CHANGELOG.md | 8 ++++++++ workspaces/libnpmexec/package.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 59e4e90b07903..eaed3d6683105 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9846,7 +9846,7 @@ } }, "workspaces/libnpmexec": { - "version": "4.0.3", + "version": "4.0.4", "license": "ISC", "dependencies": { "@npmcli/arborist": "^5.0.0", diff --git a/workspaces/libnpmexec/CHANGELOG.md b/workspaces/libnpmexec/CHANGELOG.md index 7e31757ac1bfb..ffa1212ee1ad6 100644 --- a/workspaces/libnpmexec/CHANGELOG.md +++ b/workspaces/libnpmexec/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +### [4.0.4](https://github.com/npm/cli/compare/libnpmexec-v4.0.3...libnpmexec-v4.0.4) (2022-04-19) + + +### Bug Fixes + +* **exec:** workspaces support ([6253d19](https://github.com/npm/cli/commit/6253d1968d8390ea6b16604ff3abb5e6509349c9)) +* **libnpmexec:** fix read mixed local/registry pkg ([4a46a27](https://github.com/npm/cli/commit/4a46a27f2b968e2f8c1f4821508f93013738c482)) + ### [4.0.3](https://github.com/npm/cli/compare/libnpmexec-v4.0.2...libnpmexec-v4.0.3) (2022-04-06) diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index 72a1ee983520e..5a8f7e4af2c68 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -1,6 +1,6 @@ { "name": "libnpmexec", - "version": "4.0.3", + "version": "4.0.4", "files": [ "bin/", "lib/" From 392882b2413f77c8a10e14dd2d23c0b524595f25 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 20 Apr 2022 09:21:54 -0700 Subject: [PATCH 080/406] chore(publish): add _auth tests --- .../test/lib/commands/publish.js.test.cjs | 247 +----------------- test/fixtures/mock-registry.js | 5 + test/lib/commands/publish.js | 72 +++++ 3 files changed, 78 insertions(+), 246 deletions(-) diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index c6f757e8a9b2e..41557ca2fcee3 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -5,251 +5,6 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/commands/publish.js TAP dry-run > must match snapshot 1`] = ` -Array [ - Array [ - "", - ], - Array [ - "", - "package: test-package@1.0.0", - ], - Array [ - "=== Tarball Contents ===", - ], - Array [ - "", - "87B package.json", - ], - Array [ - "=== Tarball Details ===", - ], - Array [ - "", - String( - name: test-package - version: 1.0.0 - filename: test-package-1.0.0.tgz - package size: 160 B - unpacked size: 87 B - shasum:{sha} - integrity:{sha} - total files: 1 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ (dry-run)", - ], -] -` - -exports[`test/lib/commands/publish.js TAP has auth for scope configured registry > new package version 1`] = ` +exports[`test/lib/commands/publish.js TAP scoped _auth config scoped registry > new package version 1`] = ` + @npm/test-package@1.0.0 ` - -exports[`test/lib/commands/publish.js TAP ignore-scripts > new package version 1`] = ` -+ test-package@1.0.0 -` - -exports[`test/lib/commands/publish.js TAP json > must match snapshot 1`] = ` -Array [ - Array [ - "", - "Publishing to https://registry.npmjs.org/", - ], -] -` - -exports[`test/lib/commands/publish.js TAP json > new package json 1`] = ` -{ - "id": "test-package@1.0.0", - "name": "test-package", - "version": "1.0.0", - "size": 160, - "unpackedSize": 87, - "shasum": "{sha}", - "integrity": "{sha}", - "filename": "test-package-1.0.0.tgz", - "files": [ - { - "path": "package.json", - "size": 87, - "mode": 420 - } - ], - "entryCount": 1, - "bundled": [] -} -` - -exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot 1`] = ` -+ test-package@1.0.0 -` - -exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = ` -Array [ - Array [ - "", - "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)", - ], -] -` - -exports[`test/lib/commands/publish.js TAP re-loads publishConfig.registry if added during script process > new package version 1`] = ` -+ test-package@1.0.0 -` - -exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = ` - -` - -exports[`test/lib/commands/publish.js TAP tarball > must match snapshot 1`] = ` -Array [ - Array [ - "", - ], - Array [ - "", - "package: test-tar-package@1.0.0", - ], - Array [ - "=== Tarball Contents ===", - ], - Array [ - "", - String( - 26B index.js - 98B package.json - ), - ], - Array [ - "=== Tarball Details ===", - ], - Array [ - "", - String( - name: test-tar-package - version: 1.0.0 - filename: test-tar-package-1.0.0.tgz - package size: 218 B - unpacked size: 124 B - shasum:{sha} - integrity:{sha} - total files: 2 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/", - ], -] -` - -exports[`test/lib/commands/publish.js TAP tarball > new package json 1`] = ` -+ test-tar-package@1.0.0 -` - -exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > all public workspaces 1`] = ` -+ workspace-a@1.2.3-a -+ workspace-b@1.2.3-n -+ workspace-n@1.2.3-n -` - -exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > warns about skipped private workspace in color 1`] = ` -Array [ - Array [ - "publish", - "Skipping workspace \\u001b[32mworkspace-p\\u001b[39m, marked as \\u001b[1mprivate\\u001b[22m", - ], -] -` - -exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > all public workspaces 1`] = ` -+ workspace-a@1.2.3-a -+ workspace-b@1.2.3-n -+ workspace-n@1.2.3-n -` - -exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > warns about skipped private workspace 1`] = ` -Array [ - Array [ - "publish", - "Skipping workspace workspace-p, marked as private", - ], -] -` - -exports[`test/lib/commands/publish.js TAP workspaces json > all workspaces in json 1`] = ` -{ - "workspace-a": { - "id": "workspace-a@1.2.3-a", - "name": "workspace-a", - "version": "1.2.3-a", - "size": 162, - "unpackedSize": 82, - "shasum": "{sha}", - "integrity": "{sha}", - "filename": "workspace-a-1.2.3-a.tgz", - "files": [ - { - "path": "package.json", - "size": 82, - "mode": 420 - } - ], - "entryCount": 1, - "bundled": [] - }, - "workspace-b": { - "id": "workspace-b@1.2.3-n", - "name": "workspace-b", - "version": "1.2.3-n", - "size": 171, - "unpackedSize": 92, - "shasum": "{sha}", - "integrity": "{sha}", - "filename": "workspace-b-1.2.3-n.tgz", - "files": [ - { - "path": "package.json", - "size": 92, - "mode": 420 - } - ], - "entryCount": 1, - "bundled": [] - }, - "workspace-n": { - "id": "workspace-n@1.2.3-n", - "name": "workspace-n", - "version": "1.2.3-n", - "size": 140, - "unpackedSize": 42, - "shasum": "{sha}", - "integrity": "{sha}", - "filename": "workspace-n-1.2.3-n.tgz", - "files": [ - { - "path": "package.json", - "size": 42, - "mode": 420 - } - ], - "entryCount": 1, - "bundled": [] - } -} -` - -exports[`test/lib/commands/publish.js TAP workspaces one workspace - success > single workspace 1`] = ` -+ workspace-a@1.2.3-a -` diff --git a/test/fixtures/mock-registry.js b/test/fixtures/mock-registry.js index 5e39dcf48315a..5890fa7ee9366 100644 --- a/test/fixtures/mock-registry.js +++ b/test/fixtures/mock-registry.js @@ -11,6 +11,7 @@ class MockRegistry { #nock #registry #authorization + #basic constructor (opts) { if (!opts.registry) { @@ -18,6 +19,7 @@ class MockRegistry { } this.#registry = (new URL(opts.registry)).origin this.#authorization = opts.authorization + this.#basic = opts.basic // Required for this.package this.#tap = opts.tap } @@ -32,6 +34,9 @@ class MockRegistry { if (this.#authorization) { reqheaders.authorization = `Bearer ${this.#authorization}` } + if (this.#basic) { + reqheaders.authorization = `Basic ${this.#basic}` + } this.#nock = tnock(this.#tap, this.#registry, { reqheaders }) } return this.#nock diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index b17424b084461..885e820422ec0 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -10,6 +10,7 @@ const pkg = 'test-package' const token = 'test-auth-token' const auth = { '//registry.npmjs.org/:_authToken': token } const alternateRegistry = 'https://other.registry.npmjs.org' +const basic = Buffer.from('test-user:test-password').toString('base64') const pkgJson = { name: pkg, @@ -602,3 +603,74 @@ t.test('ignore-scripts', async t => { 'did not run postpublish' ) }) + +t.test('_auth config default registry', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + _auth: basic, + }, + prefixDir: { + 'package.json': JSON.stringify(pkgJson), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + basic, + }) + registry.nock.put(`/${pkg}`).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'new package version') +}) + +t.test('bare _auth config scoped registry', async t => { + const { npm } = await loadMockNpm(t, { + config: { + '@npm:registry': alternateRegistry, + _auth: basic, + }, + prefixDir: { + 'package.json': JSON.stringify({ + name: '@npm/test-package', + version: '1.0.0', + }, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + await t.rejects( + npm.exec('publish', []), + { message: `This command requires you to be logged in to ${alternateRegistry}` } + ) +}) + +t.test('scoped _auth config scoped registry', async t => { + const spec = npa('@npm/test-package') + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + '@npm:registry': alternateRegistry, + [`${alternateRegistry.slice(6)}/:_auth`]: basic, + }, + prefixDir: { + 'package.json': JSON.stringify({ + name: '@npm/test-package', + version: '1.0.0', + }, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + const registry = new MockRegistry({ + tap: t, + registry: alternateRegistry, + basic, + }) + registry.nock.put(`/${spec.escapedName}`).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'new package version') +}) From 6cd6831eaa9e1681e07f6646e6f13cce344e1250 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 20 Apr 2022 10:07:43 -0700 Subject: [PATCH 081/406] docs: explain that _auth only goes to npm registry --- docs/content/using-npm/config.md | 2 + lib/utils/config/definitions.js | 2 + .../test/lib/commands/publish.js.test.cjs | 253 ++++++++++++++++++ .../lib/utils/config/definitions.js.test.cjs | 2 + .../lib/utils/config/describe-all.js.test.cjs | 2 + 5 files changed, 261 insertions(+) diff --git a/docs/content/using-npm/config.md b/docs/content/using-npm/config.md index 200a2e401c7a6..ba79dd505a88e 100644 --- a/docs/content/using-npm/config.md +++ b/docs/content/using-npm/config.md @@ -138,6 +138,8 @@ npm ls --global --parseable --long --loglevel info * Type: null or String A basic-auth string to use when authenticating against the npm registry. +This will ONLY be used to authenticate against the npm registry. For other +registries you will need to scope it like "//other-registry.tld/:_auth" Warning: This should generally not be set via a command-line option. It is safer to use a registry-provided authentication bearer token stored in the diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index f4ffb821837b0..4a1f971d85436 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -147,6 +147,8 @@ define('_auth', { type: [null, String], description: ` A basic-auth string to use when authenticating against the npm registry. + This will ONLY be used to authenticate against the npm registry. For other + registries you will need to scope it like "//other-registry.tld/:_auth" Warning: This should generally not be set via a command-line option. It is safer to use a registry-provided authentication bearer token stored in diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index 41557ca2fcee3..6a33b891e083d 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -5,6 +5,259 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' +exports[`test/lib/commands/publish.js TAP _auth config default registry > new package version 1`] = ` ++ test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP dry-run > must match snapshot 1`] = ` +Array [ + Array [ + "", + ], + Array [ + "", + "package: test-package@1.0.0", + ], + Array [ + "=== Tarball Contents ===", + ], + Array [ + "", + "87B package.json", + ], + Array [ + "=== Tarball Details ===", + ], + Array [ + "", + String( + name: test-package + version: 1.0.0 + filename: test-package-1.0.0.tgz + package size: 160 B + unpacked size: 87 B + shasum:{sha} + integrity:{sha} + total files: 1 + ), + ], + Array [ + "", + "", + ], + Array [ + "", + "Publishing to https://registry.npmjs.org/ (dry-run)", + ], +] +` + +exports[`test/lib/commands/publish.js TAP has auth for scope configured registry > new package version 1`] = ` ++ @npm/test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP ignore-scripts > new package version 1`] = ` ++ test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP json > must match snapshot 1`] = ` +Array [ + Array [ + "", + "Publishing to https://registry.npmjs.org/", + ], +] +` + +exports[`test/lib/commands/publish.js TAP json > new package json 1`] = ` +{ + "id": "test-package@1.0.0", + "name": "test-package", + "version": "1.0.0", + "size": 160, + "unpackedSize": 87, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "test-package-1.0.0.tgz", + "files": [ + { + "path": "package.json", + "size": 87, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] +} +` + +exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot 1`] = ` ++ test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = ` +Array [ + Array [ + "", + "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)", + ], +] +` + +exports[`test/lib/commands/publish.js TAP re-loads publishConfig.registry if added during script process > new package version 1`] = ` ++ test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = ` + +` + exports[`test/lib/commands/publish.js TAP scoped _auth config scoped registry > new package version 1`] = ` + @npm/test-package@1.0.0 ` + +exports[`test/lib/commands/publish.js TAP tarball > must match snapshot 1`] = ` +Array [ + Array [ + "", + ], + Array [ + "", + "package: test-tar-package@1.0.0", + ], + Array [ + "=== Tarball Contents ===", + ], + Array [ + "", + String( + 26B index.js + 98B package.json + ), + ], + Array [ + "=== Tarball Details ===", + ], + Array [ + "", + String( + name: test-tar-package + version: 1.0.0 + filename: test-tar-package-1.0.0.tgz + package size: 218 B + unpacked size: 124 B + shasum:{sha} + integrity:{sha} + total files: 2 + ), + ], + Array [ + "", + "", + ], + Array [ + "", + "Publishing to https://registry.npmjs.org/", + ], +] +` + +exports[`test/lib/commands/publish.js TAP tarball > new package json 1`] = ` ++ test-tar-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > all public workspaces 1`] = ` ++ workspace-a@1.2.3-a ++ workspace-b@1.2.3-n ++ workspace-n@1.2.3-n +` + +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > warns about skipped private workspace in color 1`] = ` +Array [ + Array [ + "publish", + "Skipping workspace \\u001b[32mworkspace-p\\u001b[39m, marked as \\u001b[1mprivate\\u001b[22m", + ], +] +` + +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > all public workspaces 1`] = ` ++ workspace-a@1.2.3-a ++ workspace-b@1.2.3-n ++ workspace-n@1.2.3-n +` + +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > warns about skipped private workspace 1`] = ` +Array [ + Array [ + "publish", + "Skipping workspace workspace-p, marked as private", + ], +] +` + +exports[`test/lib/commands/publish.js TAP workspaces json > all workspaces in json 1`] = ` +{ + "workspace-a": { + "id": "workspace-a@1.2.3-a", + "name": "workspace-a", + "version": "1.2.3-a", + "size": 162, + "unpackedSize": 82, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "workspace-a-1.2.3-a.tgz", + "files": [ + { + "path": "package.json", + "size": 82, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] + }, + "workspace-b": { + "id": "workspace-b@1.2.3-n", + "name": "workspace-b", + "version": "1.2.3-n", + "size": 171, + "unpackedSize": 92, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "workspace-b-1.2.3-n.tgz", + "files": [ + { + "path": "package.json", + "size": 92, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] + }, + "workspace-n": { + "id": "workspace-n@1.2.3-n", + "name": "workspace-n", + "version": "1.2.3-n", + "size": 140, + "unpackedSize": 42, + "shasum": "{sha}", + "integrity": "{sha}", + "filename": "workspace-n-1.2.3-n.tgz", + "files": [ + { + "path": "package.json", + "size": 42, + "mode": 420 + } + ], + "entryCount": 1, + "bundled": [] + } +} +` + +exports[`test/lib/commands/publish.js TAP workspaces one workspace - success > single workspace 1`] = ` ++ workspace-a@1.2.3-a +` diff --git a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs index b190d7eb10ba6..ff00f9a0f9b3d 100644 --- a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs @@ -169,6 +169,8 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for _auth * Type: null or String A basic-auth string to use when authenticating against the npm registry. +This will ONLY be used to authenticate against the npm registry. For other +registries you will need to scope it like "//other-registry.tld/:_auth" Warning: This should generally not be set via a command-line option. It is safer to use a registry-provided authentication bearer token stored in the diff --git a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs index a97b35d3acfe2..6740b94c772c8 100644 --- a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs @@ -12,6 +12,8 @@ exports[`test/lib/utils/config/describe-all.js TAP > must match snapshot 1`] = ` * Type: null or String A basic-auth string to use when authenticating against the npm registry. +This will ONLY be used to authenticate against the npm registry. For other +registries you will need to scope it like "//other-registry.tld/:_auth" Warning: This should generally not be set via a command-line option. It is safer to use a registry-provided authentication bearer token stored in the From 873ac7a6ebb41b5ff1e0907f57c5b7e73cc16f0c Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 21 Apr 2022 07:38:08 -0700 Subject: [PATCH 082/406] chore(publish): add test for _auth with configured registry --- .../test/lib/commands/publish.js.test.cjs | 4 +++ test/lib/commands/publish.js | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index 6a33b891e083d..f90cf3152e80f 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -9,6 +9,10 @@ exports[`test/lib/commands/publish.js TAP _auth config default registry > new pa + test-package@1.0.0 ` +exports[`test/lib/commands/publish.js TAP bare _auth and registry config > new package version 1`] = ` ++ @npm/test-package@1.0.0 +` + exports[`test/lib/commands/publish.js TAP dry-run > must match snapshot 1`] = ` Array [ Array [ diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index 885e820422ec0..3cbe962382e21 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -626,6 +626,33 @@ t.test('_auth config default registry', async t => { t.matchSnapshot(joinedOutput(), 'new package version') }) +t.test('bare _auth and registry config', async t => { + const spec = npa('@npm/test-package') + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + registry: alternateRegistry, + _auth: basic, + }, + prefixDir: { + 'package.json': JSON.stringify({ + name: '@npm/test-package', + version: '1.0.0', + }, null, 2), + }, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + const registry = new MockRegistry({ + tap: t, + registry: alternateRegistry, + basic, + }) + registry.nock.put(`/${spec.escapedName}`).reply(200, {}) + await npm.exec('publish', []) + t.matchSnapshot(joinedOutput(), 'new package version') +}) + t.test('bare _auth config scoped registry', async t => { const { npm } = await loadMockNpm(t, { config: { From fa3d82989df7071cfe500c5f9cc09c597bcc17ee Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Thu, 21 Apr 2022 12:19:44 -0400 Subject: [PATCH 083/406] docs: include org instructions in scoped publish (#4772) * doc: include org instructions in scoped publish * doc: update scope context to add user scopes * Update docs/content/using-npm/scope.md Co-authored-by: Gar Co-authored-by: Luke Karrys Co-authored-by: Gar --- docs/content/using-npm/scope.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/content/using-npm/scope.md b/docs/content/using-npm/scope.md index 911d7ea5177c9..1abbe9081ead8 100644 --- a/docs/content/using-npm/scope.md +++ b/docs/content/using-npm/scope.md @@ -79,9 +79,23 @@ If you wish, you may associate a scope with a registry; see below. #### Publishing public scoped packages to the primary npm registry -To publish a public scoped package, you must specify `--access public` with -the initial publication. This will publish the package and set access -to `public` as if you had run `npm access public` after publishing. +Publishing to a scope, you have two options: + +- Publishing to your user scope (example: `@username/module`) +- Publishing to an organization scope (example: `@org/module`) + +If publishing a public module to an organization scope, you must +first either create an organization with the name of the scope +that you'd like to publish to or be added to an existing organization +with the appropriate permisssions. For example, if you'd like to +publish to `@org`, you would need to create the `org` organization +on npmjs.com prior to trying to publish. + +Scoped packages are not public by default. You will need to specify +`--access public` with the initial `npm publish` command. This will publish +the package and set access to `public` as if you had run `npm access public` +after publishing. You do not need to do this when publishing new versions of +an existing scoped package. #### Publishing private scoped packages to the npm registry From e9163b48d8e46a80d2a4cc98c492b94dfa152cb8 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Tue, 26 Apr 2022 16:16:36 -0400 Subject: [PATCH 084/406] fix(libnpmpublish): unpublish from custom reg (#4657) Fixes unpublishing a package from a registry url that has pathnames after its hostname. Fixes: https://github.com/npm/cli/issues/4253 --- workspaces/libnpmpublish/lib/unpublish.js | 21 ++++++++- workspaces/libnpmpublish/test/unpublish.js | 55 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/workspaces/libnpmpublish/lib/unpublish.js b/workspaces/libnpmpublish/lib/unpublish.js index 91f5252aa33fc..9b124c11435fb 100644 --- a/workspaces/libnpmpublish/lib/unpublish.js +++ b/workspaces/libnpmpublish/lib/unpublish.js @@ -1,9 +1,26 @@ 'use strict' +const { URL } = require('url') const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') const semver = require('semver') -const { URL } = require('url') + +// given a tarball url and a registry url, returns just the +// relevant pathname portion of it, so that it can be handled +// elegantly by npm-registry-fetch which only expects pathnames +// and handles the registry hostname via opts +const getPathname = (tarball, registry) => { + const registryUrl = new URL(registry).pathname.slice(1) + let tarballUrl = new URL(tarball).pathname.slice(1) + + // test the tarball url to see if it starts with a possible + // pathname from the registry url, in that case strips that portion + // of it so that we only return the post-registry-url pathname + if (registryUrl) { + tarballUrl = tarballUrl.slice(registryUrl.length) + } + return tarballUrl +} const unpublish = async (spec, opts) => { spec = npa(spec) @@ -82,7 +99,7 @@ const unpublish = async (spec, opts) => { ...opts, query: { write: true }, }) - const tarballUrl = new URL(dist.tarball).pathname.slice(1) + const tarballUrl = getPathname(dist.tarball, opts.registry) await npmFetch(`${tarballUrl}/-rev/${_rev}`, { ...opts, method: 'DELETE', diff --git a/workspaces/libnpmpublish/test/unpublish.js b/workspaces/libnpmpublish/test/unpublish.js index 6fbe802766024..b59dad6d36a06 100644 --- a/workspaces/libnpmpublish/test/unpublish.js +++ b/workspaces/libnpmpublish/test/unpublish.js @@ -134,6 +134,61 @@ t.test('unpublish specific version', async t => { t.ok(ret, 'foo was unpublished') }) +t.test('unpublishing from a custom registry', async t => { + const opt = { + registry: 'https://artifactory.example.com/api/npm/npm-snapshots/', + } + const reg = opt.registry + const doc = { + _id: 'foo', + _rev: REV, + _revisions: [1, 2, 3], + _attachments: [1, 2, 3], + name: 'foo', + 'dist-tags': { + latest: '1.0.1', + }, + versions: { + '1.0.0': { + name: 'foo', + dist: { + tarball: `${reg}/foo/-/foo-1.0.0.tgz`, + }, + }, + '1.0.1': { + name: 'foo', + dist: { + tarball: `${reg}/foo/-/foo-1.0.1.tgz`, + }, + }, + }, + } + const postEdit = { + _id: 'foo', + _rev: REV, + name: 'foo', + 'dist-tags': { + latest: '1.0.0', + }, + versions: { + '1.0.0': { + name: 'foo', + dist: { + tarball: `${reg}/foo/-/foo-1.0.0.tgz`, + }, + }, + }, + } + + const srv = tnock(t, reg) + srv.get('/foo?write=true').reply(200, doc) + srv.put(`/foo/-rev/${REV}`, postEdit).reply(200) + srv.get('/foo?write=true').reply(200, postEdit) + srv.delete(`/foo/-/foo-1.0.1.tgz/-rev/${REV}`).reply(200) + const ret = await unpub('foo@1.0.1', opt) + t.ok(ret, 'foo was unpublished') +}) + t.test('404 considered a success', async t => { const srv = tnock(t, REG) srv.get('/foo?write=true').reply(404) From e163a0b4ba6da539c43f5af09d58aa45d964a720 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Tue, 26 Apr 2022 13:27:01 -0700 Subject: [PATCH 085/406] chore(benchmark): add comment permission check and filter paths (#4766) The updates the issue comment check in the benchmark script, so it only will trigger if posted by a user with admin rights to the repo. It also changes the comment to trigger it to `@npm-robot benchmark this` For pull requests, it now limits benchmarks only when the files changed include something inside `lib/`. Requires https://github.com/npm/benchmarks/pull/30 to be merged in the benchmark repo to allow `issue_comment` as a valid trigger. --- .github/workflows/benchmark.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 1d8e3455c25e3..2e363cb3006ec 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -4,6 +4,8 @@ on: pull_request: branches: - '*' + paths: + - lib/** issue_comment: types: - created @@ -18,7 +20,8 @@ jobs: github.event_name == 'pull_request' || ( github.event_name == 'issue_comment' && github.event.issue.pull_request && - startsWith(github.event.comment.body, 'test this please ✅') + github.event.issue.state == 'open' && + startsWith(github.event.comment.body, '@npm-robot benchmark this') ) env: # gh cli uses these env vars for owner/repo/token @@ -39,6 +42,12 @@ jobs: PR="${{ github.event.pull_request.number }}" else PR="${{ github.event.issue.number }}" + SENDER="${{ github.event.issue.sender.login }}" + ROLE=$(gh api repos/${OWNER}/${REPO}/collaborators/${SENDER}/permission -q '.permission') + if [[ "$ROLE" != "admin"]]; then + echo "${SENDER} is ${ROLE}, not an admin, exiting" + exit 0 + fi fi EVENT="${EVENT_NAME} ${OWNER}/${REPO}#${PR}" @@ -58,11 +67,21 @@ jobs: if: | github.event_name == 'issue_comment' && github.event.issue.pull_request && - startsWith(github.event.comment.body, 'test this please ✅') + github.event.issue.state == 'open' && + startsWith(github.event.comment.body, '@npm-robot benchmark this') env: # gh cli uses this env var as the token GITHUB_TOKEN: ${{ secrets.NPM_BENCHMARKS_TOKEN }} run: | + OWNER="${{ github.event.repository.owner.login }}" + REPO="${{ github.event.repository.name }}" + SENDER="${{ github.event.issue.sender.login }}" + ROLE=$(gh api repos/${OWNER}/${REPO}/collaborators/${SENDER}/permission -q '.permission') + if [[ "$ROLE" != "admin"]]; then + echo "${SENDER} is ${ROLE}, not an admin, exiting" + exit 0 + fi + COMMENT_NODE_ID="${{ github.event.comment.node_id }}" QUERY='mutation ($inputData:AddReactionInput!) { addReaction (input:$inputData) { From 5b6cbf8453903a82a13f37c1edf47e6b83785432 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 14:26:44 -0700 Subject: [PATCH 086/406] chore(deps): @npmcli/template-oss@3.4.2 --- .github/workflows/ci-docs.yml | 8 +- .github/workflows/ci-libnpmaccess.yml | 8 +- .github/workflows/ci-libnpmdiff.yml | 8 +- .github/workflows/ci-libnpmexec.yml | 8 +- .github/workflows/ci-libnpmfund.yml | 8 +- .github/workflows/ci-libnpmhook.yml | 8 +- .github/workflows/ci-libnpmorg.yml | 8 +- .github/workflows/ci-libnpmpack.yml | 8 +- .github/workflows/ci-libnpmpublish.yml | 8 +- .github/workflows/ci-libnpmsearch.yml | 8 +- .github/workflows/ci-libnpmteam.yml | 8 +- .github/workflows/ci-libnpmversion.yml | 8 +- .github/workflows/ci-npmcli-arborist.yml | 8 +- .../workflows/release-please-libnpmaccess.yml | 4 +- .../workflows/release-please-libnpmdiff.yml | 4 +- .../workflows/release-please-libnpmexec.yml | 4 +- .../workflows/release-please-libnpmfund.yml | 4 +- .../workflows/release-please-libnpmhook.yml | 4 +- .../workflows/release-please-libnpmorg.yml | 4 +- .../workflows/release-please-libnpmpack.yml | 4 +- .../release-please-libnpmpublish.yml | 4 +- .../workflows/release-please-libnpmsearch.yml | 4 +- .../workflows/release-please-libnpmteam.yml | 4 +- .../release-please-libnpmversion.yml | 4 +- .../release-please-npmcli-arborist.yml | 4 +- docs/package.json | 4 +- package-lock.json | 106 ++++++++++++------ package.json | 4 +- smoke-tests/package.json | 4 +- workspaces/arborist/package.json | 4 +- workspaces/libnpmaccess/package.json | 4 +- workspaces/libnpmdiff/package.json | 4 +- workspaces/libnpmexec/package.json | 4 +- workspaces/libnpmfund/package.json | 4 +- workspaces/libnpmhook/package.json | 4 +- workspaces/libnpmorg/package.json | 4 +- workspaces/libnpmpack/package.json | 4 +- workspaces/libnpmpublish/package.json | 4 +- workspaces/libnpmsearch/package.json | 4 +- workspaces/libnpmteam/package.json | 4 +- workspaces/libnpmversion/package.json | 4 +- 41 files changed, 177 insertions(+), 141 deletions(-) diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index 43fa240ecdaec..c3ffb5e181e44 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16 @@ -58,8 +58,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmaccess.yml b/.github/workflows/ci-libnpmaccess.yml index ca1eb19ae0f01..c01fe627bf555 100644 --- a/.github/workflows/ci-libnpmaccess.yml +++ b/.github/workflows/ci-libnpmaccess.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmdiff.yml b/.github/workflows/ci-libnpmdiff.yml index 856b8d9570b77..6013870ee2c64 100644 --- a/.github/workflows/ci-libnpmdiff.yml +++ b/.github/workflows/ci-libnpmdiff.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmexec.yml b/.github/workflows/ci-libnpmexec.yml index 8c30d053471c3..038e6e5e7e981 100644 --- a/.github/workflows/ci-libnpmexec.yml +++ b/.github/workflows/ci-libnpmexec.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmfund.yml b/.github/workflows/ci-libnpmfund.yml index 337db5b8bf39e..c70892a95c3fe 100644 --- a/.github/workflows/ci-libnpmfund.yml +++ b/.github/workflows/ci-libnpmfund.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmhook.yml b/.github/workflows/ci-libnpmhook.yml index 3ccceb99f8912..b64fd46160aab 100644 --- a/.github/workflows/ci-libnpmhook.yml +++ b/.github/workflows/ci-libnpmhook.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmorg.yml b/.github/workflows/ci-libnpmorg.yml index 2f9ba90a357c5..c87d1ca6e1466 100644 --- a/.github/workflows/ci-libnpmorg.yml +++ b/.github/workflows/ci-libnpmorg.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmpack.yml b/.github/workflows/ci-libnpmpack.yml index 146950c4f825a..a2cb15ab129ac 100644 --- a/.github/workflows/ci-libnpmpack.yml +++ b/.github/workflows/ci-libnpmpack.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmpublish.yml b/.github/workflows/ci-libnpmpublish.yml index 16d693c969866..6b46bd21ddef4 100644 --- a/.github/workflows/ci-libnpmpublish.yml +++ b/.github/workflows/ci-libnpmpublish.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmsearch.yml b/.github/workflows/ci-libnpmsearch.yml index 93f2a0caa5f7c..6bcbc772e7b46 100644 --- a/.github/workflows/ci-libnpmsearch.yml +++ b/.github/workflows/ci-libnpmsearch.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmteam.yml b/.github/workflows/ci-libnpmteam.yml index baaf78ce8dd03..b61d96c1a1f66 100644 --- a/.github/workflows/ci-libnpmteam.yml +++ b/.github/workflows/ci-libnpmteam.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-libnpmversion.yml b/.github/workflows/ci-libnpmversion.yml index 3b24bf420b38e..d2eef632469a0 100644 --- a/.github/workflows/ci-libnpmversion.yml +++ b/.github/workflows/ci-libnpmversion.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci-npmcli-arborist.yml b/.github/workflows/ci-npmcli-arborist.yml index 9998450969334..5ca3ec77a8546 100644 --- a/.github/workflows/ci-npmcli-arborist.yml +++ b/.github/workflows/ci-npmcli-arborist.yml @@ -26,8 +26,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x @@ -63,8 +63,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/release-please-libnpmaccess.yml b/.github/workflows/release-please-libnpmaccess.yml index d71654dda1a6e..13219dea1b8d0 100644 --- a/.github/workflows/release-please-libnpmaccess.yml +++ b/.github/workflows/release-please-libnpmaccess.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmdiff.yml b/.github/workflows/release-please-libnpmdiff.yml index d9a043534b670..e39fce455433b 100644 --- a/.github/workflows/release-please-libnpmdiff.yml +++ b/.github/workflows/release-please-libnpmdiff.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmexec.yml b/.github/workflows/release-please-libnpmexec.yml index bdb8c373cf150..0db48bba04517 100644 --- a/.github/workflows/release-please-libnpmexec.yml +++ b/.github/workflows/release-please-libnpmexec.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmfund.yml b/.github/workflows/release-please-libnpmfund.yml index 53da00c6bafbc..e3d5d2ecd43db 100644 --- a/.github/workflows/release-please-libnpmfund.yml +++ b/.github/workflows/release-please-libnpmfund.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmhook.yml b/.github/workflows/release-please-libnpmhook.yml index 268e4d8f030d4..267c9591576bd 100644 --- a/.github/workflows/release-please-libnpmhook.yml +++ b/.github/workflows/release-please-libnpmhook.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmorg.yml b/.github/workflows/release-please-libnpmorg.yml index e8b7c66e73247..15dc04060c4b3 100644 --- a/.github/workflows/release-please-libnpmorg.yml +++ b/.github/workflows/release-please-libnpmorg.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmpack.yml b/.github/workflows/release-please-libnpmpack.yml index 50548222ef975..1f4d181e1e9d5 100644 --- a/.github/workflows/release-please-libnpmpack.yml +++ b/.github/workflows/release-please-libnpmpack.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmpublish.yml b/.github/workflows/release-please-libnpmpublish.yml index 2bd4026d2cd37..b271b0102db73 100644 --- a/.github/workflows/release-please-libnpmpublish.yml +++ b/.github/workflows/release-please-libnpmpublish.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmsearch.yml b/.github/workflows/release-please-libnpmsearch.yml index 27f3fdec25aaa..b7b3b7e6ee6b2 100644 --- a/.github/workflows/release-please-libnpmsearch.yml +++ b/.github/workflows/release-please-libnpmsearch.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmteam.yml b/.github/workflows/release-please-libnpmteam.yml index f0c7d6e0d1b4b..e2a65d02abe55 100644 --- a/.github/workflows/release-please-libnpmteam.yml +++ b/.github/workflows/release-please-libnpmteam.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-libnpmversion.yml b/.github/workflows/release-please-libnpmversion.yml index f9b91619bc2cf..6949116700c84 100644 --- a/.github/workflows/release-please-libnpmversion.yml +++ b/.github/workflows/release-please-libnpmversion.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/.github/workflows/release-please-npmcli-arborist.yml b/.github/workflows/release-please-npmcli-arborist.yml index 8be72bc777e0a..82693f5825e1b 100644 --- a/.github/workflows/release-please-npmcli-arborist.yml +++ b/.github/workflows/release-please-npmcli-arborist.yml @@ -38,8 +38,8 @@ jobs: - uses: actions/checkout@v3 - name: Setup git user run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" + git config --global user.email "ops+robot@npmjs.com" + git config --global user.name "npm team" - uses: actions/setup-node@v3 with: node-version: 16.x diff --git a/docs/package.json b/docs/package.json index 87c5020e21e08..23e10b619060a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -24,7 +24,7 @@ "@npmcli/eslint-config": "^3.0.1", "@npmcli/fs": "^2.1.0", "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "cmark-gfm": "^0.9.0", "jsdom": "^18.1.0", "marked-man": "^0.7.0", @@ -60,6 +60,6 @@ "ciVersions": [ "16" ], - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/package-lock.json b/package-lock.json index eaed3d6683105..3b7a71406fa64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -163,7 +163,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "licensee": "^8.2.0", "nock": "^13.2.4", "spawk": "^1.7.1", @@ -181,7 +181,7 @@ "@npmcli/eslint-config": "^3.0.1", "@npmcli/fs": "^2.1.0", "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "cmark-gfm": "^0.9.0", "jsdom": "^18.1.0", "marked-man": "^0.7.0", @@ -1046,9 +1046,9 @@ } }, "node_modules/@npmcli/template-oss": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-3.3.2.tgz", - "integrity": "sha512-dxuO704qWTeSt5ievjNRhOB7VB6Mqv66wCaazOksLlAs3CittiCG0P0YWKhXojptNrOET/mGj6ltZV/A/QdGfw==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-3.4.2.tgz", + "integrity": "sha512-r5YaRlWEythue6R85ci/mTDtXOLwGDLlRHg5bH/v+++458SBTjgbQdHKoozJ0xh1ScwbA3z92jWmIzyC7Jpb+A==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -1057,6 +1057,7 @@ "@npmcli/map-workspaces": "^2.0.2", "@npmcli/package-json": "^2.0.0", "diff": "^5.0.0", + "glob": "^8.0.1", "handlebars": "^4.7.7", "hosted-git-info": "^5.0.0", "json-parse-even-better-errors": "^2.3.1", @@ -1075,6 +1076,26 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/@npmcli/template-oss/node_modules/glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@npmcli/template-oss/node_modules/yaml": { "version": "2.0.0-11", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-11.tgz", @@ -9737,7 +9758,7 @@ "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "minify-registry-metadata": "^2.2.0", "rimraf": "^3.0.2", "tap": "^16.0.1", @@ -9792,7 +9813,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "benchmark": "^2.1.4", "chalk": "^4.1.0", "minify-registry-metadata": "^2.1.0", @@ -9815,7 +9836,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -9838,7 +9859,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "tap": "^16.0.1" }, "engines": { @@ -9864,7 +9885,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "bin-links": "^3.0.0", "tap": "^16.0.1" }, @@ -9880,7 +9901,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "tap": "^16.0.1" }, "engines": { @@ -9896,7 +9917,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -9913,7 +9934,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "minipass": "^3.1.1", "nock": "^13.2.4", "tap": "^16.0.1" @@ -9932,7 +9953,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.0.7", "tap": "^16.0.1" }, @@ -9952,7 +9973,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "libnpmpack": "^4.0.0", "lodash.clonedeep": "^4.5.0", "nock": "^13.2.4", @@ -9970,7 +9991,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -9987,7 +10008,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -10007,7 +10028,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "require-inject": "^1.4.4", "tap": "^16.0.1" }, @@ -10476,7 +10497,7 @@ "@npmcli/node-gyp": "^2.0.0", "@npmcli/package-json": "^2.0.0", "@npmcli/run-script": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "benchmark": "^2.1.4", "bin-links": "^3.0.0", "cacache": "^16.0.0", @@ -10642,9 +10663,9 @@ } }, "@npmcli/template-oss": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-3.3.2.tgz", - "integrity": "sha512-dxuO704qWTeSt5ievjNRhOB7VB6Mqv66wCaazOksLlAs3CittiCG0P0YWKhXojptNrOET/mGj6ltZV/A/QdGfw==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-3.4.2.tgz", + "integrity": "sha512-r5YaRlWEythue6R85ci/mTDtXOLwGDLlRHg5bH/v+++458SBTjgbQdHKoozJ0xh1ScwbA3z92jWmIzyC7Jpb+A==", "dev": true, "requires": { "@npmcli/fs": "^2.0.1", @@ -10652,6 +10673,7 @@ "@npmcli/map-workspaces": "^2.0.2", "@npmcli/package-json": "^2.0.0", "diff": "^5.0.0", + "glob": "^8.0.1", "handlebars": "^4.7.7", "hosted-git-info": "^5.0.0", "json-parse-even-better-errors": "^2.3.1", @@ -10663,6 +10685,20 @@ "yaml": "^2.0.0-11" }, "dependencies": { + "glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "yaml": { "version": "2.0.0-11", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-11.tgz", @@ -11403,7 +11439,7 @@ "@npmcli/eslint-config": "^3.0.1", "@npmcli/fs": "^2.1.0", "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "cmark-gfm": "^0.9.0", "jsdom": "^18.1.0", "marked-man": "^0.7.0", @@ -12789,7 +12825,7 @@ "version": "file:workspaces/libnpmaccess", "requires": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "aproba": "^2.0.0", "minipass": "^3.1.1", "nock": "^13.2.4", @@ -12804,7 +12840,7 @@ "@npmcli/disparity-colors": "^2.0.0", "@npmcli/eslint-config": "^3.0.1", "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "binary-extensions": "^2.2.0", "diff": "^5.0.0", "minimatch": "^5.0.1", @@ -12821,7 +12857,7 @@ "@npmcli/ci-detect": "^2.0.0", "@npmcli/eslint-config": "^3.0.1", "@npmcli/run-script": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "bin-links": "^3.0.0", "chalk": "^4.1.0", "mkdirp-infer-owner": "^2.0.0", @@ -12840,7 +12876,7 @@ "requires": { "@npmcli/arborist": "^5.0.0", "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "tap": "^16.0.1" } }, @@ -12848,7 +12884,7 @@ "version": "file:workspaces/libnpmhook", "requires": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "aproba": "^2.0.0", "nock": "^13.2.4", "npm-registry-fetch": "^13.0.0", @@ -12859,7 +12895,7 @@ "version": "file:workspaces/libnpmorg", "requires": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "aproba": "^2.0.0", "minipass": "^3.1.1", "nock": "^13.2.4", @@ -12872,7 +12908,7 @@ "requires": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/run-script": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.0.7", "npm-package-arg": "^9.0.1", "pacote": "^13.0.5", @@ -12883,7 +12919,7 @@ "version": "file:workspaces/libnpmpublish", "requires": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "libnpmpack": "^4.0.0", "lodash.clonedeep": "^4.5.0", "nock": "^13.2.4", @@ -12899,7 +12935,7 @@ "version": "file:workspaces/libnpmsearch", "requires": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "npm-registry-fetch": "^13.0.0", "tap": "^16.0.1" @@ -12909,7 +12945,7 @@ "version": "file:workspaces/libnpmteam", "requires": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "aproba": "^2.0.0", "nock": "^13.2.4", "npm-registry-fetch": "^13.0.0", @@ -12922,7 +12958,7 @@ "@npmcli/eslint-config": "^3.0.1", "@npmcli/git": "^3.0.0", "@npmcli/run-script": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "json-parse-even-better-errors": "^2.3.1", "proc-log": "^2.0.0", "require-inject": "^1.4.4", @@ -14207,7 +14243,7 @@ "requires": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "minify-registry-metadata": "^2.2.0", "rimraf": "^3.0.2", "tap": "^16.0.1", diff --git a/package.json b/package.json index 846510f5cb927..567025106e55f 100644 --- a/package.json +++ b/package.json @@ -200,7 +200,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "licensee": "^8.2.0", "nock": "^13.2.4", "spawk": "^1.7.1", @@ -236,7 +236,7 @@ "templateOSS": { "rootRepo": false, "rootModule": false, - "version": "3.3.2" + "version": "3.4.2" }, "license": "Artistic-2.0", "engines": { diff --git a/smoke-tests/package.json b/smoke-tests/package.json index 787db4d203502..e0844c762840a 100644 --- a/smoke-tests/package.json +++ b/smoke-tests/package.json @@ -22,7 +22,7 @@ "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "minify-registry-metadata": "^2.2.0", "rimraf": "^3.0.2", "tap": "^16.0.1", @@ -32,7 +32,7 @@ "license": "ISC", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2", + "version": "3.4.2", "workspaceRepo": false }, "tap": { diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index a4d29f14e5726..6f6342b3192c5 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -40,7 +40,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "benchmark": "^2.1.4", "chalk": "^4.1.0", "minify-registry-metadata": "^2.1.0", @@ -101,6 +101,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmaccess/package.json b/workspaces/libnpmaccess/package.json index bb6837309821c..2494ef0d9dd97 100644 --- a/workspaces/libnpmaccess/package.json +++ b/workspaces/libnpmaccess/package.json @@ -20,7 +20,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -46,6 +46,6 @@ ], "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmdiff/package.json b/workspaces/libnpmdiff/package.json index 88968216f54ba..20d7637724fce 100644 --- a/workspaces/libnpmdiff/package.json +++ b/workspaces/libnpmdiff/package.json @@ -46,7 +46,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "tap": "^16.0.1" }, "dependencies": { @@ -61,6 +61,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index 5a8f7e4af2c68..d0294cbe229dd 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -50,7 +50,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "bin-links": "^3.0.0", "tap": "^16.0.1" }, @@ -70,6 +70,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmfund/package.json b/workspaces/libnpmfund/package.json index fe8e8d8e37056..9efee46511b54 100644 --- a/workspaces/libnpmfund/package.json +++ b/workspaces/libnpmfund/package.json @@ -45,7 +45,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "tap": "^16.0.1" }, "dependencies": { @@ -56,6 +56,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmhook/package.json b/workspaces/libnpmhook/package.json index 99efed490b3c4..7219e36fcc322 100644 --- a/workspaces/libnpmhook/package.json +++ b/workspaces/libnpmhook/package.json @@ -40,7 +40,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -49,6 +49,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmorg/package.json b/workspaces/libnpmorg/package.json index be6086c115cf0..56adfb6574c86 100644 --- a/workspaces/libnpmorg/package.json +++ b/workspaces/libnpmorg/package.json @@ -31,7 +31,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "minipass": "^3.1.1", "nock": "^13.2.4", "tap": "^16.0.1" @@ -52,6 +52,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmpack/package.json b/workspaces/libnpmpack/package.json index 1aa1d306a412d..4d7f9226cfbab 100644 --- a/workspaces/libnpmpack/package.json +++ b/workspaces/libnpmpack/package.json @@ -26,7 +26,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.0.7", "tap": "^16.0.1" }, @@ -47,6 +47,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmpublish/package.json b/workspaces/libnpmpublish/package.json index ba6e72297074f..1858858d04199 100644 --- a/workspaces/libnpmpublish/package.json +++ b/workspaces/libnpmpublish/package.json @@ -28,7 +28,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "libnpmpack": "^4.0.0", "lodash.clonedeep": "^4.5.0", "nock": "^13.2.4", @@ -53,6 +53,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmsearch/package.json b/workspaces/libnpmsearch/package.json index 85918e2543a75..9c33fcaaa61cf 100644 --- a/workspaces/libnpmsearch/package.json +++ b/workspaces/libnpmsearch/package.json @@ -29,7 +29,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -48,6 +48,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmteam/package.json b/workspaces/libnpmteam/package.json index 52309e1646dd0..80fb95a028958 100644 --- a/workspaces/libnpmteam/package.json +++ b/workspaces/libnpmteam/package.json @@ -19,7 +19,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -42,6 +42,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index 431587f07c4c5..20482ea665be2 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -31,7 +31,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/template-oss": "3.4.2", "require-inject": "^1.4.4", "tap": "^16.0.1" }, @@ -47,6 +47,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2" + "version": "3.4.2" } } From 3f2b24afe205547dbbadf5a6313e95f6b565fb49 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 14:30:12 -0700 Subject: [PATCH 087/406] deps: @npmcli/map-workspaces@2.0.3 --- .../map-workspaces/node_modules/glob/LICENSE | 15 + .../node_modules/glob/common.js | 238 ++++++ .../map-workspaces/node_modules/glob/glob.js | 790 ++++++++++++++++++ .../node_modules/glob/package.json | 56 ++ .../map-workspaces/node_modules/glob/sync.js | 486 +++++++++++ .../@npmcli/map-workspaces/package.json | 30 +- package-lock.json | 56 +- package.json | 2 +- workspaces/arborist/package.json | 2 +- 9 files changed, 1651 insertions(+), 24 deletions(-) create mode 100644 node_modules/@npmcli/map-workspaces/node_modules/glob/LICENSE create mode 100644 node_modules/@npmcli/map-workspaces/node_modules/glob/common.js create mode 100644 node_modules/@npmcli/map-workspaces/node_modules/glob/glob.js create mode 100644 node_modules/@npmcli/map-workspaces/node_modules/glob/package.json create mode 100644 node_modules/@npmcli/map-workspaces/node_modules/glob/sync.js diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/LICENSE b/node_modules/@npmcli/map-workspaces/node_modules/glob/LICENSE new file mode 100644 index 0000000000000..39e8fe16f665a --- /dev/null +++ b/node_modules/@npmcli/map-workspaces/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors + +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/@npmcli/map-workspaces/node_modules/glob/common.js b/node_modules/@npmcli/map-workspaces/node_modules/glob/common.js new file mode 100644 index 0000000000000..fc193ee6fbda5 --- /dev/null +++ b/node_modules/@npmcli/map-workspaces/node_modules/glob/common.js @@ -0,0 +1,238 @@ +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var fs = require("fs") +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasort (a, b) { + return a.localeCompare(b, 'en') +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute + self.fs = options.fs || fs + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + // always treat \ in patterns as escapes, not path separators + options.allowWindowsEscape = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/glob.js b/node_modules/@npmcli/map-workspaces/node_modules/glob/glob.js new file mode 100644 index 0000000000000..37a4d7e60775a --- /dev/null +++ b/node_modules/@npmcli/map-workspaces/node_modules/glob/glob.js @@ -0,0 +1,790 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + + if (!pattern) + return false + + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + this._processing = 0 + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = isAbsolute(e) ? e : this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) + e = abs + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + self.fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + self.fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + self.fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return self.fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) +} diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/package.json b/node_modules/@npmcli/map-workspaces/node_modules/glob/package.json new file mode 100644 index 0000000000000..54940cbeb4208 --- /dev/null +++ b/node_modules/@npmcli/map-workspaces/node_modules/glob/package.json @@ -0,0 +1,56 @@ +{ + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "name": "glob", + "description": "a little globber", + "version": "8.0.1", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "main": "glob.js", + "files": [ + "glob.js", + "sync.js", + "common.js" + ], + "engines": { + "node": ">=12" + }, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "devDependencies": { + "memfs": "^3.2.0", + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^16.0.1", + "tick": "0.0.6" + }, + "tap": { + "before": "test/00-setup.js", + "after": "test/zz-cleanup.js", + "statements": 90, + "branches": 90, + "functions": 90, + "lines": 90, + "jobs": 1 + }, + "scripts": { + "prepublish": "npm run benchclean", + "profclean": "rm -f v8.log profile.txt", + "test": "tap", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", + "bench": "bash benchmark.sh", + "prof": "bash prof.sh && cat profile.txt", + "benchclean": "node benchclean.js" + }, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } +} diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/sync.js b/node_modules/@npmcli/map-workspaces/node_modules/glob/sync.js new file mode 100644 index 0000000000000..c705a9c0291dd --- /dev/null +++ b/node_modules/@npmcli/map-workspaces/node_modules/glob/sync.js @@ -0,0 +1,486 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return + + var abs = this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) { + e = abs + } + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = this.fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } + } + + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, this.fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = this.fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = this.fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/node_modules/@npmcli/map-workspaces/package.json b/node_modules/@npmcli/map-workspaces/package.json index 8ae823cf3e9b7..3025081e5529b 100644 --- a/node_modules/@npmcli/map-workspaces/package.json +++ b/node_modules/@npmcli/map-workspaces/package.json @@ -1,16 +1,19 @@ { "name": "@npmcli/map-workspaces", - "version": "2.0.2", + "version": "2.0.3", "main": "lib/index.js", "files": [ - "bin", - "lib" + "bin/", + "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "description": "Retrieves a name:pathname Map for a given workspaces config", - "repository": "https://github.com/npm/map-workspaces", + "repository": { + "type": "git", + "url": "https://github.com/npm/map-workspaces.git" + }, "keywords": [ "npm", "npmcli", @@ -22,33 +25,34 @@ "author": "GitHub Inc.", "license": "ISC", "scripts": { - "lint": "eslint '**/*.js'", + "lint": "eslint \"**/*.js\"", "pretest": "npm run lint", "test": "tap", "snap": "tap", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", - "postlint": "npm-template-check", + "postlint": "template-oss-check", "lintfix": "npm run lint -- --fix", "posttest": "npm run lint", - "template-copy": "npm-template-copy --force" + "template-oss-apply": "template-oss-apply --force" }, "tap": { "check-coverage": true }, "devDependencies": { - "@npmcli/template-oss": "^2.9.2", - "eslint": "^8.10.0", - "tap": "^15.1.6" + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "3.4.1", + "tap": "^16.0.1" }, "dependencies": { "@npmcli/name-from-folder": "^1.0.1", - "glob": "^7.2.0", + "glob": "^8.0.1", "minimatch": "^5.0.1", "read-package-json-fast": "^2.0.3" }, "templateOSS": { - "version": "2.9.2" + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "3.4.1" } } diff --git a/package-lock.json b/package-lock.json index 3b7a71406fa64..68a127cdb11ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,7 +91,7 @@ "@npmcli/ci-detect": "^2.0.0", "@npmcli/config": "^4.1.0", "@npmcli/fs": "^2.1.0", - "@npmcli/map-workspaces": "^2.0.2", + "@npmcli/map-workspaces": "^2.0.3", "@npmcli/package-json": "^2.0.0", "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", @@ -952,17 +952,38 @@ } }, "node_modules/@npmcli/map-workspaces": { - "version": "2.0.2", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-2.0.3.tgz", + "integrity": "sha512-X6suAun5QyupNM8iHkNPh0AHdRC2rb1W+MTdMvvA/2ixgmqZwlq5cGUBgmKHUHT2LgrkKJMAXbfAoTxOigpK8Q==", "inBundle": true, - "license": "ISC", "dependencies": { "@npmcli/name-from-folder": "^1.0.1", - "glob": "^7.2.0", + "glob": "^8.0.1", "minimatch": "^5.0.1", "read-package-json-fast": "^2.0.3" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "inBundle": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@npmcli/metavuln-calculator": { @@ -9775,7 +9796,7 @@ "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.0", + "@npmcli/map-workspaces": "^2.0.3", "@npmcli/metavuln-calculator": "^3.0.1", "@npmcli/move-file": "^2.0.0", "@npmcli/name-from-folder": "^1.0.1", @@ -10490,7 +10511,7 @@ "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/eslint-config": "^3.0.1", "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.0", + "@npmcli/map-workspaces": "^2.0.3", "@npmcli/metavuln-calculator": "^3.0.1", "@npmcli/move-file": "^2.0.0", "@npmcli/name-from-folder": "^1.0.1", @@ -10599,12 +10620,29 @@ } }, "@npmcli/map-workspaces": { - "version": "2.0.2", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-2.0.3.tgz", + "integrity": "sha512-X6suAun5QyupNM8iHkNPh0AHdRC2rb1W+MTdMvvA/2ixgmqZwlq5cGUBgmKHUHT2LgrkKJMAXbfAoTxOigpK8Q==", "requires": { "@npmcli/name-from-folder": "^1.0.1", - "glob": "^7.2.0", + "glob": "^8.0.1", "minimatch": "^5.0.1", "read-package-json-fast": "^2.0.3" + }, + "dependencies": { + "glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "@npmcli/metavuln-calculator": { diff --git a/package.json b/package.json index 567025106e55f..8d96d76569c28 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@npmcli/ci-detect": "^2.0.0", "@npmcli/config": "^4.1.0", "@npmcli/fs": "^2.1.0", - "@npmcli/map-workspaces": "^2.0.2", + "@npmcli/map-workspaces": "^2.0.3", "@npmcli/package-json": "^2.0.0", "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index 6f6342b3192c5..eb47875f91944 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -5,7 +5,7 @@ "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.0", + "@npmcli/map-workspaces": "^2.0.3", "@npmcli/metavuln-calculator": "^3.0.1", "@npmcli/move-file": "^2.0.0", "@npmcli/name-from-folder": "^1.0.1", From 532883ffc35fc1cc9aec09f03bf5ee0f256b94a4 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 14:32:00 -0700 Subject: [PATCH 088/406] deps: cacache@16.0.6 --- node_modules/cacache/lib/verify.js | 4 +- .../cacache/node_modules/glob/LICENSE | 15 + .../cacache/node_modules/glob/common.js | 238 ++++++ .../cacache/node_modules/glob/glob.js | 790 ++++++++++++++++++ .../cacache/node_modules/glob/package.json | 56 ++ .../cacache/node_modules/glob/sync.js | 486 +++++++++++ node_modules/cacache/package.json | 8 +- package-lock.json | 57 +- package.json | 2 +- workspaces/arborist/package.json | 2 +- 10 files changed, 1640 insertions(+), 18 deletions(-) create mode 100644 node_modules/cacache/node_modules/glob/LICENSE create mode 100644 node_modules/cacache/node_modules/glob/common.js create mode 100644 node_modules/cacache/node_modules/glob/glob.js create mode 100644 node_modules/cacache/node_modules/glob/package.json create mode 100644 node_modules/cacache/node_modules/glob/sync.js diff --git a/node_modules/cacache/lib/verify.js b/node_modules/cacache/lib/verify.js index 300cd9f9de1c4..a39fb6ce1d1dc 100644 --- a/node_modules/cacache/lib/verify.js +++ b/node_modules/cacache/lib/verify.js @@ -13,6 +13,8 @@ const path = require('path') const rimraf = util.promisify(require('rimraf')) const ssri = require('ssri') +const globify = pattern => pattern.split('\\').join('/') + const hasOwnProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) @@ -119,7 +121,7 @@ function garbageCollect (cache, opts) { indexStream.on('end', resolve).on('error', reject) }).then(() => { const contentDir = contentPath.contentDir(cache) - return glob(path.join(contentDir, '**'), { + return glob(globify(path.join(contentDir, '**')), { follow: false, nodir: true, nosort: true, diff --git a/node_modules/cacache/node_modules/glob/LICENSE b/node_modules/cacache/node_modules/glob/LICENSE new file mode 100644 index 0000000000000..39e8fe16f665a --- /dev/null +++ b/node_modules/cacache/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors + +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/cacache/node_modules/glob/common.js b/node_modules/cacache/node_modules/glob/common.js new file mode 100644 index 0000000000000..fc193ee6fbda5 --- /dev/null +++ b/node_modules/cacache/node_modules/glob/common.js @@ -0,0 +1,238 @@ +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var fs = require("fs") +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasort (a, b) { + return a.localeCompare(b, 'en') +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute + self.fs = options.fs || fs + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + // always treat \ in patterns as escapes, not path separators + options.allowWindowsEscape = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/node_modules/cacache/node_modules/glob/glob.js b/node_modules/cacache/node_modules/glob/glob.js new file mode 100644 index 0000000000000..37a4d7e60775a --- /dev/null +++ b/node_modules/cacache/node_modules/glob/glob.js @@ -0,0 +1,790 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + + if (!pattern) + return false + + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + this._processing = 0 + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = isAbsolute(e) ? e : this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) + e = abs + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + self.fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + self.fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + self.fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return self.fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) +} diff --git a/node_modules/cacache/node_modules/glob/package.json b/node_modules/cacache/node_modules/glob/package.json new file mode 100644 index 0000000000000..54940cbeb4208 --- /dev/null +++ b/node_modules/cacache/node_modules/glob/package.json @@ -0,0 +1,56 @@ +{ + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "name": "glob", + "description": "a little globber", + "version": "8.0.1", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "main": "glob.js", + "files": [ + "glob.js", + "sync.js", + "common.js" + ], + "engines": { + "node": ">=12" + }, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "devDependencies": { + "memfs": "^3.2.0", + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^16.0.1", + "tick": "0.0.6" + }, + "tap": { + "before": "test/00-setup.js", + "after": "test/zz-cleanup.js", + "statements": 90, + "branches": 90, + "functions": 90, + "lines": 90, + "jobs": 1 + }, + "scripts": { + "prepublish": "npm run benchclean", + "profclean": "rm -f v8.log profile.txt", + "test": "tap", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", + "bench": "bash benchmark.sh", + "prof": "bash prof.sh && cat profile.txt", + "benchclean": "node benchclean.js" + }, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } +} diff --git a/node_modules/cacache/node_modules/glob/sync.js b/node_modules/cacache/node_modules/glob/sync.js new file mode 100644 index 0000000000000..c705a9c0291dd --- /dev/null +++ b/node_modules/cacache/node_modules/glob/sync.js @@ -0,0 +1,486 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return + + var abs = this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) { + e = abs + } + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = this.fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } + } + + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, this.fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = this.fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = this.fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/node_modules/cacache/package.json b/node_modules/cacache/package.json index 3467f8af804ed..9eb646df76b40 100644 --- a/node_modules/cacache/package.json +++ b/node_modules/cacache/package.json @@ -1,6 +1,6 @@ { "name": "cacache", - "version": "16.0.4", + "version": "16.0.6", "cache-version": { "content": "2", "index": "5" @@ -53,7 +53,7 @@ "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", - "glob": "^7.2.0", + "glob": "^8.0.1", "infer-owner": "^1.0.4", "lru-cache": "^7.7.1", "minipass": "^3.1.6", @@ -70,7 +70,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/template-oss": "3.4.1", "benchmark": "^2.1.4", "chalk": "^4.1.2", "require-inject": "^1.4.4", @@ -87,7 +87,7 @@ "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", "windowsCI": false, - "version": "3.2.2" + "version": "3.4.1" }, "author": "GitHub Inc." } diff --git a/package-lock.json b/package-lock.json index 68a127cdb11ad..a52bfe39cdae3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "archy": "~1.0.0", - "cacache": "^16.0.4", + "cacache": "^16.0.6", "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", @@ -1607,16 +1607,16 @@ } }, "node_modules/cacache": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.4.tgz", - "integrity": "sha512-U0D4wF3/W8ZgK4qDA5fTtOVSr0gaDfd5aa7tUdAV0uukVWKsAIn6SzXQCoVlg7RWZiJa+bcsM3/pXLumGaL2Ug==", + "version": "16.0.6", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.6.tgz", + "integrity": "sha512-9a/MLxGaw3LEGes0HaPez2RgZWDV6X0jrgChsuxfEh8xoDoYGxaGrkMe7Dlyjrb655tA/b8fX0qlUg6Ii5MBvw==", "inBundle": true, "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", - "glob": "^7.2.0", + "glob": "^8.0.1", "infer-owner": "^1.0.4", "lru-cache": "^7.7.1", "minipass": "^3.1.6", @@ -1635,6 +1635,26 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/cacache/node_modules/glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "inBundle": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/caching-transform": { "version": "4.0.0", "dev": true, @@ -9804,7 +9824,7 @@ "@npmcli/package-json": "^2.0.0", "@npmcli/run-script": "^3.0.0", "bin-links": "^3.0.0", - "cacache": "^16.0.0", + "cacache": "^16.0.6", "common-ancestor-path": "^1.0.1", "json-parse-even-better-errors": "^2.3.1", "json-stringify-nice": "^1.1.4", @@ -10521,7 +10541,7 @@ "@npmcli/template-oss": "3.4.2", "benchmark": "^2.1.4", "bin-links": "^3.0.0", - "cacache": "^16.0.0", + "cacache": "^16.0.6", "chalk": "^4.1.0", "common-ancestor-path": "^1.0.1", "json-parse-even-better-errors": "^2.3.1", @@ -11056,15 +11076,15 @@ } }, "cacache": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.4.tgz", - "integrity": "sha512-U0D4wF3/W8ZgK4qDA5fTtOVSr0gaDfd5aa7tUdAV0uukVWKsAIn6SzXQCoVlg7RWZiJa+bcsM3/pXLumGaL2Ug==", + "version": "16.0.6", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.6.tgz", + "integrity": "sha512-9a/MLxGaw3LEGes0HaPez2RgZWDV6X0jrgChsuxfEh8xoDoYGxaGrkMe7Dlyjrb655tA/b8fX0qlUg6Ii5MBvw==", "requires": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", - "glob": "^7.2.0", + "glob": "^8.0.1", "infer-owner": "^1.0.4", "lru-cache": "^7.7.1", "minipass": "^3.1.6", @@ -11078,6 +11098,21 @@ "ssri": "^9.0.0", "tar": "^6.1.11", "unique-filename": "^1.1.1" + }, + "dependencies": { + "glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "caching-transform": { diff --git a/package.json b/package.json index 8d96d76569c28..6cedd2b876bbd 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "archy": "~1.0.0", - "cacache": "^16.0.4", + "cacache": "^16.0.6", "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index eb47875f91944..ac2fc0f266304 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -13,7 +13,7 @@ "@npmcli/package-json": "^2.0.0", "@npmcli/run-script": "^3.0.0", "bin-links": "^3.0.0", - "cacache": "^16.0.0", + "cacache": "^16.0.6", "common-ancestor-path": "^1.0.1", "json-parse-even-better-errors": "^2.3.1", "json-stringify-nice": "^1.1.4", From 4d1398e347ed56464d7afd8ef0b3a3bc82b2f19f Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 14:33:09 -0700 Subject: [PATCH 089/406] deps: npm-profile@6.0.3 --- node_modules/npm-profile/package.json | 26 ++++++++++++++------------ package-lock.json | 17 ++++++++++------- package.json | 2 +- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/node_modules/npm-profile/package.json b/node_modules/npm-profile/package.json index 68b04bba6d900..5e8f2d2391abd 100644 --- a/node_modules/npm-profile/package.json +++ b/node_modules/npm-profile/package.json @@ -1,27 +1,28 @@ { "name": "npm-profile", - "version": "6.0.2", + "version": "6.0.3", "description": "Library for updating an npmjs.com profile", "keywords": [], "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "npm-registry-fetch": "^13.0.0", + "npm-registry-fetch": "^13.0.1", "proc-log": "^2.0.0" }, "main": "./lib/index.js", "repository": { "type": "git", - "url": "git+https://github.com/npm/npm-profile.git" + "url": "https://github.com/npm/npm-profile.git" }, "files": [ - "bin", - "lib" + "bin/", + "lib/" ], "devDependencies": { - "@npmcli/template-oss": "^2.7.1", + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "3.4.1", "nock": "^13.2.4", - "tap": "^15.1.6" + "tap": "^16.0.1" }, "scripts": { "preversion": "npm test", @@ -30,18 +31,19 @@ "posttest": "npm run lint", "test": "tap", "snap": "tap", - "lint": "eslint '**/*.js'", - "postlint": "npm-template-check", + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", "lintfix": "npm run lint -- --fix", - "template-copy": "npm-template-copy --force" + "template-oss-apply": "template-oss-apply --force" }, "tap": { "check-coverage": true }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "templateOSS": { - "version": "2.7.1" + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "3.4.1" } } diff --git a/package-lock.json b/package-lock.json index a52bfe39cdae3..65c68cd806372 100644 --- a/package-lock.json +++ b/package-lock.json @@ -133,7 +133,7 @@ "npm-install-checks": "^5.0.0", "npm-package-arg": "^9.0.2", "npm-pick-manifest": "^7.0.1", - "npm-profile": "^6.0.2", + "npm-profile": "^6.0.3", "npm-registry-fetch": "^13.1.1", "npm-user-validate": "^1.0.1", "npmlog": "^6.0.1", @@ -5202,15 +5202,16 @@ } }, "node_modules/npm-profile": { - "version": "6.0.2", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-6.0.3.tgz", + "integrity": "sha512-TVeHhnol2Iemud+Sr70/uqax5LnLJ9y361w+m5+Z7WYV2B1t6FhRDxDu72+yYYTvsgshkhnXEqbPjuD87kYXfA==", "inBundle": true, - "license": "ISC", "dependencies": { - "npm-registry-fetch": "^13.0.0", + "npm-registry-fetch": "^13.0.1", "proc-log": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-registry-fetch": { @@ -13472,9 +13473,11 @@ } }, "npm-profile": { - "version": "6.0.2", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-6.0.3.tgz", + "integrity": "sha512-TVeHhnol2Iemud+Sr70/uqax5LnLJ9y361w+m5+Z7WYV2B1t6FhRDxDu72+yYYTvsgshkhnXEqbPjuD87kYXfA==", "requires": { - "npm-registry-fetch": "^13.0.0", + "npm-registry-fetch": "^13.0.1", "proc-log": "^2.0.0" } }, diff --git a/package.json b/package.json index 6cedd2b876bbd..6ff2768f988e4 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "npm-install-checks": "^5.0.0", "npm-package-arg": "^9.0.2", "npm-pick-manifest": "^7.0.1", - "npm-profile": "^6.0.2", + "npm-profile": "^6.0.3", "npm-registry-fetch": "^13.1.1", "npm-user-validate": "^1.0.1", "npmlog": "^6.0.1", From 5e313223100db1207818d756b081eaba3468b273 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 14:34:08 -0700 Subject: [PATCH 090/406] deps: npmlog@6.0.2 --- node_modules/npmlog/package.json | 24 +++++++++++++----------- package-lock.json | 25 ++++++++++++++----------- package.json | 2 +- workspaces/arborist/package.json | 2 +- workspaces/libnpmexec/package.json | 2 +- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/node_modules/npmlog/package.json b/node_modules/npmlog/package.json index cf38f7fca475c..bdb5a384781ce 100644 --- a/node_modules/npmlog/package.json +++ b/node_modules/npmlog/package.json @@ -2,48 +2,50 @@ "author": "GitHub Inc.", "name": "npmlog", "description": "logger for npm", - "version": "6.0.1", + "version": "6.0.2", "repository": { "type": "git", "url": "https://github.com/npm/npmlog.git" }, "main": "lib/log.js", "files": [ - "bin", - "lib" + "bin/", + "lib/" ], "scripts": { "test": "tap", "npmclilint": "npmcli-lint", - "lint": "eslint '**/*.js'", + "lint": "eslint \"**/*.js\"", "lintfix": "npm run lint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", - "postlint": "npm-template-check", + "postlint": "template-oss-check", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", "snap": "tap", - "template-copy": "npm-template-copy --force" + "template-oss-apply": "template-oss-apply --force" }, "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", + "gauge": "^4.0.3", "set-blocking": "^2.0.0" }, "devDependencies": { - "@npmcli/template-oss": "^2.7.1", - "tap": "^15.1.6" + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "3.4.1", + "tap": "^16.0.1" }, "license": "ISC", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "tap": { "branches": 95 }, "templateOSS": { - "version": "2.7.1" + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "3.4.1" } } diff --git a/package-lock.json b/package-lock.json index 65c68cd806372..039996831bd6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -136,7 +136,7 @@ "npm-profile": "^6.0.3", "npm-registry-fetch": "^13.1.1", "npm-user-validate": "^1.0.1", - "npmlog": "^6.0.1", + "npmlog": "^6.0.2", "opener": "^1.5.2", "pacote": "^13.1.1", "parse-conflict-json": "^2.0.2", @@ -5238,17 +5238,18 @@ "license": "BSD-2-Clause" }, "node_modules/npmlog": { - "version": "6.0.1", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", "inBundle": true, - "license": "ISC", "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", + "gauge": "^4.0.3", "set-blocking": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/null-check": { @@ -9836,7 +9837,7 @@ "npm-package-arg": "^9.0.0", "npm-pick-manifest": "^7.0.0", "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.1", + "npmlog": "^6.0.2", "pacote": "^13.0.5", "parse-conflict-json": "^2.0.1", "proc-log": "^2.0.0", @@ -9918,7 +9919,7 @@ "chalk": "^4.1.0", "mkdirp-infer-owner": "^2.0.0", "npm-package-arg": "^9.0.1", - "npmlog": "^6.0.1", + "npmlog": "^6.0.2", "pacote": "^13.0.5", "proc-log": "^2.0.0", "read": "^1.0.7", @@ -10556,7 +10557,7 @@ "npm-package-arg": "^9.0.0", "npm-pick-manifest": "^7.0.0", "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.1", + "npmlog": "6.0.2", "pacote": "^13.0.5", "parse-conflict-json": "^2.0.1", "proc-log": "^2.0.0", @@ -12936,7 +12937,7 @@ "chalk": "^4.1.0", "mkdirp-infer-owner": "^2.0.0", "npm-package-arg": "^9.0.1", - "npmlog": "^6.0.1", + "npmlog": "6.0.2", "pacote": "^13.0.5", "proc-log": "^2.0.0", "read": "^1.0.7", @@ -13499,11 +13500,13 @@ "version": "1.0.1" }, "npmlog": { - "version": "6.0.1", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", "requires": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", + "gauge": "^4.0.3", "set-blocking": "^2.0.0" } }, diff --git a/package.json b/package.json index 6ff2768f988e4..a7084d369a708 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "npm-profile": "^6.0.3", "npm-registry-fetch": "^13.1.1", "npm-user-validate": "^1.0.1", - "npmlog": "^6.0.1", + "npmlog": "^6.0.2", "opener": "^1.5.2", "pacote": "^13.1.1", "parse-conflict-json": "^2.0.2", diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index ac2fc0f266304..5e78ced3e6da5 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -24,7 +24,7 @@ "npm-package-arg": "^9.0.0", "npm-pick-manifest": "^7.0.0", "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.1", + "npmlog": "^6.0.2", "pacote": "^13.0.5", "parse-conflict-json": "^2.0.1", "proc-log": "^2.0.0", diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index d0294cbe229dd..c108ddaea5117 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -61,7 +61,7 @@ "chalk": "^4.1.0", "mkdirp-infer-owner": "^2.0.0", "npm-package-arg": "^9.0.1", - "npmlog": "^6.0.1", + "npmlog": "^6.0.2", "pacote": "^13.0.5", "proc-log": "^2.0.0", "read": "^1.0.7", From 4eb2ccbacbd2ca55f2a41a104ee20578542fc52f Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 14:35:19 -0700 Subject: [PATCH 091/406] deps: read-package-json@5.0.1 --- .../read-package-json/lib/read-json.js | 46 +- .../node_modules/glob/LICENSE | 15 + .../node_modules/glob/common.js | 238 ++++++ .../node_modules/glob/glob.js | 790 ++++++++++++++++++ .../node_modules/glob/package.json | 56 ++ .../node_modules/glob/sync.js | 486 +++++++++++ node_modules/read-package-json/package.json | 26 +- package-lock.json | 56 +- package.json | 2 +- 9 files changed, 1670 insertions(+), 45 deletions(-) create mode 100644 node_modules/read-package-json/node_modules/glob/LICENSE create mode 100644 node_modules/read-package-json/node_modules/glob/common.js create mode 100644 node_modules/read-package-json/node_modules/glob/glob.js create mode 100644 node_modules/read-package-json/node_modules/glob/package.json create mode 100644 node_modules/read-package-json/node_modules/glob/sync.js diff --git a/node_modules/read-package-json/lib/read-json.js b/node_modules/read-package-json/lib/read-json.js index d0ee9af1ae750..c55eca32259ed 100644 --- a/node_modules/read-package-json/lib/read-json.js +++ b/node_modules/read-package-json/lib/read-json.js @@ -109,10 +109,10 @@ function parseJson (file, er, d, log, strict, cb) { delete data[key] } } - } catch (er) { + } catch (jsonErr) { data = parseIndex(d) if (!data) { - return cb(parseError(er, file)) + return cb(parseError(jsonErr, file)) } } @@ -120,11 +120,11 @@ function parseJson (file, er, d, log, strict, cb) { } function extrasCached (file, d, data, log, strict, cb) { - extras(file, data, log, strict, function (err, data) { + extras(file, data, log, strict, function (err, extrasData) { if (!err) { - cache[d] = jsonClone(data) + cache[d] = jsonClone(extrasData) } - cb(err, data) + cb(err, extrasData) }) } @@ -299,8 +299,8 @@ function readme (file, data, cb) { return cb(er) } // don't accept directories. - files = files.filter(function (file) { - return !file.match(/\/$/) + files = files.filter(function (filtered) { + return !filtered.match(/\/$/) }) if (!files.length) { return cb() @@ -328,12 +328,12 @@ function preferMarkdownReadme (files) { function readme_ (file, data, rm, cb) { var rmfn = path.basename(rm) - fs.readFile(rm, 'utf8', function (er, rm) { + fs.readFile(rm, 'utf8', function (er, rmData) { // maybe not readable, or something. if (er) { return cb() } - data.readme = rm + data.readme = rmData data.readmeFilename = rmfn return cb(er, data) }) @@ -346,11 +346,11 @@ function mans (file, data, cb) { } const dirname = path.dirname(file) cwd = path.resolve(path.dirname(file), cwd) - glob('**/*.[0-9]', { cwd }, function (er, mans) { + glob('**/*.[0-9]', { cwd }, function (er, mansGlob) { if (er) { return cb(er) } - data.man = mans.map(man => + data.man = mansGlob.map(man => path.relative(dirname, path.join(cwd, man)).split(path.sep).join('/') ) return cb(null, data) @@ -366,17 +366,17 @@ function bins (file, data, cb) { } m = path.resolve(path.dirname(file), m) - glob('**', { cwd: m }, function (er, bins) { + glob('**', { cwd: m }, function (er, binsGlob) { if (er) { return cb(er) } - bins_(file, data, bins, cb) + bins_(file, data, binsGlob, cb) }) } -function bins_ (file, data, bins, cb) { +function bins_ (file, data, binsGlob, cb) { var m = (data.directories && data.directories.bin) || '.' - data.bin = bins.reduce(function (acc, mf) { + data.bin = binsGlob.reduce(function (acc, mf) { if (mf && mf.charAt(0) !== '.') { var f = path.basename(mf) acc[f] = path.join(m, mf) @@ -412,7 +412,7 @@ function githead (file, data, cb) { } var dir = path.dirname(file) var head = path.resolve(dir, '.git/HEAD') - fs.readFile(head, 'utf8', function (er, head) { + fs.readFile(head, 'utf8', function (er, headData) { if (er) { var parent = path.dirname(dir) if (parent === dir) { @@ -420,7 +420,7 @@ function githead (file, data, cb) { } return githead(dir, data, cb) } - githead_(data, dir, head, cb) + githead_(data, dir, headData, cb) }) } @@ -431,11 +431,11 @@ function githead_ (data, dir, head, cb) { } var headRef = head.replace(/^ref: /, '').trim() var headFile = path.resolve(dir, '.git', headRef) - fs.readFile(headFile, 'utf8', function (er, head) { - if (er || !head) { + fs.readFile(headFile, 'utf8', function (er, headData) { + if (er || !headData) { var packFile = path.resolve(dir, '.git/packed-refs') - return fs.readFile(packFile, 'utf8', function (er, refs) { - if (er || !refs) { + return fs.readFile(packFile, 'utf8', function (readFileErr, refs) { + if (readFileErr || !refs) { return cb(null, data) } refs = refs.split('\n') @@ -449,8 +449,8 @@ function githead_ (data, dir, head, cb) { return cb(null, data) }) } - head = head.replace(/^ref: /, '').trim() - data.gitHead = head + headData = headData.replace(/^ref: /, '').trim() + data.gitHead = headData return cb(null, data) }) } diff --git a/node_modules/read-package-json/node_modules/glob/LICENSE b/node_modules/read-package-json/node_modules/glob/LICENSE new file mode 100644 index 0000000000000..39e8fe16f665a --- /dev/null +++ b/node_modules/read-package-json/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors + +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/read-package-json/node_modules/glob/common.js b/node_modules/read-package-json/node_modules/glob/common.js new file mode 100644 index 0000000000000..fc193ee6fbda5 --- /dev/null +++ b/node_modules/read-package-json/node_modules/glob/common.js @@ -0,0 +1,238 @@ +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var fs = require("fs") +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasort (a, b) { + return a.localeCompare(b, 'en') +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute + self.fs = options.fs || fs + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + // always treat \ in patterns as escapes, not path separators + options.allowWindowsEscape = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/node_modules/read-package-json/node_modules/glob/glob.js b/node_modules/read-package-json/node_modules/glob/glob.js new file mode 100644 index 0000000000000..37a4d7e60775a --- /dev/null +++ b/node_modules/read-package-json/node_modules/glob/glob.js @@ -0,0 +1,790 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + + if (!pattern) + return false + + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + this._processing = 0 + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = isAbsolute(e) ? e : this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) + e = abs + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + self.fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + self.fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + self.fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return self.fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) +} diff --git a/node_modules/read-package-json/node_modules/glob/package.json b/node_modules/read-package-json/node_modules/glob/package.json new file mode 100644 index 0000000000000..54940cbeb4208 --- /dev/null +++ b/node_modules/read-package-json/node_modules/glob/package.json @@ -0,0 +1,56 @@ +{ + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "name": "glob", + "description": "a little globber", + "version": "8.0.1", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "main": "glob.js", + "files": [ + "glob.js", + "sync.js", + "common.js" + ], + "engines": { + "node": ">=12" + }, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "devDependencies": { + "memfs": "^3.2.0", + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^16.0.1", + "tick": "0.0.6" + }, + "tap": { + "before": "test/00-setup.js", + "after": "test/zz-cleanup.js", + "statements": 90, + "branches": 90, + "functions": 90, + "lines": 90, + "jobs": 1 + }, + "scripts": { + "prepublish": "npm run benchclean", + "profclean": "rm -f v8.log profile.txt", + "test": "tap", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", + "bench": "bash benchmark.sh", + "prof": "bash prof.sh && cat profile.txt", + "benchclean": "node benchclean.js" + }, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } +} diff --git a/node_modules/read-package-json/node_modules/glob/sync.js b/node_modules/read-package-json/node_modules/glob/sync.js new file mode 100644 index 0000000000000..c705a9c0291dd --- /dev/null +++ b/node_modules/read-package-json/node_modules/glob/sync.js @@ -0,0 +1,486 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return + + var abs = this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) { + e = abs + } + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = this.fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } + } + + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, this.fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = this.fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = this.fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/node_modules/read-package-json/package.json b/node_modules/read-package-json/package.json index 038047c970941..8bb77ca01f653 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": "5.0.0", + "version": "5.0.1", "author": "GitHub Inc.", "description": "The thing npm uses to read package.json files with semantics and defaults and validation", "repository": { @@ -14,34 +14,35 @@ "release": "standard-version -s", "test": "tap", "npmclilint": "npmcli-lint", - "lint": "eslint '**/*.js'", + "lint": "eslint \"**/*.js\"", "lintfix": "npm run lint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", - "postlint": "npm-template-check", - "template-copy": "npm-template-copy --force", + "postlint": "template-oss-check", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", - "snap": "tap" + "snap": "tap", + "template-oss-apply": "template-oss-apply --force" }, "dependencies": { - "glob": "^7.2.0", + "glob": "^8.0.1", "json-parse-even-better-errors": "^2.3.1", "normalize-package-data": "^4.0.0", "npm-normalize-package-bin": "^1.0.1" }, "devDependencies": { - "@npmcli/template-oss": "^2.9.2", - "tap": "^15.0.9" + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "3.4.1", + "tap": "^16.0.1" }, "license": "ISC", "files": [ - "bin", - "lib" + "bin/", + "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "tap": { "branches": 68, @@ -50,6 +51,7 @@ "statements": 77 }, "templateOSS": { - "version": "2.9.2" + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "3.4.1" } } diff --git a/package-lock.json b/package-lock.json index 039996831bd6e..b9ddb736e722c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -143,7 +143,7 @@ "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", "read": "~1.0.7", - "read-package-json": "^5.0.0", + "read-package-json": "^5.0.1", "read-package-json-fast": "^2.0.3", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", @@ -6010,17 +6010,18 @@ } }, "node_modules/read-package-json": { - "version": "5.0.0", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.1.tgz", + "integrity": "sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg==", "inBundle": true, - "license": "ISC", "dependencies": { - "glob": "^7.2.0", + "glob": "^8.0.1", "json-parse-even-better-errors": "^2.3.1", "normalize-package-data": "^4.0.0", "npm-normalize-package-bin": "^1.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/read-package-json-fast": { @@ -6035,6 +6036,26 @@ "node": ">=10" } }, + "node_modules/read-package-json/node_modules/glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "inBundle": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/read-package-tree": { "version": "5.3.1", "dev": true, @@ -10557,7 +10578,7 @@ "npm-package-arg": "^9.0.0", "npm-pick-manifest": "^7.0.0", "npm-registry-fetch": "^13.0.0", - "npmlog": "6.0.2", + "npmlog": "^6.0.2", "pacote": "^13.0.5", "parse-conflict-json": "^2.0.1", "proc-log": "^2.0.0", @@ -12937,7 +12958,7 @@ "chalk": "^4.1.0", "mkdirp-infer-owner": "^2.0.0", "npm-package-arg": "^9.0.1", - "npmlog": "6.0.2", + "npmlog": "^6.0.2", "pacote": "^13.0.5", "proc-log": "^2.0.0", "read": "^1.0.7", @@ -14008,12 +14029,29 @@ "integrity": "sha512-KQDVjGqhZk92PPNRj9ZEXEuqg8bUobSKRw+q0YQ3TKI5xkce7bUJobL4Z/OtiEbAAv70yEpYIXp4iQ9L8oPVog==" }, "read-package-json": { - "version": "5.0.0", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.1.tgz", + "integrity": "sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg==", "requires": { - "glob": "^7.2.0", + "glob": "^8.0.1", "json-parse-even-better-errors": "^2.3.1", "normalize-package-data": "^4.0.0", "npm-normalize-package-bin": "^1.0.1" + }, + "dependencies": { + "glob": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "read-package-json-fast": { diff --git a/package.json b/package.json index a7084d369a708..219848f6bab6d 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", "read": "~1.0.7", - "read-package-json": "^5.0.0", + "read-package-json": "^5.0.1", "read-package-json-fast": "^2.0.3", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", From aeb54e41b613f4a98d1f02d255b3a564c43270d8 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 14:39:14 -0700 Subject: [PATCH 092/406] deps: glob@8.0.1 --- node_modules/glob/LICENSE | 8 +- node_modules/glob/common.js | 2 + node_modules/glob/glob.js | 5 +- node_modules/glob/package.json | 12 +- node_modules/glob/sync.js | 5 +- .../node_modules/brace-expansion/LICENSE | 0 .../node_modules/brace-expansion/index.js | 0 .../node_modules/brace-expansion/package.json | 0 .../node_modules/glob/LICENSE | 8 +- .../node_modules/glob/common.js | 2 - .../node_modules/glob/glob.js | 5 +- .../node_modules/glob/package.json | 12 +- .../node_modules/glob/sync.js | 5 +- .../node_modules/minimatch/LICENSE | 0 .../node_modules/minimatch/minimatch.js | 0 .../node_modules/minimatch/package.json | 0 .../node_modules/brace-expansion/LICENSE | 21 + .../node_modules/brace-expansion/index.js | 201 ++++ .../node_modules/brace-expansion/package.json | 47 + .../npm-packlist/node_modules/glob/LICENSE | 21 + .../node_modules/glob/common.js | 2 - .../node_modules/glob/glob.js | 5 +- .../node_modules/glob/package.json | 12 +- .../node_modules/glob/sync.js | 5 +- .../node_modules/minimatch}/LICENSE | 2 +- .../node_modules/minimatch/minimatch.js | 947 ++++++++++++++++++ .../node_modules/minimatch/package.json | 33 + .../node_modules/brace-expansion/LICENSE | 21 + .../node_modules/brace-expansion/index.js | 201 ++++ .../node_modules/brace-expansion/package.json | 47 + node_modules/rimraf/node_modules/glob/LICENSE | 21 + .../node_modules/glob/common.js | 2 - .../node_modules/glob/glob.js | 5 +- .../node_modules/glob/package.json | 12 +- .../node_modules/glob/sync.js | 5 +- .../node_modules/minimatch}/LICENSE | 2 +- .../node_modules/minimatch/minimatch.js | 947 ++++++++++++++++++ .../node_modules/minimatch/package.json | 33 + package-lock.json | 678 +++++++++---- package.json | 2 +- 40 files changed, 3095 insertions(+), 241 deletions(-) rename node_modules/{glob => node-gyp}/node_modules/brace-expansion/LICENSE (100%) rename node_modules/{glob => node-gyp}/node_modules/brace-expansion/index.js (100%) rename node_modules/{glob => node-gyp}/node_modules/brace-expansion/package.json (100%) rename node_modules/{read-package-json => node-gyp}/node_modules/glob/LICENSE (73%) rename node_modules/{read-package-json => node-gyp}/node_modules/glob/common.js (98%) rename node_modules/{read-package-json => node-gyp}/node_modules/glob/glob.js (99%) rename node_modules/{cacache => node-gyp}/node_modules/glob/package.json (86%) rename node_modules/{@npmcli/map-workspaces => node-gyp}/node_modules/glob/sync.js (98%) rename node_modules/{glob => node-gyp}/node_modules/minimatch/LICENSE (100%) rename node_modules/{glob => node-gyp}/node_modules/minimatch/minimatch.js (100%) rename node_modules/{glob => node-gyp}/node_modules/minimatch/package.json (100%) create mode 100644 node_modules/npm-packlist/node_modules/brace-expansion/LICENSE create mode 100644 node_modules/npm-packlist/node_modules/brace-expansion/index.js create mode 100644 node_modules/npm-packlist/node_modules/brace-expansion/package.json create mode 100644 node_modules/npm-packlist/node_modules/glob/LICENSE rename node_modules/{@npmcli/map-workspaces => npm-packlist}/node_modules/glob/common.js (98%) rename node_modules/{cacache => npm-packlist}/node_modules/glob/glob.js (99%) rename node_modules/{read-package-json => npm-packlist}/node_modules/glob/package.json (86%) rename node_modules/{read-package-json => npm-packlist}/node_modules/glob/sync.js (98%) rename node_modules/{@npmcli/map-workspaces/node_modules/glob => npm-packlist/node_modules/minimatch}/LICENSE (92%) create mode 100644 node_modules/npm-packlist/node_modules/minimatch/minimatch.js create mode 100644 node_modules/npm-packlist/node_modules/minimatch/package.json create mode 100644 node_modules/rimraf/node_modules/brace-expansion/LICENSE create mode 100644 node_modules/rimraf/node_modules/brace-expansion/index.js create mode 100644 node_modules/rimraf/node_modules/brace-expansion/package.json create mode 100644 node_modules/rimraf/node_modules/glob/LICENSE rename node_modules/{cacache => rimraf}/node_modules/glob/common.js (98%) rename node_modules/{@npmcli/map-workspaces => rimraf}/node_modules/glob/glob.js (99%) rename node_modules/{@npmcli/map-workspaces => rimraf}/node_modules/glob/package.json (86%) rename node_modules/{cacache => rimraf}/node_modules/glob/sync.js (98%) rename node_modules/{cacache/node_modules/glob => rimraf/node_modules/minimatch}/LICENSE (92%) create mode 100644 node_modules/rimraf/node_modules/minimatch/minimatch.js create mode 100644 node_modules/rimraf/node_modules/minimatch/package.json diff --git a/node_modules/glob/LICENSE b/node_modules/glob/LICENSE index 42ca266df1d52..39e8fe16f665a 100644 --- a/node_modules/glob/LICENSE +++ b/node_modules/glob/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) Isaac Z. Schlueter and Contributors +Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -13,9 +13,3 @@ 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. - -## Glob Logo - -Glob's logo created by Tanya Brassie , licensed -under a Creative Commons Attribution-ShareAlike 4.0 International License -https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/glob/common.js b/node_modules/glob/common.js index 8e363b6c1f16a..fc193ee6fbda5 100644 --- a/node_modules/glob/common.js +++ b/node_modules/glob/common.js @@ -110,6 +110,8 @@ function setopts (self, pattern, options) { // Note that they are not supported in Glob itself anyway. options.nonegate = true options.nocomment = true + // always treat \ in patterns as escapes, not path separators + options.allowWindowsEscape = true self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options diff --git a/node_modules/glob/glob.js b/node_modules/glob/glob.js index afcf82752c390..37a4d7e60775a 100644 --- a/node_modules/glob/glob.js +++ b/node_modules/glob/glob.js @@ -342,7 +342,10 @@ Glob.prototype._process = function (pattern, index, inGlobStar, cb) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/glob/package.json b/node_modules/glob/package.json index cc1a57a896e9e..54940cbeb4208 100644 --- a/node_modules/glob/package.json +++ b/node_modules/glob/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "7.2.0", + "version": "8.0.1", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" @@ -14,13 +14,13 @@ "common.js" ], "engines": { - "node": "*" + "node": ">=12" }, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^5.0.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -28,12 +28,16 @@ "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^15.0.6", + "tap": "^16.0.1", "tick": "0.0.6" }, "tap": { "before": "test/00-setup.js", "after": "test/zz-cleanup.js", + "statements": 90, + "branches": 90, + "functions": 90, + "lines": 90, "jobs": 1 }, "scripts": { diff --git a/node_modules/glob/sync.js b/node_modules/glob/sync.js index 4f46f90559a0c..c705a9c0291dd 100644 --- a/node_modules/glob/sync.js +++ b/node_modules/glob/sync.js @@ -109,7 +109,10 @@ GlobSync.prototype._process = function (pattern, index, inGlobStar) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/glob/node_modules/brace-expansion/LICENSE b/node_modules/node-gyp/node_modules/brace-expansion/LICENSE similarity index 100% rename from node_modules/glob/node_modules/brace-expansion/LICENSE rename to node_modules/node-gyp/node_modules/brace-expansion/LICENSE diff --git a/node_modules/glob/node_modules/brace-expansion/index.js b/node_modules/node-gyp/node_modules/brace-expansion/index.js similarity index 100% rename from node_modules/glob/node_modules/brace-expansion/index.js rename to node_modules/node-gyp/node_modules/brace-expansion/index.js diff --git a/node_modules/glob/node_modules/brace-expansion/package.json b/node_modules/node-gyp/node_modules/brace-expansion/package.json similarity index 100% rename from node_modules/glob/node_modules/brace-expansion/package.json rename to node_modules/node-gyp/node_modules/brace-expansion/package.json diff --git a/node_modules/read-package-json/node_modules/glob/LICENSE b/node_modules/node-gyp/node_modules/glob/LICENSE similarity index 73% rename from node_modules/read-package-json/node_modules/glob/LICENSE rename to node_modules/node-gyp/node_modules/glob/LICENSE index 39e8fe16f665a..42ca266df1d52 100644 --- a/node_modules/read-package-json/node_modules/glob/LICENSE +++ b/node_modules/node-gyp/node_modules/glob/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors +Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -13,3 +13,9 @@ 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. + +## Glob Logo + +Glob's logo created by Tanya Brassie , licensed +under a Creative Commons Attribution-ShareAlike 4.0 International License +https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/read-package-json/node_modules/glob/common.js b/node_modules/node-gyp/node_modules/glob/common.js similarity index 98% rename from node_modules/read-package-json/node_modules/glob/common.js rename to node_modules/node-gyp/node_modules/glob/common.js index fc193ee6fbda5..8e363b6c1f16a 100644 --- a/node_modules/read-package-json/node_modules/glob/common.js +++ b/node_modules/node-gyp/node_modules/glob/common.js @@ -110,8 +110,6 @@ function setopts (self, pattern, options) { // Note that they are not supported in Glob itself anyway. options.nonegate = true options.nocomment = true - // always treat \ in patterns as escapes, not path separators - options.allowWindowsEscape = true self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options diff --git a/node_modules/read-package-json/node_modules/glob/glob.js b/node_modules/node-gyp/node_modules/glob/glob.js similarity index 99% rename from node_modules/read-package-json/node_modules/glob/glob.js rename to node_modules/node-gyp/node_modules/glob/glob.js index 37a4d7e60775a..afcf82752c390 100644 --- a/node_modules/read-package-json/node_modules/glob/glob.js +++ b/node_modules/node-gyp/node_modules/glob/glob.js @@ -342,10 +342,7 @@ Glob.prototype._process = function (pattern, index, inGlobStar, cb) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/cacache/node_modules/glob/package.json b/node_modules/node-gyp/node_modules/glob/package.json similarity index 86% rename from node_modules/cacache/node_modules/glob/package.json rename to node_modules/node-gyp/node_modules/glob/package.json index 54940cbeb4208..cc1a57a896e9e 100644 --- a/node_modules/cacache/node_modules/glob/package.json +++ b/node_modules/node-gyp/node_modules/glob/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.0.1", + "version": "7.2.0", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" @@ -14,13 +14,13 @@ "common.js" ], "engines": { - "node": ">=12" + "node": "*" }, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^5.0.1", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -28,16 +28,12 @@ "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^16.0.1", + "tap": "^15.0.6", "tick": "0.0.6" }, "tap": { "before": "test/00-setup.js", "after": "test/zz-cleanup.js", - "statements": 90, - "branches": 90, - "functions": 90, - "lines": 90, "jobs": 1 }, "scripts": { diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/sync.js b/node_modules/node-gyp/node_modules/glob/sync.js similarity index 98% rename from node_modules/@npmcli/map-workspaces/node_modules/glob/sync.js rename to node_modules/node-gyp/node_modules/glob/sync.js index c705a9c0291dd..4f46f90559a0c 100644 --- a/node_modules/@npmcli/map-workspaces/node_modules/glob/sync.js +++ b/node_modules/node-gyp/node_modules/glob/sync.js @@ -109,10 +109,7 @@ GlobSync.prototype._process = function (pattern, index, inGlobStar) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/glob/node_modules/minimatch/LICENSE b/node_modules/node-gyp/node_modules/minimatch/LICENSE similarity index 100% rename from node_modules/glob/node_modules/minimatch/LICENSE rename to node_modules/node-gyp/node_modules/minimatch/LICENSE diff --git a/node_modules/glob/node_modules/minimatch/minimatch.js b/node_modules/node-gyp/node_modules/minimatch/minimatch.js similarity index 100% rename from node_modules/glob/node_modules/minimatch/minimatch.js rename to node_modules/node-gyp/node_modules/minimatch/minimatch.js diff --git a/node_modules/glob/node_modules/minimatch/package.json b/node_modules/node-gyp/node_modules/minimatch/package.json similarity index 100% rename from node_modules/glob/node_modules/minimatch/package.json rename to node_modules/node-gyp/node_modules/minimatch/package.json diff --git a/node_modules/npm-packlist/node_modules/brace-expansion/LICENSE b/node_modules/npm-packlist/node_modules/brace-expansion/LICENSE new file mode 100644 index 0000000000000..de3226673c387 --- /dev/null +++ b/node_modules/npm-packlist/node_modules/brace-expansion/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 Julian Gruber + +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/npm-packlist/node_modules/brace-expansion/index.js b/node_modules/npm-packlist/node_modules/brace-expansion/index.js new file mode 100644 index 0000000000000..0478be81eabc2 --- /dev/null +++ b/node_modules/npm-packlist/node_modules/brace-expansion/index.js @@ -0,0 +1,201 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/node_modules/npm-packlist/node_modules/brace-expansion/package.json b/node_modules/npm-packlist/node_modules/brace-expansion/package.json new file mode 100644 index 0000000000000..a18faa8fd67b8 --- /dev/null +++ b/node_modules/npm-packlist/node_modules/brace-expansion/package.json @@ -0,0 +1,47 @@ +{ + "name": "brace-expansion", + "description": "Brace expansion as known from sh/bash", + "version": "1.1.11", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "homepage": "https://github.com/juliangruber/brace-expansion", + "main": "index.js", + "scripts": { + "test": "tape test/*.js", + "gentest": "bash test/generate.sh", + "bench": "matcha test/perf/bench.js" + }, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "keywords": [], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..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" + ] + } +} diff --git a/node_modules/npm-packlist/node_modules/glob/LICENSE b/node_modules/npm-packlist/node_modules/glob/LICENSE new file mode 100644 index 0000000000000..42ca266df1d52 --- /dev/null +++ b/node_modules/npm-packlist/node_modules/glob/LICENSE @@ -0,0 +1,21 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +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. + +## Glob Logo + +Glob's logo created by Tanya Brassie , licensed +under a Creative Commons Attribution-ShareAlike 4.0 International License +https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/common.js b/node_modules/npm-packlist/node_modules/glob/common.js similarity index 98% rename from node_modules/@npmcli/map-workspaces/node_modules/glob/common.js rename to node_modules/npm-packlist/node_modules/glob/common.js index fc193ee6fbda5..8e363b6c1f16a 100644 --- a/node_modules/@npmcli/map-workspaces/node_modules/glob/common.js +++ b/node_modules/npm-packlist/node_modules/glob/common.js @@ -110,8 +110,6 @@ function setopts (self, pattern, options) { // Note that they are not supported in Glob itself anyway. options.nonegate = true options.nocomment = true - // always treat \ in patterns as escapes, not path separators - options.allowWindowsEscape = true self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options diff --git a/node_modules/cacache/node_modules/glob/glob.js b/node_modules/npm-packlist/node_modules/glob/glob.js similarity index 99% rename from node_modules/cacache/node_modules/glob/glob.js rename to node_modules/npm-packlist/node_modules/glob/glob.js index 37a4d7e60775a..afcf82752c390 100644 --- a/node_modules/cacache/node_modules/glob/glob.js +++ b/node_modules/npm-packlist/node_modules/glob/glob.js @@ -342,10 +342,7 @@ Glob.prototype._process = function (pattern, index, inGlobStar, cb) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/read-package-json/node_modules/glob/package.json b/node_modules/npm-packlist/node_modules/glob/package.json similarity index 86% rename from node_modules/read-package-json/node_modules/glob/package.json rename to node_modules/npm-packlist/node_modules/glob/package.json index 54940cbeb4208..cc1a57a896e9e 100644 --- a/node_modules/read-package-json/node_modules/glob/package.json +++ b/node_modules/npm-packlist/node_modules/glob/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.0.1", + "version": "7.2.0", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" @@ -14,13 +14,13 @@ "common.js" ], "engines": { - "node": ">=12" + "node": "*" }, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^5.0.1", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -28,16 +28,12 @@ "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^16.0.1", + "tap": "^15.0.6", "tick": "0.0.6" }, "tap": { "before": "test/00-setup.js", "after": "test/zz-cleanup.js", - "statements": 90, - "branches": 90, - "functions": 90, - "lines": 90, "jobs": 1 }, "scripts": { diff --git a/node_modules/read-package-json/node_modules/glob/sync.js b/node_modules/npm-packlist/node_modules/glob/sync.js similarity index 98% rename from node_modules/read-package-json/node_modules/glob/sync.js rename to node_modules/npm-packlist/node_modules/glob/sync.js index c705a9c0291dd..4f46f90559a0c 100644 --- a/node_modules/read-package-json/node_modules/glob/sync.js +++ b/node_modules/npm-packlist/node_modules/glob/sync.js @@ -109,10 +109,7 @@ GlobSync.prototype._process = function (pattern, index, inGlobStar) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/LICENSE b/node_modules/npm-packlist/node_modules/minimatch/LICENSE similarity index 92% rename from node_modules/@npmcli/map-workspaces/node_modules/glob/LICENSE rename to node_modules/npm-packlist/node_modules/minimatch/LICENSE index 39e8fe16f665a..19129e315fe59 100644 --- a/node_modules/@npmcli/map-workspaces/node_modules/glob/LICENSE +++ b/node_modules/npm-packlist/node_modules/minimatch/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors +Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/node_modules/npm-packlist/node_modules/minimatch/minimatch.js b/node_modules/npm-packlist/node_modules/minimatch/minimatch.js new file mode 100644 index 0000000000000..fda45ade7cfc3 --- /dev/null +++ b/node_modules/npm-packlist/node_modules/minimatch/minimatch.js @@ -0,0 +1,947 @@ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = (function () { try { return require('path') } catch (e) {}}()) || { + sep: '/' +} +minimatch.sep = path.sep + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + b = b || {} + var t = {} + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || typeof def !== 'object' || !Object.keys(def).length) { + return minimatch + } + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + m.Minimatch.defaults = function defaults (options) { + return orig.defaults(ext(def, options)).Minimatch + } + + m.filter = function filter (pattern, options) { + return orig.filter(pattern, ext(def, options)) + } + + m.defaults = function defaults (options) { + return orig.defaults(ext(def, options)) + } + + m.makeRe = function makeRe (pattern, options) { + return orig.makeRe(pattern, ext(def, options)) + } + + m.braceExpand = function braceExpand (pattern, options) { + return orig.braceExpand(pattern, ext(def, options)) + } + + m.match = function (list, pattern, options) { + return orig.match(list, pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + assertValidPattern(pattern) + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + assertValidPattern(pattern) + + if (!options) options = {} + + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (!options.allowWindowsEscape && path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + this.partial = !!options.partial + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + assertValidPattern(pattern) + + // Thanks to Yeting Li for + // improving this regexp to avoid a ReDOS vulnerability. + if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +var MAX_PATTERN_LENGTH = 1024 * 64 +var assertValidPattern = function (pattern) { + if (typeof pattern !== 'string') { + throw new TypeError('invalid pattern') + } + + if (pattern.length > MAX_PATTERN_LENGTH) { + throw new TypeError('pattern is too long') + } +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + assertValidPattern(pattern) + + var options = this.options + + // shortcuts + if (pattern === '**') { + if (!options.noglobstar) + return GLOBSTAR + else + pattern = '*' + } + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + /* istanbul ignore next */ + case '/': { + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + } + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '[': case '.': case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) /* istanbul ignore next - should be impossible */ { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) /* istanbul ignore next - should be impossible */ { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = function match (f, partial) { + if (typeof partial === 'undefined') partial = this.partial + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + /* istanbul ignore if */ + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + /* istanbul ignore if */ + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + hit = f === p + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else /* istanbul ignore else */ if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + return (fi === fl - 1) && (file[fi] === '') + } + + // should be unreachable. + /* istanbul ignore next */ + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} diff --git a/node_modules/npm-packlist/node_modules/minimatch/package.json b/node_modules/npm-packlist/node_modules/minimatch/package.json new file mode 100644 index 0000000000000..566efdfe45cb8 --- /dev/null +++ b/node_modules/npm-packlist/node_modules/minimatch/package.json @@ -0,0 +1,33 @@ +{ + "author": "Isaac Z. Schlueter (http://blog.izs.me)", + "name": "minimatch", + "description": "a glob matcher in javascript", + "version": "3.1.2", + "publishConfig": { + "tag": "v3-legacy" + }, + "repository": { + "type": "git", + "url": "git://github.com/isaacs/minimatch.git" + }, + "main": "minimatch.js", + "scripts": { + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --all; git push origin --tags" + }, + "engines": { + "node": "*" + }, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "devDependencies": { + "tap": "^15.1.6" + }, + "license": "ISC", + "files": [ + "minimatch.js" + ] +} diff --git a/node_modules/rimraf/node_modules/brace-expansion/LICENSE b/node_modules/rimraf/node_modules/brace-expansion/LICENSE new file mode 100644 index 0000000000000..de3226673c387 --- /dev/null +++ b/node_modules/rimraf/node_modules/brace-expansion/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 Julian Gruber + +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/rimraf/node_modules/brace-expansion/index.js b/node_modules/rimraf/node_modules/brace-expansion/index.js new file mode 100644 index 0000000000000..0478be81eabc2 --- /dev/null +++ b/node_modules/rimraf/node_modules/brace-expansion/index.js @@ -0,0 +1,201 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/node_modules/rimraf/node_modules/brace-expansion/package.json b/node_modules/rimraf/node_modules/brace-expansion/package.json new file mode 100644 index 0000000000000..a18faa8fd67b8 --- /dev/null +++ b/node_modules/rimraf/node_modules/brace-expansion/package.json @@ -0,0 +1,47 @@ +{ + "name": "brace-expansion", + "description": "Brace expansion as known from sh/bash", + "version": "1.1.11", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "homepage": "https://github.com/juliangruber/brace-expansion", + "main": "index.js", + "scripts": { + "test": "tape test/*.js", + "gentest": "bash test/generate.sh", + "bench": "matcha test/perf/bench.js" + }, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "keywords": [], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..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" + ] + } +} diff --git a/node_modules/rimraf/node_modules/glob/LICENSE b/node_modules/rimraf/node_modules/glob/LICENSE new file mode 100644 index 0000000000000..42ca266df1d52 --- /dev/null +++ b/node_modules/rimraf/node_modules/glob/LICENSE @@ -0,0 +1,21 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +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. + +## Glob Logo + +Glob's logo created by Tanya Brassie , licensed +under a Creative Commons Attribution-ShareAlike 4.0 International License +https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/cacache/node_modules/glob/common.js b/node_modules/rimraf/node_modules/glob/common.js similarity index 98% rename from node_modules/cacache/node_modules/glob/common.js rename to node_modules/rimraf/node_modules/glob/common.js index fc193ee6fbda5..8e363b6c1f16a 100644 --- a/node_modules/cacache/node_modules/glob/common.js +++ b/node_modules/rimraf/node_modules/glob/common.js @@ -110,8 +110,6 @@ function setopts (self, pattern, options) { // Note that they are not supported in Glob itself anyway. options.nonegate = true options.nocomment = true - // always treat \ in patterns as escapes, not path separators - options.allowWindowsEscape = true self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/glob.js b/node_modules/rimraf/node_modules/glob/glob.js similarity index 99% rename from node_modules/@npmcli/map-workspaces/node_modules/glob/glob.js rename to node_modules/rimraf/node_modules/glob/glob.js index 37a4d7e60775a..afcf82752c390 100644 --- a/node_modules/@npmcli/map-workspaces/node_modules/glob/glob.js +++ b/node_modules/rimraf/node_modules/glob/glob.js @@ -342,10 +342,7 @@ Glob.prototype._process = function (pattern, index, inGlobStar, cb) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/@npmcli/map-workspaces/node_modules/glob/package.json b/node_modules/rimraf/node_modules/glob/package.json similarity index 86% rename from node_modules/@npmcli/map-workspaces/node_modules/glob/package.json rename to node_modules/rimraf/node_modules/glob/package.json index 54940cbeb4208..cc1a57a896e9e 100644 --- a/node_modules/@npmcli/map-workspaces/node_modules/glob/package.json +++ b/node_modules/rimraf/node_modules/glob/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.0.1", + "version": "7.2.0", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" @@ -14,13 +14,13 @@ "common.js" ], "engines": { - "node": ">=12" + "node": "*" }, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^5.0.1", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -28,16 +28,12 @@ "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^16.0.1", + "tap": "^15.0.6", "tick": "0.0.6" }, "tap": { "before": "test/00-setup.js", "after": "test/zz-cleanup.js", - "statements": 90, - "branches": 90, - "functions": 90, - "lines": 90, "jobs": 1 }, "scripts": { diff --git a/node_modules/cacache/node_modules/glob/sync.js b/node_modules/rimraf/node_modules/glob/sync.js similarity index 98% rename from node_modules/cacache/node_modules/glob/sync.js rename to node_modules/rimraf/node_modules/glob/sync.js index c705a9c0291dd..4f46f90559a0c 100644 --- a/node_modules/cacache/node_modules/glob/sync.js +++ b/node_modules/rimraf/node_modules/glob/sync.js @@ -109,10 +109,7 @@ GlobSync.prototype._process = function (pattern, index, inGlobStar) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/node_modules/cacache/node_modules/glob/LICENSE b/node_modules/rimraf/node_modules/minimatch/LICENSE similarity index 92% rename from node_modules/cacache/node_modules/glob/LICENSE rename to node_modules/rimraf/node_modules/minimatch/LICENSE index 39e8fe16f665a..19129e315fe59 100644 --- a/node_modules/cacache/node_modules/glob/LICENSE +++ b/node_modules/rimraf/node_modules/minimatch/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors +Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/node_modules/rimraf/node_modules/minimatch/minimatch.js b/node_modules/rimraf/node_modules/minimatch/minimatch.js new file mode 100644 index 0000000000000..fda45ade7cfc3 --- /dev/null +++ b/node_modules/rimraf/node_modules/minimatch/minimatch.js @@ -0,0 +1,947 @@ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = (function () { try { return require('path') } catch (e) {}}()) || { + sep: '/' +} +minimatch.sep = path.sep + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + b = b || {} + var t = {} + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || typeof def !== 'object' || !Object.keys(def).length) { + return minimatch + } + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + m.Minimatch.defaults = function defaults (options) { + return orig.defaults(ext(def, options)).Minimatch + } + + m.filter = function filter (pattern, options) { + return orig.filter(pattern, ext(def, options)) + } + + m.defaults = function defaults (options) { + return orig.defaults(ext(def, options)) + } + + m.makeRe = function makeRe (pattern, options) { + return orig.makeRe(pattern, ext(def, options)) + } + + m.braceExpand = function braceExpand (pattern, options) { + return orig.braceExpand(pattern, ext(def, options)) + } + + m.match = function (list, pattern, options) { + return orig.match(list, pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + assertValidPattern(pattern) + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + assertValidPattern(pattern) + + if (!options) options = {} + + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (!options.allowWindowsEscape && path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + this.partial = !!options.partial + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + assertValidPattern(pattern) + + // Thanks to Yeting Li for + // improving this regexp to avoid a ReDOS vulnerability. + if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +var MAX_PATTERN_LENGTH = 1024 * 64 +var assertValidPattern = function (pattern) { + if (typeof pattern !== 'string') { + throw new TypeError('invalid pattern') + } + + if (pattern.length > MAX_PATTERN_LENGTH) { + throw new TypeError('pattern is too long') + } +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + assertValidPattern(pattern) + + var options = this.options + + // shortcuts + if (pattern === '**') { + if (!options.noglobstar) + return GLOBSTAR + else + pattern = '*' + } + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + /* istanbul ignore next */ + case '/': { + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + } + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '[': case '.': case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) /* istanbul ignore next - should be impossible */ { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) /* istanbul ignore next - should be impossible */ { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = function match (f, partial) { + if (typeof partial === 'undefined') partial = this.partial + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + /* istanbul ignore if */ + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + /* istanbul ignore if */ + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + hit = f === p + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else /* istanbul ignore else */ if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + return (fi === fl - 1) && (file[fi] === '') + } + + // should be unreachable. + /* istanbul ignore next */ + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} diff --git a/node_modules/rimraf/node_modules/minimatch/package.json b/node_modules/rimraf/node_modules/minimatch/package.json new file mode 100644 index 0000000000000..566efdfe45cb8 --- /dev/null +++ b/node_modules/rimraf/node_modules/minimatch/package.json @@ -0,0 +1,33 @@ +{ + "author": "Isaac Z. Schlueter (http://blog.izs.me)", + "name": "minimatch", + "description": "a glob matcher in javascript", + "version": "3.1.2", + "publishConfig": { + "tag": "v3-legacy" + }, + "repository": { + "type": "git", + "url": "git://github.com/isaacs/minimatch.git" + }, + "main": "minimatch.js", + "scripts": { + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --all; git push origin --tags" + }, + "engines": { + "node": "*" + }, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "devDependencies": { + "tap": "^15.1.6" + }, + "license": "ISC", + "files": [ + "minimatch.js" + ] +} diff --git a/package-lock.json b/package-lock.json index b9ddb736e722c..f14d1e2655671 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,7 +103,7 @@ "cli-table3": "^0.6.1", "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.12", - "glob": "^7.2.0", + "glob": "^8.0.1", "graceful-fs": "^4.2.10", "hosted-git-info": "^5.0.0", "ini": "^3.0.0", @@ -966,26 +966,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@npmcli/map-workspaces/node_modules/glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", - "inBundle": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@npmcli/metavuln-calculator": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.0.tgz", @@ -1635,26 +1615,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/cacache/node_modules/glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", - "inBundle": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/caching-transform": { "version": "4.0.0", "dev": true, @@ -3282,19 +3242,20 @@ "license": "MIT" }, "node_modules/glob": { - "version": "7.2.0", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", "inBundle": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^5.0.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3311,28 +3272,6 @@ "node": ">= 6" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "inBundle": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "inBundle": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/globals": { "version": "11.12.0", "dev": true, @@ -5056,6 +4995,48 @@ "node": "^12.22 || ^14.13 || >=16" } }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "inBundle": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "inBundle": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "inBundle": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/node-modules-regexp": { "version": "1.0.0", "dev": true, @@ -5186,6 +5167,48 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/npm-packlist/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "inBundle": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm-packlist/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "inBundle": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-packlist/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "inBundle": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/npm-pick-manifest": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz", @@ -5313,6 +5336,16 @@ "node": ">=8.9" } }, + "node_modules/nyc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/nyc/node_modules/find-up": { "version": "4.1.0", "dev": true, @@ -5325,6 +5358,26 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/nyc/node_modules/locate-path": { "version": "5.0.0", "dev": true, @@ -5336,6 +5389,18 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/nyc/node_modules/p-limit": { "version": "2.3.0", "dev": true, @@ -6036,41 +6101,63 @@ "node": ">=10" } }, - "node_modules/read-package-json/node_modules/glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", - "inBundle": true, + "node_modules/read-package-tree": { + "version": "5.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "node_modules/read-package-tree/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/read-package-tree/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^5.0.1", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=12" + "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/read-package-tree": { - "version": "5.3.1", - "dev": true, - "license": "ISC", - "dependencies": { - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "util-promisify": "^2.1.0" - } - }, "node_modules/read-package-tree/node_modules/hosted-git-info": { "version": "2.8.9", "dev": true, "license": "ISC" }, + "node_modules/read-package-tree/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/read-package-tree/node_modules/normalize-package-data": { "version": "2.5.0", "dev": true, @@ -6369,29 +6456,71 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "inBundle": true, "dependencies": { - "queue-microtask": "^1.2.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/safe-buffer": { + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "inBundle": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "inBundle": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { "version": "5.2.1", "funding": [ { @@ -6940,6 +7069,16 @@ "node": ">= 8" } }, + "node_modules/tap-mocha-reporter/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/tap-mocha-reporter/node_modules/diff": { "version": "4.0.2", "dev": true, @@ -6956,6 +7095,38 @@ "node": ">=8" } }, + "node_modules/tap-mocha-reporter/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tap-mocha-reporter/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/tap-parser": { "version": "11.0.1", "dev": true, @@ -8935,6 +9106,26 @@ "concat-map": "0.0.1" } }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/test-exclude/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -10671,21 +10862,6 @@ "glob": "^8.0.1", "minimatch": "^5.0.1", "read-package-json-fast": "^2.0.3" - }, - "dependencies": { - "glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "@npmcli/metavuln-calculator": { @@ -11121,21 +11297,6 @@ "ssri": "^9.0.0", "tar": "^6.1.11", "unique-filename": "^1.1.1" - }, - "dependencies": { - "glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "caching-transform": { @@ -12191,33 +12352,16 @@ "dev": true }, "glob": { - "version": "7.2.0", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", + "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^5.0.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "glob-parent": { @@ -13401,6 +13545,38 @@ "semver": "^7.3.5", "tar": "^6.1.2", "which": "^2.0.2" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "node-modules-regexp": { @@ -13481,6 +13657,38 @@ "ignore-walk": "^5.0.1", "npm-bundled": "^1.1.2", "npm-normalize-package-bin": "^1.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "npm-pick-manifest": { @@ -13576,6 +13784,16 @@ "yargs": "^15.0.2" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "find-up": { "version": "4.1.0", "dev": true, @@ -13584,6 +13802,20 @@ "path-exists": "^4.0.0" } }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "locate-path": { "version": "5.0.0", "dev": true, @@ -13591,6 +13823,15 @@ "p-locate": "^4.1.0" } }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "p-limit": { "version": "2.3.0", "dev": true, @@ -14037,21 +14278,6 @@ "json-parse-even-better-errors": "^2.3.1", "normalize-package-data": "^4.0.0", "npm-normalize-package-bin": "^1.0.1" - }, - "dependencies": { - "glob": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.1.tgz", - "integrity": "sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "read-package-json-fast": { @@ -14070,10 +14296,43 @@ "util-promisify": "^2.1.0" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "hosted-git-info": { "version": "2.8.9", "dev": true }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "normalize-package-data": { "version": "2.5.0", "dev": true, @@ -14282,6 +14541,38 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "run-parallel": { @@ -15851,6 +16142,16 @@ "unicode-length": "^2.0.2" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "diff": { "version": "4.0.2", "dev": true @@ -15858,6 +16159,29 @@ "escape-string-regexp": { "version": "2.0.0", "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } } } }, @@ -15947,6 +16271,20 @@ "concat-map": "0.0.1" } }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index 219848f6bab6d..832e54efd83bf 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "cli-table3": "^0.6.1", "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.12", - "glob": "^7.2.0", + "glob": "^8.0.1", "graceful-fs": "^4.2.10", "hosted-git-info": "^5.0.0", "ini": "^3.0.0", From 252b2b1e8caaf1c26e5ab6836a83ec430d2a699a Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 15:01:59 -0700 Subject: [PATCH 093/406] deps: npm-packlist@5.0.2 --- node_modules/npm-packlist/lib/index.js | 3 +- .../node_modules/brace-expansion/LICENSE | 21 - .../node_modules/brace-expansion/index.js | 201 ---- .../node_modules/brace-expansion/package.json | 47 - .../npm-packlist/node_modules/glob/LICENSE | 21 - .../npm-packlist/node_modules/glob/common.js | 236 ----- .../npm-packlist/node_modules/glob/glob.js | 787 --------------- .../node_modules/glob/package.json | 52 - .../npm-packlist/node_modules/glob/sync.js | 483 --------- .../node_modules/minimatch/LICENSE | 15 - .../node_modules/minimatch/minimatch.js | 947 ------------------ .../node_modules/minimatch/package.json | 33 - node_modules/npm-packlist/package.json | 8 +- package-lock.json | 90 +- 14 files changed, 14 insertions(+), 2930 deletions(-) delete mode 100644 node_modules/npm-packlist/node_modules/brace-expansion/LICENSE delete mode 100644 node_modules/npm-packlist/node_modules/brace-expansion/index.js delete mode 100644 node_modules/npm-packlist/node_modules/brace-expansion/package.json delete mode 100644 node_modules/npm-packlist/node_modules/glob/LICENSE delete mode 100644 node_modules/npm-packlist/node_modules/glob/common.js delete mode 100644 node_modules/npm-packlist/node_modules/glob/glob.js delete mode 100644 node_modules/npm-packlist/node_modules/glob/package.json delete mode 100644 node_modules/npm-packlist/node_modules/glob/sync.js delete mode 100644 node_modules/npm-packlist/node_modules/minimatch/LICENSE delete mode 100644 node_modules/npm-packlist/node_modules/minimatch/minimatch.js delete mode 100644 node_modules/npm-packlist/node_modules/minimatch/package.json diff --git a/node_modules/npm-packlist/lib/index.js b/node_modules/npm-packlist/lib/index.js index 30d99dc873f26..7e4093dfb3929 100644 --- a/node_modules/npm-packlist/lib/index.js +++ b/node_modules/npm-packlist/lib/index.js @@ -31,6 +31,7 @@ const packageMustHavesRE = new RegExp(`^(${packageMustHaveFileNames})(\\..*[^~$] const fs = require('fs') const glob = require('glob') +const globify = pattern => pattern.split('\\').join('/') const pathHasPkg = (input) => { if (!input.startsWith('node_modules/')) { @@ -428,7 +429,7 @@ class Walker extends IgnoreWalker { } globFiles (pattern, cb) { - glob(pattern, { dot: true, cwd: this.path, nocase: true }, cb) + glob(globify(pattern), { dot: true, cwd: this.path, nocase: true }, cb) } readPackageJson (entries) { diff --git a/node_modules/npm-packlist/node_modules/brace-expansion/LICENSE b/node_modules/npm-packlist/node_modules/brace-expansion/LICENSE deleted file mode 100644 index de3226673c387..0000000000000 --- a/node_modules/npm-packlist/node_modules/brace-expansion/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 Julian Gruber - -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/npm-packlist/node_modules/brace-expansion/index.js b/node_modules/npm-packlist/node_modules/brace-expansion/index.js deleted file mode 100644 index 0478be81eabc2..0000000000000 --- a/node_modules/npm-packlist/node_modules/brace-expansion/index.js +++ /dev/null @@ -1,201 +0,0 @@ -var concatMap = require('concat-map'); -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - diff --git a/node_modules/npm-packlist/node_modules/brace-expansion/package.json b/node_modules/npm-packlist/node_modules/brace-expansion/package.json deleted file mode 100644 index a18faa8fd67b8..0000000000000 --- a/node_modules/npm-packlist/node_modules/brace-expansion/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "brace-expansion", - "description": "Brace expansion as known from sh/bash", - "version": "1.1.11", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/brace-expansion.git" - }, - "homepage": "https://github.com/juliangruber/brace-expansion", - "main": "index.js", - "scripts": { - "test": "tape test/*.js", - "gentest": "bash test/generate.sh", - "bench": "matcha test/perf/bench.js" - }, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "devDependencies": { - "matcha": "^0.7.0", - "tape": "^4.6.0" - }, - "keywords": [], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..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" - ] - } -} diff --git a/node_modules/npm-packlist/node_modules/glob/LICENSE b/node_modules/npm-packlist/node_modules/glob/LICENSE deleted file mode 100644 index 42ca266df1d52..0000000000000 --- a/node_modules/npm-packlist/node_modules/glob/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -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. - -## Glob Logo - -Glob's logo created by Tanya Brassie , licensed -under a Creative Commons Attribution-ShareAlike 4.0 International License -https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/npm-packlist/node_modules/glob/common.js b/node_modules/npm-packlist/node_modules/glob/common.js deleted file mode 100644 index 8e363b6c1f16a..0000000000000 --- a/node_modules/npm-packlist/node_modules/glob/common.js +++ /dev/null @@ -1,236 +0,0 @@ -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var fs = require("fs") -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path-is-absolute") -var Minimatch = minimatch.Minimatch - -function alphasort (a, b) { - return a.localeCompare(b, 'en') -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - self.fs = options.fs || fs - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - self.nomount = !!options.nomount - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} diff --git a/node_modules/npm-packlist/node_modules/glob/glob.js b/node_modules/npm-packlist/node_modules/glob/glob.js deleted file mode 100644 index afcf82752c390..0000000000000 --- a/node_modules/npm-packlist/node_modules/glob/glob.js +++ /dev/null @@ -1,787 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var inherits = require('inherits') -var EE = require('events').EventEmitter -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var globSync = require('./sync.js') -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = require('inflight') -var util = require('util') -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -var once = require('once') - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync - -// old api surface -glob.glob = glob - -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } - - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] - } - return origin -} - -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true - - var g = new Glob(pattern, options) - var set = g.minimatch.set - - if (!pattern) - return false - - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - this._processing = 0 - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false - - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) - e = abs - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - self.fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - self.fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - self.fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return self.fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -} diff --git a/node_modules/npm-packlist/node_modules/glob/package.json b/node_modules/npm-packlist/node_modules/glob/package.json deleted file mode 100644 index cc1a57a896e9e..0000000000000 --- a/node_modules/npm-packlist/node_modules/glob/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "name": "glob", - "description": "a little globber", - "version": "7.2.0", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-glob.git" - }, - "main": "glob.js", - "files": [ - "glob.js", - "sync.js", - "common.js" - ], - "engines": { - "node": "*" - }, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "devDependencies": { - "memfs": "^3.2.0", - "mkdirp": "0", - "rimraf": "^2.2.8", - "tap": "^15.0.6", - "tick": "0.0.6" - }, - "tap": { - "before": "test/00-setup.js", - "after": "test/zz-cleanup.js", - "jobs": 1 - }, - "scripts": { - "prepublish": "npm run benchclean", - "profclean": "rm -f v8.log profile.txt", - "test": "tap", - "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", - "bench": "bash benchmark.sh", - "prof": "bash prof.sh && cat profile.txt", - "benchclean": "node benchclean.js" - }, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } -} diff --git a/node_modules/npm-packlist/node_modules/glob/sync.js b/node_modules/npm-packlist/node_modules/glob/sync.js deleted file mode 100644 index 4f46f90559a0c..0000000000000 --- a/node_modules/npm-packlist/node_modules/glob/sync.js +++ /dev/null @@ -1,483 +0,0 @@ -module.exports = globSync -globSync.GlobSync = GlobSync - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return - - var abs = this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) { - e = abs - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, this.fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = this.fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} diff --git a/node_modules/npm-packlist/node_modules/minimatch/LICENSE b/node_modules/npm-packlist/node_modules/minimatch/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/npm-packlist/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -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/npm-packlist/node_modules/minimatch/minimatch.js b/node_modules/npm-packlist/node_modules/minimatch/minimatch.js deleted file mode 100644 index fda45ade7cfc3..0000000000000 --- a/node_modules/npm-packlist/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,947 +0,0 @@ -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = (function () { try { return require('path') } catch (e) {}}()) || { - sep: '/' -} -minimatch.sep = path.sep - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = require('brace-expansion') - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - b = b || {} - var t = {} - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return minimatch - } - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - m.Minimatch.defaults = function defaults (options) { - return orig.defaults(ext(def, options)).Minimatch - } - - m.filter = function filter (pattern, options) { - return orig.filter(pattern, ext(def, options)) - } - - m.defaults = function defaults (options) { - return orig.defaults(ext(def, options)) - } - - m.makeRe = function makeRe (pattern, options) { - return orig.makeRe(pattern, ext(def, options)) - } - - m.braceExpand = function braceExpand (pattern, options) { - return orig.braceExpand(pattern, ext(def, options)) - } - - m.match = function (list, pattern, options) { - return orig.match(list, pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - return minimatch.defaults(def).Minimatch -} - -function minimatch (p, pattern, options) { - assertValidPattern(pattern) - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } - - assertValidPattern(pattern) - - if (!options) options = {} - - pattern = pattern.trim() - - // windows support: need to use /, not \ - if (!options.allowWindowsEscape && path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - this.partial = !!options.partial - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} - -Minimatch.prototype.make = make -function make () { - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} - -Minimatch.prototype.braceExpand = braceExpand - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - assertValidPattern(pattern) - - // Thanks to Yeting Li for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -var MAX_PATTERN_LENGTH = 1024 * 64 -var assertValidPattern = function (pattern) { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern') - } - - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long') - } -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - assertValidPattern(pattern) - - var options = this.options - - // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return GLOBSTAR - else - pattern = '*' - } - if (pattern === '') return '' - - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - /* istanbul ignore next */ - case '/': { - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - } - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '[': case '.': case '(': addPatternStart = true - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) /* istanbul ignore next - should be impossible */ { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) /* istanbul ignore next - should be impossible */ { - this.regexp = false - } - return this.regexp -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = function match (f, partial) { - if (typeof partial === 'undefined') partial = this.partial - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - /* istanbul ignore if */ - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - /* istanbul ignore if */ - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - hit = f === p - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else /* istanbul ignore else */ if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - return (fi === fl - 1) && (file[fi] === '') - } - - // should be unreachable. - /* istanbul ignore next */ - throw new Error('wtf?') -} - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} diff --git a/node_modules/npm-packlist/node_modules/minimatch/package.json b/node_modules/npm-packlist/node_modules/minimatch/package.json deleted file mode 100644 index 566efdfe45cb8..0000000000000 --- a/node_modules/npm-packlist/node_modules/minimatch/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "author": "Isaac Z. Schlueter (http://blog.izs.me)", - "name": "minimatch", - "description": "a glob matcher in javascript", - "version": "3.1.2", - "publishConfig": { - "tag": "v3-legacy" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "main": "minimatch.js", - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "engines": { - "node": "*" - }, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "devDependencies": { - "tap": "^15.1.6" - }, - "license": "ISC", - "files": [ - "minimatch.js" - ] -} diff --git a/node_modules/npm-packlist/package.json b/node_modules/npm-packlist/package.json index 632524d789ca8..ab5e46359d09b 100644 --- a/node_modules/npm-packlist/package.json +++ b/node_modules/npm-packlist/package.json @@ -1,13 +1,13 @@ { "name": "npm-packlist", - "version": "5.0.0", + "version": "5.0.2", "description": "Get a list of the files to add from a folder into an npm package", "directories": { "test": "test" }, "main": "lib", "dependencies": { - "glob": "^7.2.0", + "glob": "^8.0.1", "ignore-walk": "^5.0.1", "npm-bundled": "^1.1.2", "npm-normalize-package-bin": "^1.0.1" @@ -20,7 +20,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/template-oss": "3.4.1", "mutate-fs": "^2.1.1", "tap": "^16.0.1" }, @@ -56,6 +56,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "3.4.1" } } diff --git a/package-lock.json b/package-lock.json index f14d1e2655671..a5f2e30433b3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5150,12 +5150,12 @@ } }, "node_modules/npm-packlist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.0.0.tgz", - "integrity": "sha512-uU20UwM4Hogfab1Q7htJbhcyafM9lGHxOrDjkKvR2S3z7Ds0uRaESk0cXctczk+ABT4DZWNwjB10xlurFdEwZg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.0.2.tgz", + "integrity": "sha512-jLhcNisUgpz6v2KC75qSeEYAM8UBMYjQ2OhlCOJjB4Ovu7XXnD25UqZ6hOQNeGShL/2ju3LL2E/zBbsuzkIQ8w==", "inBundle": true, "dependencies": { - "glob": "^7.2.0", + "glob": "^8.0.1", "ignore-walk": "^5.0.1", "npm-bundled": "^1.1.2", "npm-normalize-package-bin": "^1.0.1" @@ -5167,48 +5167,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/npm-packlist/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "inBundle": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npm-packlist/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "inBundle": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm-packlist/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "inBundle": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/npm-pick-manifest": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz", @@ -13649,46 +13607,14 @@ } }, "npm-packlist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.0.0.tgz", - "integrity": "sha512-uU20UwM4Hogfab1Q7htJbhcyafM9lGHxOrDjkKvR2S3z7Ds0uRaESk0cXctczk+ABT4DZWNwjB10xlurFdEwZg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.0.2.tgz", + "integrity": "sha512-jLhcNisUgpz6v2KC75qSeEYAM8UBMYjQ2OhlCOJjB4Ovu7XXnD25UqZ6hOQNeGShL/2ju3LL2E/zBbsuzkIQ8w==", "requires": { - "glob": "^7.2.0", + "glob": "^8.0.1", "ignore-walk": "^5.0.1", "npm-bundled": "^1.1.2", "npm-normalize-package-bin": "^1.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "npm-pick-manifest": { From c51e553a32315e4f1b703ca9030eb7ade91d1a85 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 15:05:34 -0700 Subject: [PATCH 094/406] deps: semver@7.3.7 --- node_modules/semver/bin/semver.js | 3 +- node_modules/semver/classes/semver.js | 2 +- node_modules/semver/functions/inc.js | 5 +- .../semver/node_modules/lru-cache/LICENSE | 15 + .../semver/node_modules/lru-cache/index.js | 334 ++++++++++++++++++ .../node_modules/lru-cache/package.json | 34 ++ node_modules/semver/package.json | 11 +- package-lock.json | 54 ++- package.json | 2 +- workspaces/arborist/package.json | 2 +- workspaces/libnpmpublish/package.json | 2 +- workspaces/libnpmversion/package.json | 2 +- 12 files changed, 438 insertions(+), 28 deletions(-) create mode 100644 node_modules/semver/node_modules/lru-cache/LICENSE create mode 100644 node_modules/semver/node_modules/lru-cache/index.js create mode 100644 node_modules/semver/node_modules/lru-cache/package.json diff --git a/node_modules/semver/bin/semver.js b/node_modules/semver/bin/semver.js index 779b8b0cdc2aa..8d1b55720e0ab 100755 --- a/node_modules/semver/bin/semver.js +++ b/node_modules/semver/bin/semver.js @@ -37,8 +37,9 @@ const main = () => { let a = argv.shift() const indexOfEqualSign = a.indexOf('=') if (indexOfEqualSign !== -1) { + const value = a.slice(indexOfEqualSign + 1) a = a.slice(0, indexOfEqualSign) - argv.unshift(a.slice(indexOfEqualSign + 1)) + argv.unshift(value) } switch (a) { case '-rv': case '-rev': case '--rev': case '--reverse': diff --git a/node_modules/semver/classes/semver.js b/node_modules/semver/classes/semver.js index ed81a7ec6cbfe..af62955194793 100644 --- a/node_modules/semver/classes/semver.js +++ b/node_modules/semver/classes/semver.js @@ -265,7 +265,7 @@ class SemVer { if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { + if (compareIdentifiers(this.prerelease[0], identifier) === 0) { if (isNaN(this.prerelease[1])) { this.prerelease = [identifier, 0] } diff --git a/node_modules/semver/functions/inc.js b/node_modules/semver/functions/inc.js index aa4d83ab4c289..62d1da2c4093b 100644 --- a/node_modules/semver/functions/inc.js +++ b/node_modules/semver/functions/inc.js @@ -7,7 +7,10 @@ const inc = (version, release, options, identifier) => { } try { - return new SemVer(version, options).inc(release, identifier).version + return new SemVer( + version instanceof SemVer ? version.version : version, + options + ).inc(release, identifier).version } catch (er) { return null } diff --git a/node_modules/semver/node_modules/lru-cache/LICENSE b/node_modules/semver/node_modules/lru-cache/LICENSE new file mode 100644 index 0000000000000..19129e315fe59 --- /dev/null +++ b/node_modules/semver/node_modules/lru-cache/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +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/semver/node_modules/lru-cache/index.js b/node_modules/semver/node_modules/lru-cache/index.js new file mode 100644 index 0000000000000..573b6b85b9779 --- /dev/null +++ b/node_modules/semver/node_modules/lru-cache/index.js @@ -0,0 +1,334 @@ +'use strict' + +// A linked list to keep track of recently-used-ness +const Yallist = require('yallist') + +const MAX = Symbol('max') +const LENGTH = Symbol('length') +const LENGTH_CALCULATOR = Symbol('lengthCalculator') +const ALLOW_STALE = Symbol('allowStale') +const MAX_AGE = Symbol('maxAge') +const DISPOSE = Symbol('dispose') +const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet') +const LRU_LIST = Symbol('lruList') +const CACHE = Symbol('cache') +const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet') + +const naiveLength = () => 1 + +// lruList is a yallist where the head is the youngest +// item, and the tail is the oldest. the list contains the Hit +// objects as the entries. +// Each Hit object has a reference to its Yallist.Node. This +// never changes. +// +// cache is a Map (or PseudoMap) that matches the keys to +// the Yallist.Node object. +class LRUCache { + constructor (options) { + if (typeof options === 'number') + options = { max: options } + + if (!options) + options = {} + + if (options.max && (typeof options.max !== 'number' || options.max < 0)) + throw new TypeError('max must be a non-negative number') + // Kind of weird to have a default max of Infinity, but oh well. + const max = this[MAX] = options.max || Infinity + + const lc = options.length || naiveLength + this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc + this[ALLOW_STALE] = options.stale || false + if (options.maxAge && typeof options.maxAge !== 'number') + throw new TypeError('maxAge must be a number') + this[MAX_AGE] = options.maxAge || 0 + this[DISPOSE] = options.dispose + this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false + this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false + this.reset() + } + + // resize the cache when the max changes. + set max (mL) { + if (typeof mL !== 'number' || mL < 0) + throw new TypeError('max must be a non-negative number') + + this[MAX] = mL || Infinity + trim(this) + } + get max () { + return this[MAX] + } + + set allowStale (allowStale) { + this[ALLOW_STALE] = !!allowStale + } + get allowStale () { + return this[ALLOW_STALE] + } + + set maxAge (mA) { + if (typeof mA !== 'number') + throw new TypeError('maxAge must be a non-negative number') + + this[MAX_AGE] = mA + trim(this) + } + get maxAge () { + return this[MAX_AGE] + } + + // resize the cache when the lengthCalculator changes. + set lengthCalculator (lC) { + if (typeof lC !== 'function') + lC = naiveLength + + if (lC !== this[LENGTH_CALCULATOR]) { + this[LENGTH_CALCULATOR] = lC + this[LENGTH] = 0 + this[LRU_LIST].forEach(hit => { + hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) + this[LENGTH] += hit.length + }) + } + trim(this) + } + get lengthCalculator () { return this[LENGTH_CALCULATOR] } + + get length () { return this[LENGTH] } + get itemCount () { return this[LRU_LIST].length } + + rforEach (fn, thisp) { + thisp = thisp || this + for (let walker = this[LRU_LIST].tail; walker !== null;) { + const prev = walker.prev + forEachStep(this, fn, walker, thisp) + walker = prev + } + } + + forEach (fn, thisp) { + thisp = thisp || this + for (let walker = this[LRU_LIST].head; walker !== null;) { + const next = walker.next + forEachStep(this, fn, walker, thisp) + walker = next + } + } + + keys () { + return this[LRU_LIST].toArray().map(k => k.key) + } + + values () { + return this[LRU_LIST].toArray().map(k => k.value) + } + + reset () { + if (this[DISPOSE] && + this[LRU_LIST] && + this[LRU_LIST].length) { + this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)) + } + + this[CACHE] = new Map() // hash of items by key + this[LRU_LIST] = new Yallist() // list of items in order of use recency + this[LENGTH] = 0 // length of items in the list + } + + dump () { + return this[LRU_LIST].map(hit => + isStale(this, hit) ? false : { + k: hit.key, + v: hit.value, + e: hit.now + (hit.maxAge || 0) + }).toArray().filter(h => h) + } + + dumpLru () { + return this[LRU_LIST] + } + + set (key, value, maxAge) { + maxAge = maxAge || this[MAX_AGE] + + if (maxAge && typeof maxAge !== 'number') + throw new TypeError('maxAge must be a number') + + const now = maxAge ? Date.now() : 0 + const len = this[LENGTH_CALCULATOR](value, key) + + if (this[CACHE].has(key)) { + if (len > this[MAX]) { + del(this, this[CACHE].get(key)) + return false + } + + const node = this[CACHE].get(key) + const item = node.value + + // dispose of the old one before overwriting + // split out into 2 ifs for better coverage tracking + if (this[DISPOSE]) { + if (!this[NO_DISPOSE_ON_SET]) + this[DISPOSE](key, item.value) + } + + item.now = now + item.maxAge = maxAge + item.value = value + this[LENGTH] += len - item.length + item.length = len + this.get(key) + trim(this) + return true + } + + const hit = new Entry(key, value, len, now, maxAge) + + // oversized objects fall out of cache automatically. + if (hit.length > this[MAX]) { + if (this[DISPOSE]) + this[DISPOSE](key, value) + + return false + } + + this[LENGTH] += hit.length + this[LRU_LIST].unshift(hit) + this[CACHE].set(key, this[LRU_LIST].head) + trim(this) + return true + } + + has (key) { + if (!this[CACHE].has(key)) return false + const hit = this[CACHE].get(key).value + return !isStale(this, hit) + } + + get (key) { + return get(this, key, true) + } + + peek (key) { + return get(this, key, false) + } + + pop () { + const node = this[LRU_LIST].tail + if (!node) + return null + + del(this, node) + return node.value + } + + del (key) { + del(this, this[CACHE].get(key)) + } + + load (arr) { + // reset the cache + this.reset() + + const now = Date.now() + // A previous serialized cache has the most recent items first + for (let l = arr.length - 1; l >= 0; l--) { + const hit = arr[l] + const expiresAt = hit.e || 0 + if (expiresAt === 0) + // the item was created without expiration in a non aged cache + this.set(hit.k, hit.v) + else { + const maxAge = expiresAt - now + // dont add already expired items + if (maxAge > 0) { + this.set(hit.k, hit.v, maxAge) + } + } + } + } + + prune () { + this[CACHE].forEach((value, key) => get(this, key, false)) + } +} + +const get = (self, key, doUse) => { + const node = self[CACHE].get(key) + if (node) { + const hit = node.value + if (isStale(self, hit)) { + del(self, node) + if (!self[ALLOW_STALE]) + return undefined + } else { + if (doUse) { + if (self[UPDATE_AGE_ON_GET]) + node.value.now = Date.now() + self[LRU_LIST].unshiftNode(node) + } + } + return hit.value + } +} + +const isStale = (self, hit) => { + if (!hit || (!hit.maxAge && !self[MAX_AGE])) + return false + + const diff = Date.now() - hit.now + return hit.maxAge ? diff > hit.maxAge + : self[MAX_AGE] && (diff > self[MAX_AGE]) +} + +const trim = self => { + if (self[LENGTH] > self[MAX]) { + for (let walker = self[LRU_LIST].tail; + self[LENGTH] > self[MAX] && walker !== null;) { + // We know that we're about to delete this one, and also + // what the next least recently used key will be, so just + // go ahead and set it now. + const prev = walker.prev + del(self, walker) + walker = prev + } + } +} + +const del = (self, node) => { + if (node) { + const hit = node.value + if (self[DISPOSE]) + self[DISPOSE](hit.key, hit.value) + + self[LENGTH] -= hit.length + self[CACHE].delete(hit.key) + self[LRU_LIST].removeNode(node) + } +} + +class Entry { + constructor (key, value, length, now, maxAge) { + this.key = key + this.value = value + this.length = length + this.now = now + this.maxAge = maxAge || 0 + } +} + +const forEachStep = (self, fn, node, thisp) => { + let hit = node.value + if (isStale(self, hit)) { + del(self, node) + if (!self[ALLOW_STALE]) + hit = undefined + } + if (hit) + fn.call(thisp, hit.value, hit.key, self) +} + +module.exports = LRUCache diff --git a/node_modules/semver/node_modules/lru-cache/package.json b/node_modules/semver/node_modules/lru-cache/package.json new file mode 100644 index 0000000000000..43b7502c3e7c7 --- /dev/null +++ b/node_modules/semver/node_modules/lru-cache/package.json @@ -0,0 +1,34 @@ +{ + "name": "lru-cache", + "description": "A cache object that deletes the least-recently-used items.", + "version": "6.0.0", + "author": "Isaac Z. Schlueter ", + "keywords": [ + "mru", + "lru", + "cache" + ], + "scripts": { + "test": "tap", + "snap": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags" + }, + "main": "index.js", + "repository": "git://github.com/isaacs/node-lru-cache.git", + "devDependencies": { + "benchmark": "^2.1.4", + "tap": "^14.10.7" + }, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "files": [ + "index.js" + ], + "engines": { + "node": ">=10" + } +} diff --git a/node_modules/semver/package.json b/node_modules/semver/package.json index b04e0d328268f..7898f5902cb73 100644 --- a/node_modules/semver/package.json +++ b/node_modules/semver/package.json @@ -1,6 +1,6 @@ { "name": "semver", - "version": "7.3.6", + "version": "7.3.7", "description": "The semantic version parser used by npm.", "main": "index.js", "scripts": { @@ -18,7 +18,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/template-oss": "3.3.2", "tap": "^16.0.0" }, "license": "ISC", @@ -44,15 +44,16 @@ "coverage-map": "map.js" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=10" }, "dependencies": { - "lru-cache": "^7.4.0" + "lru-cache": "^6.0.0" }, "author": "GitHub Inc.", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2", + "version": "3.3.2", + "engines": ">=10", "ciVersions": [ "10.0.0", "10.x", diff --git a/package-lock.json b/package-lock.json index a5f2e30433b3f..41e70e0a2cb7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -147,7 +147,7 @@ "read-package-json-fast": "^2.0.3", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", - "semver": "^7.3.6", + "semver": "^7.3.7", "ssri": "^9.0.0", "tar": "^6.1.11", "text-table": "~0.2.0", @@ -6515,18 +6515,30 @@ } }, "node_modules/semver": { - "version": "7.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz", - "integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "inBundle": true, "dependencies": { - "lru-cache": "^7.4.0" + "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "inBundle": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/set-blocking": { @@ -10016,7 +10028,7 @@ "read-package-json-fast": "^2.0.2", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", - "semver": "^7.3.5", + "semver": "^7.3.7", "ssri": "^9.0.0", "treeverse": "^2.0.0", "walk-up-path": "^1.0.0" @@ -10181,7 +10193,7 @@ "normalize-package-data": "^4.0.0", "npm-package-arg": "^9.0.1", "npm-registry-fetch": "^13.0.0", - "semver": "^7.1.3", + "semver": "^7.3.7", "ssri": "^9.0.0" }, "devDependencies": { @@ -10237,7 +10249,7 @@ "@npmcli/run-script": "^3.0.0", "json-parse-even-better-errors": "^2.3.1", "proc-log": "^2.0.0", - "semver": "^7.3.5" + "semver": "^7.3.7" }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", @@ -10736,7 +10748,7 @@ "read-package-json-fast": "^2.0.2", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", - "semver": "^7.3.5", + "semver": "7.3.7", "ssri": "^9.0.0", "tap": "^16.0.1", "tcompare": "^5.0.6", @@ -13124,7 +13136,7 @@ "normalize-package-data": "^4.0.0", "npm-package-arg": "^9.0.1", "npm-registry-fetch": "^13.0.0", - "semver": "^7.1.3", + "semver": "7.3.7", "ssri": "^9.0.0", "tap": "^16.0.1" } @@ -13160,7 +13172,7 @@ "json-parse-even-better-errors": "^2.3.1", "proc-log": "^2.0.0", "require-inject": "^1.4.4", - "semver": "^7.3.5", + "semver": "7.3.7", "tap": "^16.0.1" } }, @@ -14523,11 +14535,21 @@ } }, "semver": { - "version": "7.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz", - "integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "requires": { - "lru-cache": "^7.4.0" + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + } } }, "set-blocking": { diff --git a/package.json b/package.json index 832e54efd83bf..07238b3f240d5 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "read-package-json-fast": "^2.0.3", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", - "semver": "^7.3.6", + "semver": "^7.3.7", "ssri": "^9.0.0", "tar": "^6.1.11", "text-table": "~0.2.0", diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index 5e78ced3e6da5..005942e9a2e0e 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -33,7 +33,7 @@ "read-package-json-fast": "^2.0.2", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", - "semver": "^7.3.5", + "semver": "^7.3.7", "ssri": "^9.0.0", "treeverse": "^2.0.0", "walk-up-path": "^1.0.0" diff --git a/workspaces/libnpmpublish/package.json b/workspaces/libnpmpublish/package.json index 1858858d04199..8d0d9644fea0e 100644 --- a/workspaces/libnpmpublish/package.json +++ b/workspaces/libnpmpublish/package.json @@ -45,7 +45,7 @@ "normalize-package-data": "^4.0.0", "npm-package-arg": "^9.0.1", "npm-registry-fetch": "^13.0.0", - "semver": "^7.1.3", + "semver": "^7.3.7", "ssri": "^9.0.0" }, "engines": { diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index 20482ea665be2..fb24fdd135bc8 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -40,7 +40,7 @@ "@npmcli/run-script": "^3.0.0", "json-parse-even-better-errors": "^2.3.1", "proc-log": "^2.0.0", - "semver": "^7.3.5" + "semver": "^7.3.7" }, "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" From 13299eed80db9a05f0b0a063b8936c0148ec3037 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 15:22:45 -0700 Subject: [PATCH 095/406] deps: lru-cache@7.8.1 --- node_modules/lru-cache/index.js | 57 +++++++++++++++++++++-------- node_modules/lru-cache/package.json | 8 +++- package-lock.json | 18 ++++----- 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/node_modules/lru-cache/index.js b/node_modules/lru-cache/index.js index 2168fd3a67bb4..b63be6e988835 100644 --- a/node_modules/lru-cache/index.js +++ b/node_modules/lru-cache/index.js @@ -3,7 +3,7 @@ const perf = typeof performance === 'object' && performance && const hasAbortController = typeof AbortController !== 'undefined' -/* istanbul ignore next - minimal backwards compatibility polyfill */ +// minimal backwards-compatibility polyfill const AC = hasAbortController ? AbortController : Object.assign( class AbortController { constructor () { this.signal = new AC.AbortSignal } @@ -36,14 +36,20 @@ const deprecatedProperty = (field, instead) => { } } -const shouldWarn = code => typeof process === 'object' && - process && - !warned.has(code) +const emitWarning = (...a) => { + typeof process === 'object' && + process && + typeof process.emitWarning === 'function' + ? process.emitWarning(...a) + : console.error(...a) +} + +const shouldWarn = code => !warned.has(code) const warn = (code, what, instead, fn) => { warned.add(code) const msg = `The ${what} is deprecated. Please use ${instead} instead.` - process.emitWarning(msg, 'DeprecationWarning', code, fn) + emitWarning(msg, 'DeprecationWarning', code, fn) } const isPosInt = n => n && n === Math.floor(n) && n > 0 && isFinite(n) @@ -72,7 +78,10 @@ class ZeroArray extends Array { class Stack { constructor (max) { - const UintArray = max ? getUintArray(max) : Array + if (max === 0) { + return [] + } + const UintArray = getUintArray(max) this.heap = new UintArray(max) this.length = 0 } @@ -92,6 +101,7 @@ class LRUCache { ttlResolution = 1, ttlAutopurge, updateAgeOnGet, + updateAgeOnHas, allowStale, dispose, disposeAfter, @@ -136,7 +146,6 @@ class LRUCache { throw new TypeError('fetchMethod must be a function if specified') } - this.keyMap = new Map() this.keyList = new Array(max).fill(null) this.valList = new Array(max).fill(null) @@ -170,6 +179,7 @@ class LRUCache { this.allowStale = !!allowStale || !!stale this.updateAgeOnGet = !!updateAgeOnGet + this.updateAgeOnHas = !!updateAgeOnHas this.ttlResolution = isPosInt(ttlResolution) || ttlResolution === 0 ? ttlResolution : 1 this.ttlAutopurge = !!ttlAutopurge @@ -191,7 +201,7 @@ class LRUCache { warned.add(code) const msg = 'TTL caching without ttlAutopurge, max, or maxSize can ' + 'result in unbounded memory consumption.' - process.emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache) + emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache) } } @@ -207,7 +217,7 @@ class LRUCache { } getRemainingTTL (key) { - return this.has(key) ? Infinity : 0 + return this.has(key, { updateAgeOnHas: false }) ? Infinity : 0 } initializeTTLTracking () { @@ -292,7 +302,7 @@ class LRUCache { this.sizes[index] = size const maxSize = this.maxSize - this.sizes[index] while (this.calculatedSize > maxSize) { - this.evict() + this.evict(true) } this.calculatedSize += this.sizes[index] } @@ -512,8 +522,8 @@ class LRUCache { if (this.size === 0) { return this.tail } - if (this.size === this.max) { - return this.evict() + if (this.size === this.max && this.max !== 0) { + return this.evict(false) } if (this.free.length !== 0) { return this.free.pop() @@ -525,12 +535,12 @@ class LRUCache { pop () { if (this.size) { const val = this.valList[this.head] - this.evict() + this.evict(true) return val } } - evict () { + evict (free) { const head = this.head const k = this.keyList[head] const v = this.valList[head] @@ -543,14 +553,29 @@ class LRUCache { } } this.removeItemSize(head) + // if we aren't about to use the index, then null these out + if (free) { + this.keyList[head] = null + this.valList[head] = null + this.free.push(head) + } this.head = this.next[head] this.keyMap.delete(k) this.size -- return head } - has (k) { - return this.keyMap.has(k) && !this.isStale(this.keyMap.get(k)) + has (k, { updateAgeOnHas = this.updateAgeOnHas } = {}) { + const index = this.keyMap.get(k) + if (index !== undefined) { + if (!this.isStale(index)) { + if (updateAgeOnHas) { + this.updateItemAge(index) + } + return true + } + } + return false } // like get(), but without any LRU updating or TTL expiration diff --git a/node_modules/lru-cache/package.json b/node_modules/lru-cache/package.json index ca75abf004021..32fb9da24e56e 100644 --- a/node_modules/lru-cache/package.json +++ b/node_modules/lru-cache/package.json @@ -1,7 +1,7 @@ { "name": "lru-cache", "description": "A cache object that deletes the least-recently-used items.", - "version": "7.7.3", + "version": "7.8.1", "author": "Isaac Z. Schlueter ", "keywords": [ "mru", @@ -23,6 +23,7 @@ "@size-limit/preset-small-lib": "^7.0.8", "benchmark": "^2.1.4", "clock-mock": "^1.0.4", + "heapdump": "^0.3.15", "size-limit": "^7.0.8", "tap": "^15.1.6" }, @@ -34,7 +35,10 @@ "node": ">=12" }, "tap": { - "coverage-map": "map.js" + "coverage-map": "map.js", + "node-arg": [ + "--expose-gc" + ] }, "size-limit": [ { diff --git a/package-lock.json b/package-lock.json index 41e70e0a2cb7f..eebf70478645b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4585,9 +4585,9 @@ } }, "node_modules/lru-cache": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", - "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz", + "integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==", "inBundle": true, "engines": { "node": ">=12" @@ -10748,7 +10748,7 @@ "read-package-json-fast": "^2.0.2", "readdir-scoped-modules": "^1.1.0", "rimraf": "^3.0.2", - "semver": "7.3.7", + "semver": "^7.3.7", "ssri": "^9.0.0", "tap": "^16.0.1", "tcompare": "^5.0.6", @@ -13136,7 +13136,7 @@ "normalize-package-data": "^4.0.0", "npm-package-arg": "^9.0.1", "npm-registry-fetch": "^13.0.0", - "semver": "7.3.7", + "semver": "^7.3.7", "ssri": "^9.0.0", "tap": "^16.0.1" } @@ -13172,7 +13172,7 @@ "json-parse-even-better-errors": "^2.3.1", "proc-log": "^2.0.0", "require-inject": "^1.4.4", - "semver": "7.3.7", + "semver": "^7.3.7", "tap": "^16.0.1" } }, @@ -13260,9 +13260,9 @@ "peer": true }, "lru-cache": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", - "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==" + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz", + "integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==" }, "make-dir": { "version": "3.1.0", From 0f2da5dca54862707a00d2254bf4c0b4c2e0be60 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 15:32:32 -0700 Subject: [PATCH 096/406] deps: cli-table3@0.6.2 --- node_modules/{ => @colors}/colors/LICENSE | 1 + .../colors/examples/normal-usage.js | 1 + .../colors/examples/safe-string.js | 1 + node_modules/{ => @colors}/colors/index.d.ts | 4 +- .../{ => @colors}/colors/lib/colors.js | 2 +- .../{ => @colors}/colors/lib/custom/trap.js | 0 .../{ => @colors}/colors/lib/custom/zalgo.js | 0 .../colors/lib/extendStringPrototype.js | 0 .../{ => @colors}/colors/lib/index.js | 0 .../{ => @colors}/colors/lib/maps/america.js | 0 .../{ => @colors}/colors/lib/maps/rainbow.js | 0 .../{ => @colors}/colors/lib/maps/random.js | 0 .../{ => @colors}/colors/lib/maps/zebra.js | 0 .../{ => @colors}/colors/lib/styles.js | 0 .../colors/lib/system/has-flag.js | 0 .../colors/lib/system/supports-colors.js | 0 .../{ => @colors}/colors/package.json | 14 ++--- node_modules/{ => @colors}/colors/safe.d.ts | 0 node_modules/{ => @colors}/colors/safe.js | 0 .../colors/themes/generic-logging.js | 0 node_modules/cli-table3/index.d.ts | 1 + node_modules/cli-table3/package.json | 8 +-- node_modules/cli-table3/src/cell.js | 63 ++++++++++++++----- node_modules/cli-table3/src/debug.js | 28 +++++++++ node_modules/cli-table3/src/layout-manager.js | 57 +++++++++++------ node_modules/cli-table3/src/table.js | 33 +++++++++- node_modules/cli-table3/src/utils.js | 38 ++++++++++- package-lock.json | 44 +++++++------ package.json | 2 +- 29 files changed, 227 insertions(+), 70 deletions(-) rename node_modules/{ => @colors}/colors/LICENSE (96%) rename node_modules/{ => @colors}/colors/examples/normal-usage.js (98%) rename node_modules/{ => @colors}/colors/examples/safe-string.js (98%) rename node_modules/{ => @colors}/colors/index.d.ts (96%) rename node_modules/{ => @colors}/colors/lib/colors.js (99%) rename node_modules/{ => @colors}/colors/lib/custom/trap.js (100%) rename node_modules/{ => @colors}/colors/lib/custom/zalgo.js (100%) rename node_modules/{ => @colors}/colors/lib/extendStringPrototype.js (100%) rename node_modules/{ => @colors}/colors/lib/index.js (100%) rename node_modules/{ => @colors}/colors/lib/maps/america.js (100%) rename node_modules/{ => @colors}/colors/lib/maps/rainbow.js (100%) rename node_modules/{ => @colors}/colors/lib/maps/random.js (100%) rename node_modules/{ => @colors}/colors/lib/maps/zebra.js (100%) rename node_modules/{ => @colors}/colors/lib/styles.js (100%) rename node_modules/{ => @colors}/colors/lib/system/has-flag.js (100%) rename node_modules/{ => @colors}/colors/lib/system/supports-colors.js (100%) rename node_modules/{ => @colors}/colors/package.json (68%) rename node_modules/{ => @colors}/colors/safe.d.ts (100%) rename node_modules/{ => @colors}/colors/safe.js (100%) rename node_modules/{ => @colors}/colors/themes/generic-logging.js (100%) create mode 100644 node_modules/cli-table3/src/debug.js diff --git a/node_modules/colors/LICENSE b/node_modules/@colors/colors/LICENSE similarity index 96% rename from node_modules/colors/LICENSE rename to node_modules/@colors/colors/LICENSE index 17880ff02972b..6b86056199d2a 100644 --- a/node_modules/colors/LICENSE +++ b/node_modules/@colors/colors/LICENSE @@ -5,6 +5,7 @@ Original Library Additional Functionality - Copyright (c) Sindre Sorhus (sindresorhus.com) + - Copyright (c) DABH (https://github.com/DABH) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/node_modules/colors/examples/normal-usage.js b/node_modules/@colors/colors/examples/normal-usage.js similarity index 98% rename from node_modules/colors/examples/normal-usage.js rename to node_modules/@colors/colors/examples/normal-usage.js index 822db1cc81ba4..a4bfe7b7be633 100644 --- a/node_modules/colors/examples/normal-usage.js +++ b/node_modules/@colors/colors/examples/normal-usage.js @@ -29,6 +29,7 @@ console.log('Background color attack!'.black.bgWhite); console.log('Use random styles on everything!'.random); console.log('America, Heck Yeah!'.america); +// eslint-disable-next-line max-len console.log('Blindingly '.brightCyan + 'bright? '.brightRed + 'Why '.brightYellow + 'not?!'.brightGreen); console.log('Setting themes is useful'); diff --git a/node_modules/colors/examples/safe-string.js b/node_modules/@colors/colors/examples/safe-string.js similarity index 98% rename from node_modules/colors/examples/safe-string.js rename to node_modules/@colors/colors/examples/safe-string.js index 5bc0168e33ed0..fc664745705f3 100644 --- a/node_modules/colors/examples/safe-string.js +++ b/node_modules/@colors/colors/examples/safe-string.js @@ -28,6 +28,7 @@ console.log(colors.black.bgWhite('Background color attack!')); console.log(colors.random('Use random styles on everything!')); console.log(colors.america('America, Heck Yeah!')); +// eslint-disable-next-line max-len console.log(colors.brightCyan('Blindingly ') + colors.brightRed('bright? ') + colors.brightYellow('Why ') + colors.brightGreen('not?!')); console.log('Setting themes is useful'); diff --git a/node_modules/colors/index.d.ts b/node_modules/@colors/colors/index.d.ts similarity index 96% rename from node_modules/colors/index.d.ts rename to node_modules/@colors/colors/index.d.ts index baa70686535a7..df3f2e6afc945 100644 --- a/node_modules/colors/index.d.ts +++ b/node_modules/@colors/colors/index.d.ts @@ -1,7 +1,7 @@ -// Type definitions for Colors.js 1.2 +// Type definitions for @colors/colors 1.4+ // Project: https://github.com/Marak/colors.js // Definitions by: Bart van der Schoor , Staffan Eketorp -// Definitions: https://github.com/Marak/colors.js +// Definitions: https://github.com/DABH/colors.js export interface Color { (text: string): string; diff --git a/node_modules/colors/lib/colors.js b/node_modules/@colors/colors/lib/colors.js similarity index 99% rename from node_modules/colors/lib/colors.js rename to node_modules/@colors/colors/lib/colors.js index 9c7f1d1416313..d9fb08762fde5 100644 --- a/node_modules/colors/lib/colors.js +++ b/node_modules/@colors/colors/lib/colors.js @@ -65,7 +65,7 @@ var stylize = colors.stylize = function stylize(str, style) { var styleMap = ansiStyles[style]; // Stylize should work for non-ANSI styles, too - if(!styleMap && style in colors){ + if (!styleMap && style in colors) { // Style maps like trap operate as functions on strings; // they don't have properties like open or close. return colors[style](str); diff --git a/node_modules/colors/lib/custom/trap.js b/node_modules/@colors/colors/lib/custom/trap.js similarity index 100% rename from node_modules/colors/lib/custom/trap.js rename to node_modules/@colors/colors/lib/custom/trap.js diff --git a/node_modules/colors/lib/custom/zalgo.js b/node_modules/@colors/colors/lib/custom/zalgo.js similarity index 100% rename from node_modules/colors/lib/custom/zalgo.js rename to node_modules/@colors/colors/lib/custom/zalgo.js diff --git a/node_modules/colors/lib/extendStringPrototype.js b/node_modules/@colors/colors/lib/extendStringPrototype.js similarity index 100% rename from node_modules/colors/lib/extendStringPrototype.js rename to node_modules/@colors/colors/lib/extendStringPrototype.js diff --git a/node_modules/colors/lib/index.js b/node_modules/@colors/colors/lib/index.js similarity index 100% rename from node_modules/colors/lib/index.js rename to node_modules/@colors/colors/lib/index.js diff --git a/node_modules/colors/lib/maps/america.js b/node_modules/@colors/colors/lib/maps/america.js similarity index 100% rename from node_modules/colors/lib/maps/america.js rename to node_modules/@colors/colors/lib/maps/america.js diff --git a/node_modules/colors/lib/maps/rainbow.js b/node_modules/@colors/colors/lib/maps/rainbow.js similarity index 100% rename from node_modules/colors/lib/maps/rainbow.js rename to node_modules/@colors/colors/lib/maps/rainbow.js diff --git a/node_modules/colors/lib/maps/random.js b/node_modules/@colors/colors/lib/maps/random.js similarity index 100% rename from node_modules/colors/lib/maps/random.js rename to node_modules/@colors/colors/lib/maps/random.js diff --git a/node_modules/colors/lib/maps/zebra.js b/node_modules/@colors/colors/lib/maps/zebra.js similarity index 100% rename from node_modules/colors/lib/maps/zebra.js rename to node_modules/@colors/colors/lib/maps/zebra.js diff --git a/node_modules/colors/lib/styles.js b/node_modules/@colors/colors/lib/styles.js similarity index 100% rename from node_modules/colors/lib/styles.js rename to node_modules/@colors/colors/lib/styles.js diff --git a/node_modules/colors/lib/system/has-flag.js b/node_modules/@colors/colors/lib/system/has-flag.js similarity index 100% rename from node_modules/colors/lib/system/has-flag.js rename to node_modules/@colors/colors/lib/system/has-flag.js diff --git a/node_modules/colors/lib/system/supports-colors.js b/node_modules/@colors/colors/lib/system/supports-colors.js similarity index 100% rename from node_modules/colors/lib/system/supports-colors.js rename to node_modules/@colors/colors/lib/system/supports-colors.js diff --git a/node_modules/colors/package.json b/node_modules/@colors/colors/package.json similarity index 68% rename from node_modules/colors/package.json rename to node_modules/@colors/colors/package.json index dbd71ba5a7756..cb87f20953886 100644 --- a/node_modules/colors/package.json +++ b/node_modules/@colors/colors/package.json @@ -1,16 +1,16 @@ { - "name": "colors", + "name": "@colors/colors", "description": "get colors in your node.js console", - "version": "1.4.0", - "author": "Marak Squires", + "version": "1.5.0", + "author": "DABH", "contributors": [ { "name": "DABH", "url": "https://github.com/DABH" } ], - "homepage": "https://github.com/Marak/colors.js", - "bugs": "https://github.com/Marak/colors.js/issues", + "homepage": "https://github.com/DABH/colors.js", + "bugs": "https://github.com/DABH/colors.js/issues", "keywords": [ "ansi", "terminal", @@ -18,12 +18,12 @@ ], "repository": { "type": "git", - "url": "http://github.com/Marak/colors.js.git" + "url": "http://github.com/DABH/colors.js.git" }, "license": "MIT", "scripts": { "lint": "eslint . --fix", - "test": "node tests/basic-test.js && node tests/safe-test.js" + "test": "export FORCE_COLOR=1 && node tests/basic-test.js && node tests/safe-test.js" }, "engines": { "node": ">=0.1.90" diff --git a/node_modules/colors/safe.d.ts b/node_modules/@colors/colors/safe.d.ts similarity index 100% rename from node_modules/colors/safe.d.ts rename to node_modules/@colors/colors/safe.d.ts diff --git a/node_modules/colors/safe.js b/node_modules/@colors/colors/safe.js similarity index 100% rename from node_modules/colors/safe.js rename to node_modules/@colors/colors/safe.js diff --git a/node_modules/colors/themes/generic-logging.js b/node_modules/@colors/colors/themes/generic-logging.js similarity index 100% rename from node_modules/colors/themes/generic-logging.js rename to node_modules/@colors/colors/themes/generic-logging.js diff --git a/node_modules/cli-table3/index.d.ts b/node_modules/cli-table3/index.d.ts index aa94b7440d0ea..16980f848cc8e 100644 --- a/node_modules/cli-table3/index.d.ts +++ b/node_modules/cli-table3/index.d.ts @@ -27,6 +27,7 @@ declare namespace CliTable3 { rowAligns: VerticalAlignment[]; head: string[]; wordWrap: boolean; + wrapOnWordBoundary: boolean; } interface TableInstanceOptions extends TableOptions { diff --git a/node_modules/cli-table3/package.json b/node_modules/cli-table3/package.json index 82a4905f6ec4e..4e6689621968c 100644 --- a/node_modules/cli-table3/package.json +++ b/node_modules/cli-table3/package.json @@ -1,6 +1,6 @@ { "name": "cli-table3", - "version": "0.6.1", + "version": "0.6.2", "description": "Pretty unicode tables for the command line. Based on the original cli-table.", "main": "index.js", "types": "index.d.ts", @@ -16,8 +16,8 @@ "string-width": "^4.2.0" }, "devDependencies": { - "ansi-256-colors": "^1.1.0", "cli-table": "^0.3.1", + "eslint": "^6.0.0", "eslint-config-prettier": "^6.0.0", "eslint-plugin-prettier": "^3.0.0", "jest": "^25.2.4", @@ -26,7 +26,7 @@ "prettier": "2.3.2" }, "optionalDependencies": { - "colors": "1.4.0" + "@colors/colors": "1.5.0" }, "scripts": { "changelog": "lerna-changelog", @@ -75,7 +75,7 @@ { "displayName": "test", "testMatch": [ - "/test/*.js" + "/test/**/*.js" ] }, { diff --git a/node_modules/cli-table3/src/cell.js b/node_modules/cli-table3/src/cell.js index b8da994a61a5a..8f507442bb8fc 100644 --- a/node_modules/cli-table3/src/cell.js +++ b/node_modules/cli-table3/src/cell.js @@ -1,3 +1,4 @@ +const { info, debug } = require('./debug'); const utils = require('./utils'); class Cell { @@ -30,12 +31,19 @@ class Cell { if (['boolean', 'number', 'string'].indexOf(typeof content) !== -1) { this.content = String(content); } else if (!content) { - this.content = ''; + this.content = this.options.href || ''; } else { throw new Error('Content needs to be a primitive, got: ' + typeof content); } this.colSpan = options.colSpan || 1; this.rowSpan = options.rowSpan || 1; + if (this.options.href) { + Object.defineProperty(this, 'href', { + get() { + return this.options.href; + }, + }); + } } mergeTableOptions(tableOptions, cells) { @@ -57,23 +65,35 @@ class Cell { this.head = style.head || tableStyle.head; this.border = style.border || tableStyle.border; - let fixedWidth = tableOptions.colWidths[this.x]; - if (tableOptions.wordWrap && fixedWidth) { - fixedWidth -= this.paddingLeft + this.paddingRight; + this.fixedWidth = tableOptions.colWidths[this.x]; + this.lines = this.computeLines(tableOptions); + + this.desiredWidth = utils.strlen(this.content) + this.paddingLeft + this.paddingRight; + this.desiredHeight = this.lines.length; + } + + computeLines(tableOptions) { + if (this.fixedWidth && (tableOptions.wordWrap || tableOptions.textWrap)) { + this.fixedWidth -= this.paddingLeft + this.paddingRight; if (this.colSpan) { let i = 1; while (i < this.colSpan) { - fixedWidth += tableOptions.colWidths[this.x + i]; + this.fixedWidth += tableOptions.colWidths[this.x + i]; i++; } } - this.lines = utils.colorizeLines(utils.wordWrap(fixedWidth, this.content)); - } else { - this.lines = utils.colorizeLines(this.content.split('\n')); + const { wrapOnWordBoundary = true } = tableOptions; + return this.wrapLines(utils.wordWrap(this.fixedWidth, this.content, wrapOnWordBoundary)); } + return this.wrapLines(this.content.split('\n')); + } - this.desiredWidth = utils.strlen(this.content) + this.paddingLeft + this.paddingRight; - this.desiredHeight = this.lines.length; + wrapLines(computedLines) { + const lines = utils.colorizeLines(computedLines); + if (this.href) { + return lines.map((line) => utils.hyperlink(this.href, line)); + } + return lines; } /** @@ -110,6 +130,12 @@ class Cell { draw(lineNum, spanningCell) { if (lineNum == 'top') return this.drawTop(this.drawRight); if (lineNum == 'bottom') return this.drawBottom(this.drawRight); + let content = utils.truncate(this.content, 10, this.truncate); + if (!lineNum) { + info(`${this.y}-${this.x}: ${this.rowSpan - lineNum}x${this.colSpan} Cell ${content}`); + } else { + // debug(`${lineNum}-${this.x}: 1x${this.colSpan} RowSpanCell ${content}`); + } let padLen = Math.max(this.height - this.lines.length, 0); let padTop; switch (this.vAlign) { @@ -186,7 +212,7 @@ class Cell { wrapWithStyleColors(styleProperty, content) { if (this[styleProperty] && this[styleProperty].length) { try { - let colors = require('colors/safe'); + let colors = require('@colors/colors/safe'); for (let i = this[styleProperty].length - 1; i >= 0; i--) { colors = colors[this[styleProperty][i]]; } @@ -285,7 +311,10 @@ class ColSpanCell { */ constructor() {} - draw() { + draw(lineNum) { + if (typeof lineNum === 'number') { + debug(`${this.y}-${this.x}: 1x1 ColSpanCell`); + } return ''; } @@ -319,21 +348,26 @@ class RowSpanCell { if (lineNum == 'bottom') { return this.originalCell.draw('bottom'); } + debug(`${this.y}-${this.x}: 1x${this.colSpan} RowSpanCell for ${this.originalCell.content}`); return this.originalCell.draw(this.offset + 1 + lineNum); } mergeTableOptions() {} } +function firstDefined(...args) { + return args.filter((v) => v !== undefined && v !== null).shift(); +} + // HELPER FUNCTIONS function setOption(objA, objB, nameB, targetObj) { let nameA = nameB.split('-'); if (nameA.length > 1) { nameA[1] = nameA[1].charAt(0).toUpperCase() + nameA[1].substr(1); nameA = nameA.join(''); - targetObj[nameA] = objA[nameA] || objA[nameB] || objB[nameA] || objB[nameB]; + targetObj[nameA] = firstDefined(objA[nameA], objA[nameB], objB[nameA], objB[nameB]); } else { - targetObj[nameB] = objA[nameB] || objB[nameB]; + targetObj[nameB] = firstDefined(objA[nameB], objB[nameB]); } } @@ -366,6 +400,7 @@ let CHAR_NAMES = [ 'right-mid', 'middle', ]; + module.exports = Cell; module.exports.ColSpanCell = ColSpanCell; module.exports.RowSpanCell = RowSpanCell; diff --git a/node_modules/cli-table3/src/debug.js b/node_modules/cli-table3/src/debug.js new file mode 100644 index 0000000000000..6acfb03032159 --- /dev/null +++ b/node_modules/cli-table3/src/debug.js @@ -0,0 +1,28 @@ +let messages = []; +let level = 0; + +const debug = (msg, min) => { + if (level >= min) { + messages.push(msg); + } +}; + +debug.WARN = 1; +debug.INFO = 2; +debug.DEBUG = 3; + +debug.reset = () => { + messages = []; +}; + +debug.setDebugLevel = (v) => { + level = v; +}; + +debug.warn = (msg) => debug(msg, debug.WARN); +debug.info = (msg) => debug(msg, debug.INFO); +debug.debug = (msg) => debug(msg, debug.DEBUG); + +debug.debugMessages = () => messages; + +module.exports = debug; diff --git a/node_modules/cli-table3/src/layout-manager.js b/node_modules/cli-table3/src/layout-manager.js index fe84ef844da79..3937452274d72 100644 --- a/node_modules/cli-table3/src/layout-manager.js +++ b/node_modules/cli-table3/src/layout-manager.js @@ -1,24 +1,35 @@ +const { warn, debug } = require('./debug'); const Cell = require('./cell'); const { ColSpanCell, RowSpanCell } = Cell; (function () { + function next(alloc, col) { + if (alloc[col] > 0) { + return next(alloc, col + 1); + } + return col; + } + function layoutTable(table) { + let alloc = {}; table.forEach(function (row, rowIndex) { - let prevCell = null; - row.forEach(function (cell, columnIndex) { + let col = 0; + row.forEach(function (cell) { cell.y = rowIndex; - cell.x = prevCell ? prevCell.x + 1 : columnIndex; - for (let y = rowIndex; y >= 0; y--) { - let row2 = table[y]; - let xMax = y === rowIndex ? columnIndex : row2.length; - for (let x = 0; x < xMax; x++) { - let cell2 = row2[x]; - while (cellsConflict(cell, cell2)) { - cell.x++; - } + // Avoid erroneous call to next() on first row + cell.x = rowIndex ? next(alloc, col) : col; + const rowSpan = cell.rowSpan || 1; + const colSpan = cell.colSpan || 1; + if (rowSpan > 1) { + for (let cs = 0; cs < colSpan; cs++) { + alloc[cell.x + cs] = rowSpan; } - prevCell = cell; } + col = cell.x + colSpan; + }); + Object.keys(alloc).forEach((idx) => { + alloc[idx]--; + if (alloc[idx] < 1) delete alloc[idx]; }); }); } @@ -116,6 +127,7 @@ const { ColSpanCell, RowSpanCell } = Cell; function fillInTable(table) { let h_max = maxHeight(table); let w_max = maxWidth(table); + debug(`Max rows: ${h_max}; Max cols: ${w_max}`); for (let y = 0; y < h_max; y++) { for (let x = 0; x < w_max; x++) { if (!conflictExists(table, x, y)) { @@ -130,10 +142,10 @@ const { ColSpanCell, RowSpanCell } = Cell; opts.rowSpan++; y2++; } - let cell = new Cell(opts); cell.x = opts.x; cell.y = opts.y; + warn(`Missing cell at ${cell.y}-${cell.x}.`); insertCell(cell, table[y]); } } @@ -182,6 +194,7 @@ function makeComputeWidths(colSpan, desiredWidth, x, forcedMin) { return function (vals, table) { let result = []; let spanners = []; + let auto = {}; table.forEach(function (row) { row.forEach(function (cell) { if ((cell[colSpan] || 1) > 1) { @@ -205,12 +218,20 @@ function makeComputeWidths(colSpan, desiredWidth, x, forcedMin) { let col = cell[x]; let existingWidth = result[col]; let editableCols = typeof vals[col] === 'number' ? 0 : 1; - for (let i = 1; i < span; i++) { - existingWidth += 1 + result[col + i]; - if (typeof vals[col + i] !== 'number') { - editableCols++; + if (typeof existingWidth === 'number') { + for (let i = 1; i < span; i++) { + existingWidth += 1 + result[col + i]; + if (typeof vals[col + i] !== 'number') { + editableCols++; + } + } + } else { + existingWidth = desiredWidth === 'desiredWidth' ? cell.desiredWidth - 1 : 1; + if (!auto[col] || auto[col] < existingWidth) { + auto[col] = existingWidth; } } + if (cell[desiredWidth] > existingWidth) { let i = 0; while (editableCols > 0 && cell[desiredWidth] > existingWidth) { @@ -225,7 +246,7 @@ function makeComputeWidths(colSpan, desiredWidth, x, forcedMin) { } } - Object.assign(vals, result); + Object.assign(vals, result, auto); for (let j = 0; j < vals.length; j++) { vals[j] = Math.max(forcedMin, vals[j] || 0); } diff --git a/node_modules/cli-table3/src/table.js b/node_modules/cli-table3/src/table.js index 4fb33eccf6406..eb4a9bda9a364 100644 --- a/node_modules/cli-table3/src/table.js +++ b/node_modules/cli-table3/src/table.js @@ -1,11 +1,38 @@ +const debug = require('./debug'); const utils = require('./utils'); const tableLayout = require('./layout-manager'); class Table extends Array { - constructor(options) { + constructor(opts) { super(); - this.options = utils.mergeOptions(options); + const options = utils.mergeOptions(opts); + Object.defineProperty(this, 'options', { + value: options, + enumerable: options.debug, + }); + + if (options.debug) { + switch (typeof options.debug) { + case 'boolean': + debug.setDebugLevel(debug.WARN); + break; + case 'number': + debug.setDebugLevel(options.debug); + break; + case 'string': + debug.setDebugLevel(parseInt(options.debug, 10)); + break; + default: + debug.setDebugLevel(debug.WARN); + debug.warn(`Debug option is expected to be boolean, number, or string. Received a ${typeof options.debug}`); + } + Object.defineProperty(this, 'messages', { + get() { + return debug.debugMessages(); + }, + }); + } } toString() { @@ -65,6 +92,8 @@ class Table extends Array { } } +Table.reset = () => debug.reset(); + function doDraw(row, lineNum, result) { let line = []; row.forEach(function (cell) { diff --git a/node_modules/cli-table3/src/utils.js b/node_modules/cli-table3/src/utils.js index 1e6254af984d0..c922c5b9adb62 100644 --- a/node_modules/cli-table3/src/utils.js +++ b/node_modules/cli-table3/src/utils.js @@ -240,6 +240,7 @@ function mergeOptions(options, defaults) { return ret; } +// Wrap on word boundary function wordWrap(maxLength, input) { let lines = []; let split = input.split(/(\s+)/g); @@ -270,11 +271,32 @@ function wordWrap(maxLength, input) { return lines; } -function multiLineWordWrap(maxLength, input) { +// Wrap text (ignoring word boundaries) +function textWrap(maxLength, input) { + let lines = []; + let line = ''; + function pushLine(str, ws) { + if (line.length && ws) line += ws; + line += str; + while (line.length > maxLength) { + lines.push(line.slice(0, maxLength)); + line = line.slice(maxLength); + } + } + let split = input.split(/(\s+)/g); + for (let i = 0; i < split.length; i += 2) { + pushLine(split[i], i && split[i - 1]); + } + if (line.length) lines.push(line); + return lines; +} + +function multiLineWordWrap(maxLength, input, wrapOnWordBoundary = true) { let output = []; input = input.split('\n'); + const handler = wrapOnWordBoundary ? wordWrap : textWrap; for (let i = 0; i < input.length; i++) { - output.push.apply(output, wordWrap(maxLength, input[i])); + output.push.apply(output, handler(maxLength, input[i])); } return output; } @@ -291,6 +313,17 @@ function colorizeLines(input) { return output; } +/** + * Credit: Matheus Sampaio https://github.com/matheussampaio + */ +function hyperlink(url, text) { + const OSC = '\u001B]'; + const BEL = '\u0007'; + const SEP = ';'; + + return [OSC, '8', SEP, SEP, url || text, BEL, text, OSC, '8', SEP, SEP, BEL].join(''); +} + module.exports = { strlen: strlen, repeat: repeat, @@ -299,4 +332,5 @@ module.exports = { mergeOptions: mergeOptions, wordWrap: multiLineWordWrap, colorizeLines: colorizeLines, + hyperlink, }; diff --git a/package-lock.json b/package-lock.json index eebf70478645b..eccfacccb2913 100644 --- a/package-lock.json +++ b/package-lock.json @@ -100,7 +100,7 @@ "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.1", + "cli-table3": "^0.6.2", "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.12", "glob": "^8.0.1", @@ -565,6 +565,16 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "inBundle": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.2.1", "dev": true, @@ -1808,9 +1818,10 @@ } }, "node_modules/cli-table3": { - "version": "0.6.1", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", "inBundle": true, - "license": "MIT", "dependencies": { "string-width": "^4.2.0" }, @@ -1818,7 +1829,7 @@ "node": "10.* || >= 12.*" }, "optionalDependencies": { - "colors": "1.4.0" + "@colors/colors": "1.5.0" } }, "node_modules/cliui": { @@ -1905,15 +1916,6 @@ "color-support": "bin.js" } }, - "node_modules/colors": { - "version": "1.4.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/columnify": { "version": "1.6.0", "inBundle": true, @@ -10513,6 +10515,12 @@ "version": "2.0.0", "dev": true }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true + }, "@eslint/eslintrc": { "version": "1.2.1", "dev": true, @@ -11386,9 +11394,11 @@ } }, "cli-table3": { - "version": "0.6.1", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", + "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", "requires": { - "colors": "1.4.0", + "@colors/colors": "1.5.0", "string-width": "^4.2.0" } }, @@ -11441,10 +11451,6 @@ "color-support": { "version": "1.1.3" }, - "colors": { - "version": "1.4.0", - "optional": true - }, "columnify": { "version": "1.6.0", "requires": { diff --git a/package.json b/package.json index 07238b3f240d5..3cc79695bab24 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.1", + "cli-table3": "^0.6.2", "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.12", "glob": "^8.0.1", From 9ea26038ad4d3dc971d442cba2bb02a35755c07a Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Wed, 20 Apr 2022 20:10:37 -0700 Subject: [PATCH 097/406] fix: normalize win32 paths before globbing --- lib/commands/help-search.js | 4 +++- lib/commands/help.js | 5 +++-- lib/utils/log-file.js | 5 +++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/commands/help-search.js b/lib/commands/help-search.js index 23b426eaa016d..488189bbbc5cd 100644 --- a/lib/commands/help-search.js +++ b/lib/commands/help-search.js @@ -6,6 +6,8 @@ const glob = promisify(require('glob')) const readFile = promisify(fs.readFile) const BaseCommand = require('../base-command.js') +const globify = pattern => pattern.split('\\').join('/') + class HelpSearch extends BaseCommand { static description = 'Search npm help documentation' static name = 'help-search' @@ -19,7 +21,7 @@ class HelpSearch extends BaseCommand { } const docPath = path.resolve(__dirname, '..', '..', 'docs/content') - const files = await glob(`${docPath}/*/*.md`) + const files = await glob(`${globify(docPath)}/*/*.md`) const data = await this.readFiles(files) const results = await this.searchFiles(args, data, files) const formatted = this.formatResults(args, results) diff --git a/lib/commands/help.js b/lib/commands/help.js index d31b3ca697651..e7d6395a1b01a 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -5,6 +5,7 @@ const { promisify } = require('util') const glob = promisify(require('glob')) const localeCompare = require('@isaacs/string-locale-compare')('en') +const globify = pattern => pattern.split('\\').join('/') const BaseCommand = require('../base-command.js') // Strips out the number from foo.7 or foo.7. or foo.7.tgz @@ -26,7 +27,7 @@ class Help extends BaseCommand { return [] } const g = path.resolve(__dirname, '../../man/man[0-9]/*.[0-9]') - const files = await glob(g) + const files = await glob(globify(g)) return Object.keys(files.reduce(function (acc, file) { file = path.basename(file).replace(/\.[0-9]+$/, '') @@ -61,7 +62,7 @@ class Help extends BaseCommand { const manroot = path.resolve(__dirname, '..', '..', 'man') // find either section.n or npm-section.n const f = `${manroot}/${manSearch}/?(npm-)${section}.[0-9]*` - let mans = await glob(f) + let mans = await glob(globify(f)) mans = mans.sort((a, b) => { // Prefer the page with an npm prefix, if there's only one. const aHasPrefix = manNpmPrefixRegex.test(a) diff --git a/lib/utils/log-file.js b/lib/utils/log-file.js index 282c72700e58e..9cf6513bedf48 100644 --- a/lib/utils/log-file.js +++ b/lib/utils/log-file.js @@ -9,6 +9,7 @@ const fs = require('@npmcli/fs') const log = require('./log-shim') const padZero = (n, length) => n.toString().padStart(length.toString().length, '0') +const globify = pattern => pattern.split('\\').join('/') const _logHandler = Symbol('logHandler') const _formatLogItem = Symbol('formatLogItem') @@ -225,7 +226,7 @@ class LogFiles { ) // Always ignore the currently written files - const files = await glob(logGlob, { ignore: this.#files }) + const files = await glob(globify(logGlob), { ignore: this.#files.map(globify) }) const toDelete = files.length - this.#logsMax if (toDelete <= 0) { @@ -236,7 +237,7 @@ class LogFiles { for (const file of files.slice(0, toDelete)) { try { - await rimraf(file) + await rimraf(file, { glob: false }) } catch (e) { log.silly('logfile', 'error removing log file', file, e) } From 9a19bc9887cf9ee20c4d465154e099fff15362e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 20:30:41 +0000 Subject: [PATCH 098/406] chore(latest): release arborist 5.1.1 --- workspaces/arborist/CHANGELOG.md | 10 ++++++++++ workspaces/arborist/package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/workspaces/arborist/CHANGELOG.md b/workspaces/arborist/CHANGELOG.md index c1ab55234607c..476524a265191 100644 --- a/workspaces/arborist/CHANGELOG.md +++ b/workspaces/arborist/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +### [5.1.1](https://github.com/npm/cli/compare/arborist-v5.1.0...arborist-v5.1.1) (2022-04-26) + + +### Dependencies + +* @npmcli/map-workspaces@2.0.3 ([3f2b24a](https://github.com/npm/cli/commit/3f2b24afe205547dbbadf5a6313e95f6b565fb49)) +* cacache@16.0.6 ([532883f](https://github.com/npm/cli/commit/532883ffc35fc1cc9aec09f03bf5ee0f256b94a4)) +* npmlog@6.0.2 ([5e31322](https://github.com/npm/cli/commit/5e313223100db1207818d756b081eaba3468b273)) +* semver@7.3.7 ([c51e553](https://github.com/npm/cli/commit/c51e553a32315e4f1b703ca9030eb7ade91d1a85)) + ## [5.1.0](https://github.com/npm/cli/compare/arborist-v5.0.6...arborist-v5.1.0) (2022-04-19) diff --git a/workspaces/arborist/package.json b/workspaces/arborist/package.json index 005942e9a2e0e..bf3031fd066d5 100644 --- a/workspaces/arborist/package.json +++ b/workspaces/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "5.1.0", + "version": "5.1.1", "description": "Manage node_modules trees", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", From 36899d193b8e8ee6019b04aa5e6a3a9a641a3172 Mon Sep 17 00:00:00 2001 From: npm team Date: Tue, 26 Apr 2022 20:31:20 +0000 Subject: [PATCH 099/406] deps: @npmcli/arborist@5.1.1 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index eccfacccb2913..84057bb73b161 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9997,7 +9997,7 @@ }, "workspaces/arborist": { "name": "@npmcli/arborist", - "version": "5.1.0", + "version": "5.1.1", "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", From 2e92e75a5cb7b2d94e9790d956870bf0c7147ebb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 20:29:55 +0000 Subject: [PATCH 100/406] chore(latest): release libnpmpublish 6.0.4 --- workspaces/libnpmpublish/CHANGELOG.md | 12 ++++++++++++ workspaces/libnpmpublish/package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmpublish/CHANGELOG.md b/workspaces/libnpmpublish/CHANGELOG.md index a93a930f1f2f8..5cda1cb947023 100644 --- a/workspaces/libnpmpublish/CHANGELOG.md +++ b/workspaces/libnpmpublish/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +### [6.0.4](https://github.com/npm/cli/compare/libnpmpublish-v6.0.3...libnpmpublish-v6.0.4) (2022-04-26) + + +### Bug Fixes + +* **libnpmpublish:** unpublish from custom reg ([#4657](https://github.com/npm/cli/issues/4657)) ([e9163b4](https://github.com/npm/cli/commit/e9163b48d8e46a80d2a4cc98c492b94dfa152cb8)) + + +### Dependencies + +* semver@7.3.7 ([c51e553](https://github.com/npm/cli/commit/c51e553a32315e4f1b703ca9030eb7ade91d1a85)) + ### [6.0.3](https://github.com/npm/cli/compare/libnpmpublish-v6.0.2...libnpmpublish-v6.0.3) (2022-04-06) diff --git a/workspaces/libnpmpublish/package.json b/workspaces/libnpmpublish/package.json index 8d0d9644fea0e..fec6490d4771c 100644 --- a/workspaces/libnpmpublish/package.json +++ b/workspaces/libnpmpublish/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpublish", - "version": "6.0.3", + "version": "6.0.4", "description": "Programmatic API for the bits behind npm publish and unpublish", "author": "GitHub Inc.", "main": "lib/index.js", From 0ee57f1492893da84686f4340feeb0469fb751f8 Mon Sep 17 00:00:00 2001 From: npm team Date: Tue, 26 Apr 2022 20:30:20 +0000 Subject: [PATCH 101/406] deps: libnpmpublish@6.0.4 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 84057bb73b161..f5858fdd92580 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10189,7 +10189,7 @@ } }, "workspaces/libnpmpublish": { - "version": "6.0.3", + "version": "6.0.4", "license": "ISC", "dependencies": { "normalize-package-data": "^4.0.0", From 60ef43b4d2704699266e3b6257a887eb1cbd5760 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 20:30:09 +0000 Subject: [PATCH 102/406] chore(latest): release libnpmversion 3.0.4 --- workspaces/libnpmversion/CHANGELOG.md | 7 +++++++ workspaces/libnpmversion/package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmversion/CHANGELOG.md b/workspaces/libnpmversion/CHANGELOG.md index 2adb434e28653..2045dc32b9788 100644 --- a/workspaces/libnpmversion/CHANGELOG.md +++ b/workspaces/libnpmversion/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [3.0.4](https://github.com/npm/cli/compare/libnpmversion-v3.0.3...libnpmversion-v3.0.4) (2022-04-26) + + +### Dependencies + +* semver@7.3.7 ([c51e553](https://github.com/npm/cli/commit/c51e553a32315e4f1b703ca9030eb7ade91d1a85)) + ### [3.0.3](https://github.com/npm/cli/compare/libnpmversion-v3.0.2...libnpmversion-v3.0.3) (2022-04-12) diff --git a/workspaces/libnpmversion/package.json b/workspaces/libnpmversion/package.json index fb24fdd135bc8..d374f3e392b5d 100644 --- a/workspaces/libnpmversion/package.json +++ b/workspaces/libnpmversion/package.json @@ -1,6 +1,6 @@ { "name": "libnpmversion", - "version": "3.0.3", + "version": "3.0.4", "main": "lib/index.js", "files": [ "bin/", From 8a633a436cf37dad293af3aaf8ea9a0b5badf314 Mon Sep 17 00:00:00 2001 From: npm team Date: Tue, 26 Apr 2022 20:30:45 +0000 Subject: [PATCH 103/406] deps: libnpmversion@3.0.4 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index f5858fdd92580..d91abe767184d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10244,7 +10244,7 @@ } }, "workspaces/libnpmversion": { - "version": "3.0.3", + "version": "3.0.4", "license": "ISC", "dependencies": { "@npmcli/git": "^3.0.0", From 2bd2c0d96628ac1e7c237a803c02c5311238d4d2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 20:30:42 +0000 Subject: [PATCH 104/406] chore(latest): release libnpmexec 4.0.5 --- workspaces/libnpmexec/CHANGELOG.md | 7 +++++++ workspaces/libnpmexec/package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmexec/CHANGELOG.md b/workspaces/libnpmexec/CHANGELOG.md index ffa1212ee1ad6..cb123185f15c0 100644 --- a/workspaces/libnpmexec/CHANGELOG.md +++ b/workspaces/libnpmexec/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [4.0.5](https://github.com/npm/cli/compare/libnpmexec-v4.0.4...libnpmexec-v4.0.5) (2022-04-26) + + +### Dependencies + +* npmlog@6.0.2 ([5e31322](https://github.com/npm/cli/commit/5e313223100db1207818d756b081eaba3468b273)) + ### [4.0.4](https://github.com/npm/cli/compare/libnpmexec-v4.0.3...libnpmexec-v4.0.4) (2022-04-19) diff --git a/workspaces/libnpmexec/package.json b/workspaces/libnpmexec/package.json index c108ddaea5117..f41df25140fb2 100644 --- a/workspaces/libnpmexec/package.json +++ b/workspaces/libnpmexec/package.json @@ -1,6 +1,6 @@ { "name": "libnpmexec", - "version": "4.0.4", + "version": "4.0.5", "files": [ "bin/", "lib/" From b1b69487637ce99192dc930257eebae9eed4fe7f Mon Sep 17 00:00:00 2001 From: npm team Date: Tue, 26 Apr 2022 20:31:18 +0000 Subject: [PATCH 105/406] deps: libnpmexec@4.0.5 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index d91abe767184d..7b568a1b5d3cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10094,7 +10094,7 @@ } }, "workspaces/libnpmexec": { - "version": "4.0.4", + "version": "4.0.5", "license": "ISC", "dependencies": { "@npmcli/arborist": "^5.0.0", From 8f7bccb0380827d2a14a4da36af6281c3f3836a4 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Tue, 26 Apr 2022 18:01:36 -0400 Subject: [PATCH 106/406] chore: changelog for v8.8.0 --- CHANGELOG.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee70bdb4dafa2..2e3b4f6dbeb99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,49 @@ # Changelog +## v8.8.0 (2022-04-27) + +### Features + + * [`bedd8a1`](https://github.com/npm/cli/commit/bedd8a1f5844b5b379af5a756baa70821d78c610) [#4745](https://github.com/npm/cli/pull/4745) feat: add install-links config definition ([@nlf](https://github.com/nlf)) + +### Bug Fixes + + * [`6253d19`](https://github.com/npm/cli/commit/6253d1968d8390ea6b16604ff3abb5e6509349c9) [#4643](https://github.com/npm/cli/pull/4643) fix(exec): workspaces support ([@ruyadorno](https://github.com/ruyadorno)) + * [`e9163b4`](https://github.com/npm/cli/commit/e9163b48d8e46a80d2a4cc98c492b94dfa152cb8) [#4657](https://github.com/npm/cli/pull/4657) fix(libnpmpublish): unpublish from custom registry ([@ruyadorno](https://github.com/ruyadorno)) + * [`a677f49`](https://github.com/npm/cli/commit/a677f49e29ee9d472c8c9aa1c9eb3d5d8b4ee4a9) [#4778](https://github.com/npm/cli/pull/4778) fix: Use node in and fallback to PATH if not found ([@elibus](https://github.com/elibus)) + * [`b10462e`](https://github.com/npm/cli/commit/b10462ed156ada4d4ad90e6cf613e292a9361a87) [#4752](https://github.com/npm/cli/pull/4752) fix: completion for `deprecate` cmd ([@wraithgar](https://github.com/wraithgar)) + * [`ced0acf`](https://github.com/npm/cli/commit/ced0acfe5998a5be9313815f76f5c1439a09db78) [#4775](https://github.com/npm/cli/pull/4775) fix: consolidate registryConfig application logic ([@wraithgar](https://github.com/wraithgar)) + * [`b06e89f`](https://github.com/npm/cli/commit/b06e89f434fe8f104e71d4d8b5c98f1e866efdfa) [#4679](https://github.com/npm/cli/pull/4679) fix(install): do not install invalid package name ([@ruyadorno](https://github.com/ruyadorno)) + * [`9ea2603`](https://github.com/npm/cli/commit/9ea26038ad4d3dc971d442cba2bb02a35755c07a) [#4786](https://github.com/npm/cli/pull/4786) fix: normalize win32 paths before globbing ([@lukekarrys](https://github.com/lukekarrys)) + * [`8da28b4`](https://github.com/npm/cli/commit/8da28b403f32d2e99c842893bdc40429b8ffa9a7) [#4757](https://github.com/npm/cli/pull/4757) fix: remove `lib/utils/read-package-name.js` ([@wraithgar](https://github.com/wraithgar)) + +### Documentation + + * [`a6ea884`](https://github.com/npm/cli/commit/a6ea8843a9761d4392b3344400eb56e07691a91d) [#4745](https://github.com/npm/cli/pull/4745) docs: add some more docs for --install-links ([@nlf](https://github.com/nlf)) + * [`6cd6831`](https://github.com/npm/cli/commit/6cd6831eaa9e1681e07f6646e6f13cce344e1250) [#4782](https://github.com/npm/cli/pull/4782) docs: explain that _auth only goes to npm registry ([@wraithgar](https://github.com/wraithgar)) + * [`fa3d829`](https://github.com/npm/cli/commit/fa3d82989df7071cfe500c5f9cc09c597bcc17ee) [#4772](https://github.com/npm/cli/pull/4772) docs: include org instructions in scoped publish ([@bnb](https://github.com/bnb)) + +### Dependencies + + * [`36899d1`](https://github.com/npm/cli/commit/36899d193b8e8ee6019b04aa5e6a3a9a641a3172) [#4807](https://github.com/npm/cli/pull/4807) deps: `@npmcli/arborist@5.1.1` + * [`0ebadf5`](https://github.com/npm/cli/commit/0ebadf5b603368557e9e837a46ea5c59c2677a81) [#4745](https://github.com/npm/cli/pull/4745) add support for installLinks ([@nlf](https://github.com/nlf)) + * [`3d96494`](https://github.com/npm/cli/commit/3d964940f410052918e37a9b05818fe9dc4cd86a) [#4745](https://github.com/npm/cli/pull/4745) when replacing a Link with a Node, make sure to remove the Link target from the root ([@nlf](https://github.com/nlf)) + * [`3f2b24a`](https://github.com/npm/cli/commit/3f2b24afe205547dbbadf5a6313e95f6b565fb49) [#4786](https://github.com/npm/cli/pull/4786) deps: `@npmcli/map-workspaces@2.0.3` + * [`b1b6948`](https://github.com/npm/cli/commit/b1b69487637ce99192dc930257eebae9eed4fe7f) [#4808](https://github.com/npm/cli/pull/4808) deps: `libnpmexec@4.0.5` + * [`4a46a27`](https://github.com/npm/cli/commit/4a46a27f2b968e2f8c1f4821508f93013738c482) [#4777](https://github.com/npm/cli/pull/4777) fix read mixed local/registry pkg ([@ruyadorno](https://github.com/ruyadorno)) + * [`9f57404`](https://github.com/npm/cli/commit/9f57404dc148835d7393b5fe617c8c5e2c958061) [#4743](https://github.com/npm/cli/pull/4743) deps: `npm-registry-fetch@13.1.1` + * [`532883f`](https://github.com/npm/cli/commit/532883ffc35fc1cc9aec09f03bf5ee0f256b94a4) [#4786](https://github.com/npm/cli/pull/4786) deps: `cacache@16.0.6` + * [`4d1398e`](https://github.com/npm/cli/commit/4d1398e347ed56464d7afd8ef0b3a3bc82b2f19f) [#4786](https://github.com/npm/cli/pull/4786) deps: `npm-profile@6.0.3` + * [`5e31322`](https://github.com/npm/cli/commit/5e313223100db1207818d756b081eaba3468b273) [#4786](https://github.com/npm/cli/pull/4786) deps: `npmlog@6.0.2` + * [`4eb2ccb`](https://github.com/npm/cli/commit/4eb2ccbacbd2ca55f2a41a104ee20578542fc52f) [#4786](https://github.com/npm/cli/pull/4786) deps: `read-package-json@5.0.1` + * [`aeb54e4`](https://github.com/npm/cli/commit/aeb54e41b613f4a98d1f02d255b3a564c43270d8) [#4786](https://github.com/npm/cli/pull/4786) deps: `glob@8.0.1` + * [`252b2b1`](https://github.com/npm/cli/commit/252b2b1e8caaf1c26e5ab6836a83ec430d2a699a) [#4786](https://github.com/npm/cli/pull/4786) deps: `npm-packlist@5.0.2` + * [`c51e553`](https://github.com/npm/cli/commit/c51e553a32315e4f1b703ca9030eb7ade91d1a85) [#4786](https://github.com/npm/cli/pull/4786) deps: `semver@7.3.7` + * [`13299ee`](https://github.com/npm/cli/commit/13299eed80db9a05f0b0a063b8936c0148ec3037) [#4786](https://github.com/npm/cli/pull/4786) deps: `lru-cache@7.8.1` + * [`0f2da5d`](https://github.com/npm/cli/commit/0f2da5dca54862707a00d2254bf4c0b4c2e0be60) [#4786](https://github.com/npm/cli/pull/4786) deps: `cli-table3@0.6.2` + * [`0ee57f1`](https://github.com/npm/cli/commit/0ee57f1492893da84686f4340feeb0469fb751f8) [#4805](https://github.com/npm/cli/pull/4805) deps: `libnpmpublish@6.0.4` + * [`8a633a4`](https://github.com/npm/cli/commit/8a633a436cf37dad293af3aaf8ea9a0b5badf314) [#4806](https://github.com/npm/cli/pull/4806) deps: `libnpmversion@3.0.4` + ## v8.7.0 (2022-04-13) ### Features From f63d680b730e4cb73b019dcc39ede1bc44447c26 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Tue, 26 Apr 2022 18:02:20 -0400 Subject: [PATCH 107/406] chore: update AUTHORS --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index 5e7c0c9ad8e6c..eaa9149070222 100644 --- a/AUTHORS +++ b/AUTHORS @@ -830,3 +830,5 @@ Boris Verkhovskiy JSKitty CommanderRoot npm cli ops bot +Marco Tizzoni +npm team From 7a858277171813b37d46a032e49db44c8624f78f Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Tue, 26 Apr 2022 18:02:20 -0400 Subject: [PATCH 108/406] 8.8.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 7b568a1b5d3cb..7babdc84abc78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "npm", - "version": "8.7.0", + "version": "8.8.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "npm", - "version": "8.7.0", + "version": "8.8.0", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", diff --git a/package.json b/package.json index 3cc79695bab24..e1f683219311a 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "8.7.0", + "version": "8.8.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ From 4e994c5af4af18c9235479d4e43f62f910d36f8b Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Tue, 3 May 2022 12:29:36 -0400 Subject: [PATCH 109/406] chore: remove bot from authors (#4833) Replaces: https://github.com/npm/cli/pull/4814 Co-authored-by: Gar Co-authored-by: Gar --- .mailmap | 1 + AUTHORS | 2 -- scripts/update-authors.sh | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.mailmap b/.mailmap index 725a59da65590..41b54f4896a49 100644 --- a/.mailmap +++ b/.mailmap @@ -55,6 +55,7 @@ Maximilian Antoni Michael Hayes Misha Kaletsky Nicolas Morel +npm team Olivier Melcher Ra'Shaun Stovall Rebecca Turner diff --git a/AUTHORS b/AUTHORS index eaa9149070222..7bddcf7dc4ba9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -829,6 +829,4 @@ David Walker Boris Verkhovskiy JSKitty CommanderRoot -npm cli ops bot Marco Tizzoni -npm team diff --git a/scripts/update-authors.sh b/scripts/update-authors.sh index 732ad7d3504d6..3c1990f353268 100755 --- a/scripts/update-authors.sh +++ b/scripts/update-authors.sh @@ -1,6 +1,6 @@ #!/bin/sh -git log --use-mailmap --reverse --format='%aN <%aE>' | grep -v "\[bot\]" | perl -wnE ' +git log --use-mailmap --reverse --format='%aN <%aE>' | grep -v "\[bot\]" | grep -v "^npm team" | perl -wnE ' BEGIN { say "# Authors sorted by whether or not they\x27re me"; } From 9ed00dc9f31e5f9237c981d11784dd6cd4bd1df4 Mon Sep 17 00:00:00 2001 From: nlf Date: Tue, 3 May 2022 10:36:17 -0700 Subject: [PATCH 110/406] chore(benchmarks): add missing space to if condition (#4841) --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 2e363cb3006ec..3eca93882c07a 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -44,7 +44,7 @@ jobs: PR="${{ github.event.issue.number }}" SENDER="${{ github.event.issue.sender.login }}" ROLE=$(gh api repos/${OWNER}/${REPO}/collaborators/${SENDER}/permission -q '.permission') - if [[ "$ROLE" != "admin"]]; then + if [[ "$ROLE" != "admin" ]]; then echo "${SENDER} is ${ROLE}, not an admin, exiting" exit 0 fi From d654e7e9146f123a9806cfd9a17150eb1f6075a4 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 20 Apr 2022 07:12:39 -0700 Subject: [PATCH 111/406] fix: start consolidating color output chalk already has a way to disable color output, so if we don't want color we can disable it there and always use that instance of chalk. This was only updated in the two commands that have real tests. Doing it in the other places is going to require making their tests real so that we don't ALSO have to rewrite their tests just to change their internal code. --- lib/commands/doctor.js | 34 ++++++++++++---------------------- lib/commands/publish.js | 7 ++----- lib/npm.js | 19 +++++++++++++++---- test/fixtures/mock-npm.js | 4 +++- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lib/commands/doctor.js b/lib/commands/doctor.js index ca0438f1a2481..f5bee1eb83f6c 100644 --- a/lib/commands/doctor.js +++ b/lib/commands/doctor.js @@ -1,5 +1,4 @@ const cacache = require('cacache') -const chalk = require('chalk') const fs = require('fs') const fetch = require('make-fetch-happen') const table = require('text-table') @@ -102,28 +101,19 @@ class Doctor extends BaseCommand { messages.push(line) } - const outHead = ['Check', 'Value', 'Recommendation/Notes'].map( - !this.npm.color ? h => h : h => chalk.underline(h) - ) + const outHead = ['Check', 'Value', 'Recommendation/Notes'].map(h => this.npm.chalk.underline(h)) let allOk = true - const outBody = messages.map( - !this.npm.color - ? item => { - allOk = allOk && item[1] - item[1] = item[1] ? 'ok' : 'not ok' - item[2] = String(item[2]) - return item - } - : item => { - allOk = allOk && item[1] - if (!item[1]) { - item[0] = chalk.red(item[0]) - item[2] = chalk.magenta(String(item[2])) - } - item[1] = item[1] ? chalk.green('ok') : chalk.red('not ok') - return item - } - ) + const outBody = messages.map(item => { + if (!item[1]) { + allOk = false + item[0] = this.npm.chalk.red(item[0]) + item[1] = this.npm.chalk.red('not ok') + item[2] = this.npm.chalk.magenta(String(item[2])) + } else { + item[1] = this.npm.chalk.green('ok') + } + return item + }) const outTable = [outHead, ...outBody] const tableOpts = { stringLength: s => ansiTrim(s).length, diff --git a/lib/commands/publish.js b/lib/commands/publish.js index ff30366938786..cbf0ccf4d6581 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -7,7 +7,6 @@ const runScript = require('@npmcli/run-script') const pacote = require('pacote') const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') -const chalk = require('chalk') const replaceInfo = require('../utils/replace-info.js') const otplease = require('../utils/otplease.js') @@ -151,8 +150,6 @@ class Publish extends BaseCommand { const results = {} const json = this.npm.config.get('json') const { silent } = this.npm - const noop = a => a - const color = this.npm.color ? chalk : { green: noop, bold: noop } await this.setWorkspaces(filters) for (const [name, workspace] of this.workspaces.entries()) { @@ -164,9 +161,9 @@ class Publish extends BaseCommand { log.warn( 'publish', `Skipping workspace ${ - color.green(name) + this.npm.chalk.green(name) }, marked as ${ - color.bold('private') + this.npm.chalk.bold('private') }` ) continue diff --git a/lib/npm.js b/lib/npm.js index c819a0807b507..732362565e290 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -1,16 +1,15 @@ const EventEmitter = require('events') const { resolve, dirname, join } = require('path') const Config = require('@npmcli/config') +const chalk = require('chalk') +const which = require('which') +const fs = require('@npmcli/fs') // Patch the global fs module here at the app level require('graceful-fs').gracefulify(require('fs')) const { definitions, flatten, shorthands } = require('./utils/config/index.js') const usage = require('./utils/npm-usage.js') - -const which = require('which') -const fs = require('@npmcli/fs') - const LogFile = require('./utils/log-file.js') const Timers = require('./utils/timers.js') const Display = require('./utils/display.js') @@ -37,6 +36,7 @@ class Npm extends EventEmitter { #tmpFolder = null #title = 'npm' #argvClean = [] + #chalk = null #logFile = new LogFile() #display = new Display() @@ -322,6 +322,17 @@ class Npm extends EventEmitter { return this.flatOptions.color } + get chalk () { + if (!this.#chalk) { + let level = chalk.level + if (!this.color) { + level = 0 + } + this.#chalk = new chalk.Instance({ level }) + } + return this.#chalk + } + get logColor () { return this.flatOptions.logColor } diff --git a/test/fixtures/mock-npm.js b/test/fixtures/mock-npm.js index 4263dc8fbedc3..c9701ebc23794 100644 --- a/test/fixtures/mock-npm.js +++ b/test/fixtures/mock-npm.js @@ -132,7 +132,9 @@ const LoadMockNpm = async (t, { }) const npm = init ? new Npm() : null - t.teardown(() => npm && npm.unload()) + t.teardown(() => { + npm && npm.unload() + }) if (load) { await npm.load() From 21b823edf7b3095ce1f53da7befda2b41296afe4 Mon Sep 17 00:00:00 2001 From: nlf Date: Tue, 3 May 2022 10:52:56 -0700 Subject: [PATCH 112/406] chore(test): add lib/npm.js to coverage map for all commands --- test/coverage-map.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/coverage-map.js b/test/coverage-map.js index 0ea9098186021..9a289b6489e3e 100644 --- a/test/coverage-map.js +++ b/test/coverage-map.js @@ -12,6 +12,7 @@ const coverageMap = (filename) => { if (/^test\/lib\/commands/.test(filename) || filename === 'test/lib/npm.js') { return [ filename.replace(/^test\//, ''), + 'lib/npm.js', 'lib/base-command.js', 'lib/exec/get-workspace-location-msg.js', ] From 2bd5d7b24f05d438938466adcea35ecfed310871 Mon Sep 17 00:00:00 2001 From: nlf Date: Tue, 3 May 2022 11:50:27 -0700 Subject: [PATCH 113/406] chore: gitignore __pycache__ directories in node_modules (#4842) --- node_modules/.gitignore | 1 + scripts/bundle-and-gitignore-deps.js | 1 + 2 files changed, 2 insertions(+) diff --git a/node_modules/.gitignore b/node_modules/.gitignore index 9b34c08077c99..2133d6edeaa88 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -5,6 +5,7 @@ CHANGELOG* changelog* README* readme* +__pycache__ .editorconfig .idea/ .npmignore diff --git a/scripts/bundle-and-gitignore-deps.js b/scripts/bundle-and-gitignore-deps.js index 96c1419e21807..93d8d89617eb4 100644 --- a/scripts/bundle-and-gitignore-deps.js +++ b/scripts/bundle-and-gitignore-deps.js @@ -33,6 +33,7 @@ CHANGELOG* changelog* README* readme* +__pycache__ .editorconfig .idea/ .npmignore From 62af3a1dc003cf23c563d18437be81f61e65cb49 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 3 May 2022 13:42:22 -0700 Subject: [PATCH 114/406] feat: make npm owner workspace aware (#4835) --- docs/content/commands/npm-owner.md | 46 +++++ lib/commands/owner.js | 51 +++-- .../test/lib/load-all-commands.js.test.cjs | 2 + .../test/lib/utils/npm-usage.js.test.cjs | 2 + test/lib/commands/owner.js | 189 ++++++++++++++++++ test/lib/npm.js | 2 +- 6 files changed, 277 insertions(+), 15 deletions(-) diff --git a/docs/content/commands/npm-owner.md b/docs/content/commands/npm-owner.md index 0779984e19a9d..72dfe6a22d01b 100644 --- a/docs/content/commands/npm-owner.md +++ b/docs/content/commands/npm-owner.md @@ -73,6 +73,52 @@ password, npm will prompt on the command line for one. +#### `workspace` + +* Default: +* Type: String (can be set multiple times) + +Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option. + +Valid values for the `workspace` config are either: + +* Workspace names +* Path to a workspace directory +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) + +When set for the `npm init` command, this may be set to the folder of a +workspace which does not yet exist, to create the folder and set it up as a +brand new workspace within the project. + +This value is not exported to the environment for child processes. + + + + +#### `workspaces` + +* Default: null +* Type: null or Boolean + +Set to true to run the command in the context of **all** configured +workspaces. + +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + +This value is not exported to the environment for child processes. + + + + ### See Also diff --git a/lib/commands/owner.js b/lib/commands/owner.js index 285b06be8e5fe..9338b22a5e857 100644 --- a/lib/commands/owner.js +++ b/lib/commands/owner.js @@ -22,6 +22,8 @@ class Owner extends BaseCommand { static params = [ 'registry', 'otp', + 'workspace', + 'workspaces', ] static usage = [ @@ -69,22 +71,43 @@ class Owner extends BaseCommand { } async exec ([action, ...args]) { - switch (action) { - case 'ls': - case 'list': - return this.ls(args[0]) - case 'add': - return this.changeOwners(args[0], args[1], 'add') - case 'rm': - case 'remove': - return this.changeOwners(args[0], args[1], 'rm') - default: + if (action === 'ls' || action === 'list') { + await this.ls(args[0]) + } else if (action === 'add') { + await this.changeOwners(args[0], args[1], 'add') + } else if (action === 'rm' || action === 'remove') { + await this.changeOwners(args[0], args[1], 'rm') + } else { + throw this.usageError() + } + } + + async execWorkspaces ([action, ...args], filters) { + await this.setWorkspaces(filters) + // ls pkg or owner add/rm package + if ((action === 'ls' && args.length > 0) || args.length > 1) { + const implicitWorkspaces = this.npm.config.get('workspace', 'default') + if (implicitWorkspaces.length === 0) { + log.warn(`Ignoring specified workspace(s)`) + } + return this.exec([action, ...args]) + } + + for (const [name] of this.workspaces) { + if (action === 'ls' || action === 'list') { + await this.ls(name) + } else if (action === 'add') { + await this.changeOwners(args[0], name, 'add') + } else if (action === 'rm' || action === 'remove') { + await this.changeOwners(args[0], name, 'rm') + } else { throw this.usageError() + } } } async ls (pkg) { - pkg = await this.getPkg(pkg) + pkg = await this.getPkg(this.npm.prefix, pkg) const spec = npa(pkg) try { @@ -101,12 +124,12 @@ class Owner extends BaseCommand { } } - async getPkg (pkg) { + async getPkg (prefix, pkg) { if (!pkg) { if (this.npm.config.get('global')) { throw this.usageError() } - const { name } = await readJson(resolve(this.npm.prefix, 'package.json')) + const { name } = await readJson(resolve(prefix, 'package.json')) if (!name) { throw this.usageError() } @@ -121,7 +144,7 @@ class Owner extends BaseCommand { throw this.usageError() } - pkg = await this.getPkg(pkg) + pkg = await this.getPkg(this.npm.prefix, pkg) log.verbose(`owner ${addOrRm}`, '%s to %s', user, pkg) const spec = npa(pkg) diff --git a/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/tap-snapshots/test/lib/load-all-commands.js.test.cjs index 37349cbe01e7d..eccb06580d9f9 100644 --- a/tap-snapshots/test/lib/load-all-commands.js.test.cjs +++ b/tap-snapshots/test/lib/load-all-commands.js.test.cjs @@ -596,6 +596,8 @@ npm owner ls [<@scope>/] Options: [--registry ] [--otp ] +[-w|--workspace [-w|--workspace ...]] +[-ws|--workspaces] alias: author diff --git a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs index eb71ced8d73b5..d7ec4953d6ab3 100644 --- a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs +++ b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs @@ -664,6 +664,8 @@ All commands: Options: [--registry ] [--otp ] + [-w|--workspace [-w|--workspace ...]] + [-ws|--workspaces] alias: author diff --git a/test/lib/commands/owner.js b/test/lib/commands/owner.js index d80ce36fece98..800d5b96a5876 100644 --- a/test/lib/commands/owner.js +++ b/test/lib/commands/owner.js @@ -2,6 +2,7 @@ const t = require('tap') const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') const MockRegistry = require('../../fixtures/mock-registry.js') +const path = require('path') const npa = require('npm-package-arg') const packageName = '@npmcli/test-package' const spec = npa(packageName) @@ -12,6 +13,42 @@ const maintainers = [ { email: 'test-user-b@npmjs.org', name: 'test-user-b' }, ] +const workspaceFixture = { + 'package.json': JSON.stringify({ + name: packageName, + version: '1.2.3-test', + workspaces: ['workspace-a', 'workspace-b', 'workspace-c'], + }), + 'workspace-a': { + 'package.json': JSON.stringify({ + name: 'workspace-a', + version: '1.2.3-a', + }), + }, + 'workspace-b': { + 'package.json': JSON.stringify({ + name: 'workspace-b', + version: '1.2.3-n', + }), + }, + 'workspace-c': JSON.stringify({ + 'package.json': { + name: 'workspace-n', + version: '1.2.3-n', + }, + }), +} + +function registryPackage (t, registry, name) { + const mockRegistry = new MockRegistry({ tap: t, registry }) + + const manifest = mockRegistry.manifest({ + name, + packuments: [{ maintainers, version: '1.0.0' }], + }) + mockRegistry.package({ manifest }) +} + t.test('owner no args', async t => { const { npm } = await loadMockNpm(t) await t.rejects( @@ -429,6 +466,158 @@ t.test('owner rm no cwd package', async t => { ) }) +t.test('workspaces', async t => { + t.test('owner no args --workspace', async t => { + const { npm } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + }) + npm.config.set('workspace', ['workspace-a']) + await t.rejects( + npm.exec('owner', []), + { code: 'EUSAGE' }, + 'rejects with usage' + ) + }) + + t.test('owner ls implicit workspace', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + globals: ({ prefix }) => ({ + 'process.cwd': () => path.join(prefix, 'workspace-a'), + }), + }) + registryPackage(t, npm.config.get('registry'), 'workspace-a') + await npm.exec('owner', ['ls']) + t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) + }) + + t.test('owner ls explicit workspace', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + npm.config.set('workspace', ['workspace-a']) + registryPackage(t, npm.config.get('registry'), 'workspace-a') + await npm.exec('owner', ['ls']) + t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) + }) + + t.test('owner ls implicit workspace', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + globals: ({ prefix }) => ({ + 'process.cwd': () => path.join(prefix, 'workspace-a'), + }), + }) + registryPackage(t, npm.config.get('registry'), packageName) + await npm.exec('owner', ['ls', packageName]) + t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) + }) + + t.test('owner ls explicit workspace', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), + }) + npm.config.set('workspace', ['workspace-a']) + registryPackage(t, npm.config.get('registry'), packageName) + await npm.exec('owner', ['ls', packageName]) + t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) + }) + + t.test('owner add implicit workspace', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + globals: ({ prefix }) => ({ + 'process.cwd': () => path.join(prefix, 'workspace-a'), + }), + }) + const username = 'foo' + const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) + + const manifest = registry.manifest({ + name: 'workspace-a', + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.package({ manifest }) + registry.couchuser({ username }) + registry.nock.put(`/workspace-a/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: [ + ...manifest.maintainers, + { name: username, email: '' }, + ], + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['add', username]) + t.equal(joinedOutput(), `+ ${username} (workspace-a)`) + }) + + t.test('owner add --workspace', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + }) + npm.config.set('workspace', ['workspace-a']) + const username = 'foo' + const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) + + const manifest = registry.manifest({ + name: 'workspace-a', + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.package({ manifest }) + registry.couchuser({ username }) + registry.nock.put(`/workspace-a/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: [ + ...manifest.maintainers, + { name: username, email: '' }, + ], + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['add', username]) + t.equal(joinedOutput(), `+ ${username} (workspace-a)`) + }) + + t.test('owner rm --workspace', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: workspaceFixture, + globals: ({ prefix }) => ({ + 'process.cwd': () => path.join(prefix, 'workspace-a'), + }), + }) + const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) + + const username = maintainers[0].name + const manifest = registry.manifest({ + name: 'workspace-a', + packuments: [{ maintainers, version: '1.0.0' }], + }) + registry.package({ manifest }) + registry.couchuser({ username }) + registry.nock.put(`/workspace-a/-rev/${manifest._rev}`, body => { + t.match(body, { + _id: manifest._id, + _rev: manifest._rev, + maintainers: maintainers.slice(1), + }) + return true + }).reply(200, {}) + await npm.exec('owner', ['rm', username]) + t.equal(joinedOutput(), `- ${username} (workspace-a)`) + }) +}) + t.test('completion', async t => { t.test('basic commands', async t => { const { npm } = await loadMockNpm(t) diff --git a/test/lib/npm.js b/test/lib/npm.js index 1966ca9600088..566cbca20f6bf 100644 --- a/test/lib/npm.js +++ b/test/lib/npm.js @@ -620,7 +620,7 @@ t.test('implicit workspace rejection', async t => { }), }) await t.rejects( - mock.npm.exec('owner', []), + mock.npm.exec('team', []), /This command does not support workspaces/ ) }) From b9a966cf33cfa9b1e5f16c16219f63633bbe19d6 Mon Sep 17 00:00:00 2001 From: nlf Date: Tue, 3 May 2022 13:53:10 -0700 Subject: [PATCH 115/406] fix(exec): ignore packageLockOnly flag (#4843) --- lib/commands/exec.js | 3 ++ test/lib/commands/exec.js | 58 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/lib/commands/exec.js b/lib/commands/exec.js index f764cea528adb..d9a686cc9a3be 100644 --- a/lib/commands/exec.js +++ b/lib/commands/exec.js @@ -73,6 +73,9 @@ class Exec extends BaseCommand { return libexec({ ...flatOptions, + // we explicitly set packageLockOnly to false because if it's true + // when we try to install a missing package, we won't actually install it + packageLockOnly: false, args, call, localBin, diff --git a/test/lib/commands/exec.js b/test/lib/commands/exec.js index d6e598d568d5b..1117885b91731 100644 --- a/test/lib/commands/exec.js +++ b/test/lib/commands/exec.js @@ -385,6 +385,64 @@ t.test('npm exec foo, not present locally or in central loc', async t => { ]) }) +t.test('npm exec foo, packageLockOnly set to true', async t => { + const path = t.testdir() + const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') + npm.localPrefix = path + npm.config.set('package-lock-only', true) + t.teardown(() => { + npm.config.set('package-lock-only', false) + }) + + ARB_ACTUAL_TREE[path] = { + inventory: { + query () { + return new Set() + }, + }, + } + ARB_ACTUAL_TREE[installDir] = { + inventory: { + query () { + return new Set() + }, + }, + } + MANIFESTS.foo = { + name: 'foo', + version: '1.2.3', + bin: { + foo: 'foo', + }, + _from: 'foo@', + } + await exec.exec(['foo', 'one arg', 'two arg']) + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ + path, + packageLockOnly: false, + }]) + t.match(ARB_REIFY, [{ + add: ['foo@'], + legacyPeerDeps: false, + packageLockOnly: false, + }], 'need to install foo@') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [ + { + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }, + ]) +}) + t.test('npm exec foo, not present locally but in central loc', async t => { const path = t.testdir() const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') From 62faf8adba19d6ef26238887a453d013fe58ae75 Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Tue, 3 May 2022 13:57:22 -0700 Subject: [PATCH 116/406] deps: pacote@13.2.0 (#4837) --- node_modules/pacote/lib/fetcher.js | 11 +++++++++-- node_modules/pacote/lib/remote.js | 13 ++++++++----- node_modules/pacote/package.json | 6 +++--- package-lock.json | 14 +++++++------- package.json | 2 +- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/node_modules/pacote/lib/fetcher.js b/node_modules/pacote/lib/fetcher.js index 65e97e205204e..d88724c5d1973 100644 --- a/node_modules/pacote/lib/fetcher.js +++ b/node_modules/pacote/lib/fetcher.js @@ -105,8 +105,15 @@ class FetcherBase { this[_readPackageJson] = readPackageJsonFast } - // config values: npmjs (default), never - this.replaceRegistryHost = opts.replaceRegistryHost === 'never' ? 'never' : 'npmjs' + // config values: npmjs (default), never, always + // we don't want to mutate the original value + if (opts.replaceRegistryHost !== 'never' + && opts.replaceRegistryHost !== 'always' + ) { + this.replaceRegistryHost = 'npmjs' + } else { + this.replaceRegistryHost = opts.replaceRegistryHost + } this.defaultTag = opts.defaultTag || 'latest' this.registry = removeTrailingSlashes(opts.registry || 'https://registry.npmjs.org') diff --git a/node_modules/pacote/lib/remote.js b/node_modules/pacote/lib/remote.js index 3404ea9474944..14e687805d47a 100644 --- a/node_modules/pacote/lib/remote.js +++ b/node_modules/pacote/lib/remote.js @@ -5,7 +5,7 @@ const pacoteVersion = require('../package.json').version const fetch = require('npm-registry-fetch') const Minipass = require('minipass') // The default registry URL is a string of great magic. -const magic = /^https?:\/\/registry\.npmjs\.org\// +const magicHost = 'https://registry.npmjs.org' const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches') const _headers = Symbol('_headers') @@ -13,10 +13,13 @@ class RemoteFetcher extends Fetcher { constructor (spec, opts) { super(spec, opts) this.resolved = this.spec.fetchSpec - if (this.replaceRegistryHost === 'npmjs' - && magic.test(this.resolved) - && !magic.test(this.registry + '/')) { - this.resolved = this.resolved.replace(magic, this.registry + '/') + const resolvedURL = new URL(this.resolved) + if ( + (this.replaceRegistryHost === 'npmjs' + && resolvedURL.origin === magicHost) + || this.replaceRegistryHost === 'always' + ) { + this.resolved = new URL(resolvedURL.pathname, this.registry).href } // nam is a fermented pork sausage that is good to eat diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json index af8166d4ea19e..a978852b2db91 100644 --- a/node_modules/pacote/package.json +++ b/node_modules/pacote/package.json @@ -1,6 +1,6 @@ { "name": "pacote", - "version": "13.1.1", + "version": "13.2.0", "description": "JavaScript package downloader", "author": "GitHub Inc.", "bin": { @@ -26,7 +26,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/template-oss": "3.4.2", "hosted-git-info": "^5.0.0", "mutate-fs": "^2.1.1", "nock": "^13.2.4", @@ -74,7 +74,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2", + "version": "3.4.2", "windowsCI": false } } diff --git a/package-lock.json b/package-lock.json index 7babdc84abc78..89f3515d7b3bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -138,7 +138,7 @@ "npm-user-validate": "^1.0.1", "npmlog": "^6.0.2", "opener": "^1.5.2", - "pacote": "^13.1.1", + "pacote": "^13.2.0", "parse-conflict-json": "^2.0.2", "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", @@ -5563,9 +5563,9 @@ } }, "node_modules/pacote": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.1.1.tgz", - "integrity": "sha512-MTT3k1OhUo+IpvoHGp25OwsRU0L+kJQM236OCywxvY4OIJ/YfloNW2/Yc3HMASH10BkfZaGMVK/pxybB7fWcLw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.2.0.tgz", + "integrity": "sha512-IT4/xHT8eLi4cJdKSGCuqooWp2YwRP5OgrQypbBlLG8Ubzw+h7s57QbrA2SegQcdGefD81ZvuI+aL0JlfFcPCA==", "inBundle": true, "dependencies": { "@npmcli/git": "^3.0.0", @@ -13898,9 +13898,9 @@ } }, "pacote": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.1.1.tgz", - "integrity": "sha512-MTT3k1OhUo+IpvoHGp25OwsRU0L+kJQM236OCywxvY4OIJ/YfloNW2/Yc3HMASH10BkfZaGMVK/pxybB7fWcLw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.2.0.tgz", + "integrity": "sha512-IT4/xHT8eLi4cJdKSGCuqooWp2YwRP5OgrQypbBlLG8Ubzw+h7s57QbrA2SegQcdGefD81ZvuI+aL0JlfFcPCA==", "requires": { "@npmcli/git": "^3.0.0", "@npmcli/installed-package-contents": "^1.0.7", diff --git a/package.json b/package.json index e1f683219311a..14c1ceb6963dc 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "npm-user-validate": "^1.0.1", "npmlog": "^6.0.2", "opener": "^1.5.2", - "pacote": "^13.1.1", + "pacote": "^13.2.0", "parse-conflict-json": "^2.0.2", "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", From 4ff7d3d993533d6407fa69c5e6dd00f95090a280 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 3 May 2022 14:09:46 -0700 Subject: [PATCH 117/406] deps: cacache@16.0.7 (#4816) --- node_modules/cacache/lib/content/read.js | 9 ++-- node_modules/cacache/lib/content/write.js | 65 +++++++++++------------ node_modules/cacache/lib/entry-index.js | 8 ++- node_modules/cacache/lib/get.js | 49 +++++------------ node_modules/cacache/lib/put.js | 26 ++++----- node_modules/cacache/lib/util/disposer.js | 31 ----------- node_modules/cacache/package.json | 7 +-- package-lock.json | 14 ++--- package.json | 2 +- 9 files changed, 75 insertions(+), 136 deletions(-) delete mode 100644 node_modules/cacache/lib/util/disposer.js diff --git a/node_modules/cacache/lib/content/read.js b/node_modules/cacache/lib/content/read.js index 8bffb2af83cab..0aeb454725bd0 100644 --- a/node_modules/cacache/lib/content/read.js +++ b/node_modules/cacache/lib/content/read.js @@ -10,6 +10,7 @@ const Pipeline = require('minipass-pipeline') const lstat = util.promisify(fs.lstat) const readFile = util.promisify(fs.readFile) +const copyFile = util.promisify(fs.copyFile) module.exports = read @@ -90,12 +91,8 @@ function readStream (cache, integrity, opts = {}) { return stream } -let copyFile -if (fs.copyFile) { - module.exports.copy = copy - module.exports.copy.sync = copySync - copyFile = util.promisify(fs.copyFile) -} +module.exports.copy = copy +module.exports.copy.sync = copySync function copy (cache, integrity, dest) { return withContentSri(cache, integrity, (cpath, sri) => { diff --git a/node_modules/cacache/lib/content/write.js b/node_modules/cacache/lib/content/write.js index a71e81ad5e150..b0aa18c12ba78 100644 --- a/node_modules/cacache/lib/content/write.js +++ b/node_modules/cacache/lib/content/write.js @@ -13,34 +13,37 @@ const path = require('path') const rimraf = util.promisify(require('rimraf')) const ssri = require('ssri') const uniqueFilename = require('unique-filename') -const { disposer } = require('./../util/disposer') const fsm = require('fs-minipass') const writeFile = util.promisify(fs.writeFile) module.exports = write -function write (cache, data, opts = {}) { +async function write (cache, data, opts = {}) { const { algorithms, size, integrity } = opts if (algorithms && algorithms.length > 1) { throw new Error('opts.algorithms only supports a single algorithm for now') } if (typeof size === 'number' && data.length !== size) { - return Promise.reject(sizeError(size, data.length)) + throw sizeError(size, data.length) } const sri = ssri.fromData(data, algorithms ? { algorithms } : {}) if (integrity && !ssri.checkData(data, integrity, opts)) { - return Promise.reject(checksumError(integrity, sri)) + throw checksumError(integrity, sri) } - return disposer(makeTmp(cache, opts), makeTmpDisposer, - (tmp) => { - return writeFile(tmp.target, data, { flag: 'wx' }) - .then(() => moveToDestination(tmp, cache, sri, opts)) - }) - .then(() => ({ integrity: sri, size: data.length })) + const tmp = await makeTmp(cache, opts) + try { + await writeFile(tmp.target, data, { flag: 'wx' }) + await moveToDestination(tmp, cache, sri, opts) + return { integrity: sri, size: data.length } + } finally { + if (!tmp.moved) { + await rimraf(tmp.target) + } + } } module.exports.stream = writeStream @@ -94,18 +97,22 @@ function writeStream (cache, opts = {}) { return new CacacheWriteStream(cache, opts) } -function handleContent (inputStream, cache, opts) { - return disposer(makeTmp(cache, opts), makeTmpDisposer, (tmp) => { - return pipeToTmp(inputStream, cache, tmp.target, opts) - .then((res) => { - return moveToDestination( - tmp, - cache, - res.integrity, - opts - ).then(() => res) - }) - }) +async function handleContent (inputStream, cache, opts) { + const tmp = await makeTmp(cache, opts) + try { + const res = await pipeToTmp(inputStream, cache, tmp.target, opts) + await moveToDestination( + tmp, + cache, + res.integrity, + opts + ) + return res + } finally { + if (!tmp.moved) { + await rimraf(tmp.target) + } + } } function pipeToTmp (inputStream, cache, tmpTarget, opts) { @@ -136,11 +143,7 @@ function pipeToTmp (inputStream, cache, tmpTarget, opts) { outStream ) - return pipeline.promise() - .then(() => ({ integrity, size })) - .catch(er => rimraf(tmpTarget).then(() => { - throw er - })) + return pipeline.promise().then(() => ({ integrity, size })) } function makeTmp (cache, opts) { @@ -151,14 +154,6 @@ function makeTmp (cache, opts) { })) } -function makeTmpDisposer (tmp) { - if (tmp.moved) { - return Promise.resolve() - } - - return rimraf(tmp.target) -} - function moveToDestination (tmp, cache, sri, opts) { const destination = contentPath(cache, sri) const destDir = path.dirname(destination) diff --git a/node_modules/cacache/lib/entry-index.js b/node_modules/cacache/lib/entry-index.js index 426778b850963..9d4485624acbc 100644 --- a/node_modules/cacache/lib/entry-index.js +++ b/node_modules/cacache/lib/entry-index.js @@ -8,7 +8,6 @@ const path = require('path') const ssri = require('ssri') const uniqueFilename = require('unique-filename') -const { disposer } = require('./util/disposer') const contentPath = require('./content/path') const fixOwner = require('./util/fix-owner') const hashToSegments = require('./util/hash-to-segments') @@ -102,7 +101,12 @@ async function compact (cache, key, matchFn, opts = {}) { } // write the file atomically - await disposer(setup(), teardown, write) + const tmp = await setup() + try { + await write(tmp) + } finally { + await teardown(tmp) + } // we reverse the list we generated such that the newest // entries come first in order to make looping through them easier diff --git a/node_modules/cacache/lib/get.js b/node_modules/cacache/lib/get.js index d9d4bf4c6416f..58f357b1da3d1 100644 --- a/node_modules/cacache/lib/get.js +++ b/node_modules/cacache/lib/get.js @@ -3,15 +3,11 @@ const Collect = require('minipass-collect') const Minipass = require('minipass') const Pipeline = require('minipass-pipeline') -const fs = require('fs') -const util = require('util') const index = require('./entry-index') const memo = require('./memoization') const read = require('./content/read') -const writeFile = util.promisify(fs.writeFile) - function getData (cache, key, opts = {}) { const { integrity, memoize, size } = opts const memoized = memo.get(cache, key, opts) @@ -209,42 +205,25 @@ function info (cache, key, opts = {}) { module.exports.info = info function copy (cache, key, dest, opts = {}) { - if (read.copy) { - return index.find(cache, key, opts).then((entry) => { - if (!entry) { - throw new index.NotFoundError(cache, key) - } - return read.copy(cache, entry.integrity, dest, opts) - .then(() => { - return { - metadata: entry.metadata, - size: entry.size, - integrity: entry.integrity, - } - }) - }) - } - - return getData(cache, key, opts).then((res) => { - return writeFile(dest, res.data).then(() => { - return { - metadata: res.metadata, - size: res.size, - integrity: res.integrity, - } - }) + return index.find(cache, key, opts).then((entry) => { + if (!entry) { + throw new index.NotFoundError(cache, key) + } + return read.copy(cache, entry.integrity, dest, opts) + .then(() => { + return { + metadata: entry.metadata, + size: entry.size, + integrity: entry.integrity, + } + }) }) } + module.exports.copy = copy function copyByDigest (cache, key, dest, opts = {}) { - if (read.copy) { - return read.copy(cache, key, dest, opts).then(() => key) - } - - return getDataByDigest(cache, key, opts).then((res) => { - return writeFile(dest, res).then(() => key) - }) + return read.copy(cache, key, dest, opts).then(() => key) } module.exports.copy.byDigest = copyByDigest diff --git a/node_modules/cacache/lib/put.js b/node_modules/cacache/lib/put.js index d6904fa301272..eed51874f9f64 100644 --- a/node_modules/cacache/lib/put.js +++ b/node_modules/cacache/lib/put.js @@ -37,6 +37,7 @@ function putStream (cache, key, opts = {}) { opts = putOpts(opts) let integrity let size + let error let memoData const pipeline = new Pipeline() @@ -58,6 +59,9 @@ function putStream (cache, key, opts = {}) { .on('size', (s) => { size = s }) + .on('error', (err) => { + error = err + }) pipeline.push(contentStream) @@ -65,21 +69,17 @@ function putStream (cache, key, opts = {}) { // and memoize if we're doing that pipeline.push(new Flush({ flush () { - return index - .insert(cache, key, integrity, { ...opts, size }) - .then((entry) => { - if (memoize && memoData) { - memo.put(cache, entry, memoData, opts) - } - - if (integrity) { + if (!error) { + return index + .insert(cache, key, integrity, { ...opts, size }) + .then((entry) => { + if (memoize && memoData) { + memo.put(cache, entry, memoData, opts) + } pipeline.emit('integrity', integrity) - } - - if (size) { pipeline.emit('size', size) - } - }) + }) + } }, })) diff --git a/node_modules/cacache/lib/util/disposer.js b/node_modules/cacache/lib/util/disposer.js deleted file mode 100644 index 52d7d3edda7d5..0000000000000 --- a/node_modules/cacache/lib/util/disposer.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' - -module.exports.disposer = disposer - -function disposer (creatorFn, disposerFn, fn) { - const runDisposer = (resource, result, shouldThrow = false) => { - return disposerFn(resource) - .then( - // disposer resolved, do something with original fn's promise - () => { - if (shouldThrow) { - throw result - } - - return result - }, - // Disposer fn failed, crash process - (err) => { - throw err - // Or process.exit? - }) - } - - return creatorFn - .then((resource) => { - // fn(resource) can throw, so wrap in a promise here - return Promise.resolve().then(() => fn(resource)) - .then((result) => runDisposer(resource, result)) - .catch((err) => runDisposer(resource, err, true)) - }) -} diff --git a/node_modules/cacache/package.json b/node_modules/cacache/package.json index 9eb646df76b40..cd7e4de5e0cba 100644 --- a/node_modules/cacache/package.json +++ b/node_modules/cacache/package.json @@ -1,6 +1,6 @@ { "name": "cacache", - "version": "16.0.6", + "version": "16.0.7", "cache-version": { "content": "2", "index": "5" @@ -12,7 +12,6 @@ "lib/" ], "scripts": { - "benchmarks": "node test/benchmarks", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", @@ -71,10 +70,6 @@ "devDependencies": { "@npmcli/eslint-config": "^3.0.1", "@npmcli/template-oss": "3.4.1", - "benchmark": "^2.1.4", - "chalk": "^4.1.2", - "require-inject": "^1.4.4", - "tacks": "^1.3.0", "tap": "^16.0.0" }, "tap": { diff --git a/package-lock.json b/package-lock.json index 89f3515d7b3bb..f184e3a58a22d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "archy": "~1.0.0", - "cacache": "^16.0.6", + "cacache": "^16.0.7", "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", @@ -1597,9 +1597,9 @@ } }, "node_modules/cacache": { - "version": "16.0.6", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.6.tgz", - "integrity": "sha512-9a/MLxGaw3LEGes0HaPez2RgZWDV6X0jrgChsuxfEh8xoDoYGxaGrkMe7Dlyjrb655tA/b8fX0qlUg6Ii5MBvw==", + "version": "16.0.7", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.7.tgz", + "integrity": "sha512-a4zfQpp5vm4Ipdvbj+ZrPonikRhm6WBEd4zT1Yc1DXsmAxrPgDwWBLF/u/wTVXSFPIgOJ1U3ghSa2Xm4s3h28w==", "inBundle": true, "dependencies": { "@npmcli/fs": "^2.1.0", @@ -11253,9 +11253,9 @@ } }, "cacache": { - "version": "16.0.6", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.6.tgz", - "integrity": "sha512-9a/MLxGaw3LEGes0HaPez2RgZWDV6X0jrgChsuxfEh8xoDoYGxaGrkMe7Dlyjrb655tA/b8fX0qlUg6Ii5MBvw==", + "version": "16.0.7", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.7.tgz", + "integrity": "sha512-a4zfQpp5vm4Ipdvbj+ZrPonikRhm6WBEd4zT1Yc1DXsmAxrPgDwWBLF/u/wTVXSFPIgOJ1U3ghSa2Xm4s3h28w==", "requires": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", diff --git a/package.json b/package.json index 14c1ceb6963dc..90090e758cf23 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@npmcli/run-script": "^3.0.1", "abbrev": "~1.1.1", "archy": "~1.0.0", - "cacache": "^16.0.6", + "cacache": "^16.0.7", "chalk": "^4.1.2", "chownr": "^2.0.0", "cli-columns": "^4.0.0", From 29d301a3717e89ede6fd3e35019e5dd81c519ac3 Mon Sep 17 00:00:00 2001 From: nlf Date: Tue, 3 May 2022 16:18:44 -0700 Subject: [PATCH 118/406] chore: run make docs in postsnap script instead of make mandocs (#4848) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 90090e758cf23..96b9321ec66fb 100644 --- a/package.json +++ b/package.json @@ -213,7 +213,7 @@ "test": "tap", "test-all": "npm run test --if-present --workspaces --include-workspace-root", "snap": "tap", - "postsnap": "make -s mandocs", + "postsnap": "make -s docs", "test:nocleanup": "NO_TEST_CLEANUP=1 npm run test --", "sudotest": "sudo npm run test --", "sudotest:nocleanup": "sudo NO_TEST_CLEANUP=1 npm run test --", From 8fd7eec8ef76224dd8a9874a1044a0cc8f5e1c49 Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 3 May 2022 16:43:44 -0700 Subject: [PATCH 119/406] docs: remove incorrect v6 auto prune info (#4845) As of npm@7, extraneous modules are always auto pruned --- docs/content/commands/npm-dedupe.md | 4 ---- docs/content/commands/npm-find-dupes.md | 4 ---- docs/content/commands/npm-install-test.md | 4 ---- docs/content/commands/npm-install.md | 4 ---- docs/content/commands/npm-link.md | 4 ---- docs/content/commands/npm-update.md | 4 ---- docs/content/using-npm/config.md | 4 ---- lib/utils/config/definitions.js | 4 ---- tap-snapshots/test/lib/utils/config/definitions.js.test.cjs | 4 ---- tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs | 4 ---- 10 files changed, 40 deletions(-) diff --git a/docs/content/commands/npm-dedupe.md b/docs/content/commands/npm-dedupe.md index f816b99433581..570e018342f27 100644 --- a/docs/content/commands/npm-dedupe.md +++ b/docs/content/commands/npm-dedupe.md @@ -147,10 +147,6 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use `npm prune`. - This configuration does not affect `npm ci`. diff --git a/docs/content/commands/npm-find-dupes.md b/docs/content/commands/npm-find-dupes.md index a92c57bd7e183..4da6c296c6bf6 100644 --- a/docs/content/commands/npm-find-dupes.md +++ b/docs/content/commands/npm-find-dupes.md @@ -87,10 +87,6 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use `npm prune`. - This configuration does not affect `npm ci`. diff --git a/docs/content/commands/npm-install-test.md b/docs/content/commands/npm-install-test.md index 931ff050718e1..3dd860ea5c6f6 100644 --- a/docs/content/commands/npm-install-test.md +++ b/docs/content/commands/npm-install-test.md @@ -162,10 +162,6 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use `npm prune`. - This configuration does not affect `npm ci`. diff --git a/docs/content/commands/npm-install.md b/docs/content/commands/npm-install.md index 5cf3b0326d72f..445772f0353a1 100644 --- a/docs/content/commands/npm-install.md +++ b/docs/content/commands/npm-install.md @@ -552,10 +552,6 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use `npm prune`. - This configuration does not affect `npm ci`. diff --git a/docs/content/commands/npm-link.md b/docs/content/commands/npm-link.md index fb2b23921b044..975c807c38b34 100644 --- a/docs/content/commands/npm-link.md +++ b/docs/content/commands/npm-link.md @@ -224,10 +224,6 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use `npm prune`. - This configuration does not affect `npm ci`. diff --git a/docs/content/commands/npm-update.md b/docs/content/commands/npm-update.md index 394773214995c..421d04ca3dc58 100644 --- a/docs/content/commands/npm-update.md +++ b/docs/content/commands/npm-update.md @@ -280,10 +280,6 @@ this warning is treated as a failure. If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use `npm prune`. - This configuration does not affect `npm ci`. diff --git a/docs/content/using-npm/config.md b/docs/content/using-npm/config.md index ba79dd505a88e..4dc2829825d60 100644 --- a/docs/content/using-npm/config.md +++ b/docs/content/using-npm/config.md @@ -1219,10 +1219,6 @@ The package to install for [`npm exec`](/commands/npm-exec) If set to false, then ignore `package-lock.json` files when installing. This will also prevent _writing_ `package-lock.json` if `save` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use `npm prune`. - This configuration does not affect `npm ci`. diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index 4a1f971d85436..6f1b1a7244a50 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -1448,10 +1448,6 @@ define('package-lock', { This will also prevent _writing_ \`package-lock.json\` if \`save\` is true. - When package package-locks are disabled, automatic pruning of extraneous - modules will also be disabled. To remove extraneous modules with - package-locks disabled use \`npm prune\`. - This configuration does not affect \`npm ci\`. `, flatten: (key, obj, flatOptions) => { diff --git a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs index ff00f9a0f9b3d..42db6ce030b53 100644 --- a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs @@ -1302,10 +1302,6 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for packa If set to false, then ignore \`package-lock.json\` files when installing. This will also prevent _writing_ \`package-lock.json\` if \`save\` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use \`npm prune\`. - This configuration does not affect \`npm ci\`. ` diff --git a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs index 6740b94c772c8..d0ce3a26f764f 100644 --- a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs @@ -1093,10 +1093,6 @@ The package to install for [\`npm exec\`](/commands/npm-exec) If set to false, then ignore \`package-lock.json\` files when installing. This will also prevent _writing_ \`package-lock.json\` if \`save\` is true. -When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use \`npm prune\`. - This configuration does not affect \`npm ci\`. From 5f59f803d1c6cdc690d4d7016990ca0e20c6706f Mon Sep 17 00:00:00 2001 From: Gar Date: Tue, 3 May 2022 16:55:09 -0700 Subject: [PATCH 120/406] docs: show complex object interactions in npm pkg (#4847) --- docs/content/commands/npm-pkg.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/content/commands/npm-pkg.md b/docs/content/commands/npm-pkg.md index 576e1335efbba..deff7e82c694d 100644 --- a/docs/content/commands/npm-pkg.md +++ b/docs/content/commands/npm-pkg.md @@ -76,6 +76,14 @@ Returned values are always in **json** format. npm pkg get contributors[0].email ``` + For complex fields you can also name a property in square brackets + to specifically select a child field. This is especially helpful + with the exports object: + + ```bash + npm pkg get "exports[.].require" + ``` + * `npm pkg set =` Sets a `value` in your `package.json` based on the `field` value. When From e2e9c8152e2d2adcb7e2dfc90f61353d50e433ba Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 4 May 2022 09:14:11 -0700 Subject: [PATCH 121/406] deps: pacote@13.3.0 (#4852) * add _signatures to manifest --- node_modules/pacote/lib/registry.js | 3 +++ node_modules/pacote/package.json | 8 ++++---- package-lock.json | 14 +++++++------- package.json | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/node_modules/pacote/lib/registry.js b/node_modules/pacote/lib/registry.js index b4f890d310dfa..e8ca16f596d6f 100644 --- a/node_modules/pacote/lib/registry.js +++ b/node_modules/pacote/lib/registry.js @@ -165,6 +165,9 @@ class RegistryFetcher extends Fetcher { } if (this.integrity) { mani._integrity = String(this.integrity) + if (dist.signatures) { + mani._signatures = dist.signatures + } } this.package = rpj.normalize(mani) return this.package diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json index a978852b2db91..2f4323c4414ed 100644 --- a/node_modules/pacote/package.json +++ b/node_modules/pacote/package.json @@ -1,6 +1,6 @@ { "name": "pacote", - "version": "13.2.0", + "version": "13.3.0", "description": "JavaScript package downloader", "author": "GitHub Inc.", "bin": { @@ -26,11 +26,11 @@ }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.4.2", + "@npmcli/template-oss": "3.4.3", "hosted-git-info": "^5.0.0", "mutate-fs": "^2.1.1", "nock": "^13.2.4", - "npm-registry-mock": "^1.3.1", + "npm-registry-mock": "^1.3.2", "tap": "^16.0.1" }, "files": [ @@ -74,7 +74,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.4.2", + "version": "3.4.3", "windowsCI": false } } diff --git a/package-lock.json b/package-lock.json index f184e3a58a22d..e9ce783635057 100644 --- a/package-lock.json +++ b/package-lock.json @@ -138,7 +138,7 @@ "npm-user-validate": "^1.0.1", "npmlog": "^6.0.2", "opener": "^1.5.2", - "pacote": "^13.2.0", + "pacote": "^13.3.0", "parse-conflict-json": "^2.0.2", "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", @@ -5563,9 +5563,9 @@ } }, "node_modules/pacote": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.2.0.tgz", - "integrity": "sha512-IT4/xHT8eLi4cJdKSGCuqooWp2YwRP5OgrQypbBlLG8Ubzw+h7s57QbrA2SegQcdGefD81ZvuI+aL0JlfFcPCA==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.3.0.tgz", + "integrity": "sha512-auhJAUlfC2TALo6I0s1vFoPvVFgWGx+uz/PnIojTTgkGwlK3Np8sGJ0ghfFhiuzJXTZoTycMLk8uLskdntPbDw==", "inBundle": true, "dependencies": { "@npmcli/git": "^3.0.0", @@ -13898,9 +13898,9 @@ } }, "pacote": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.2.0.tgz", - "integrity": "sha512-IT4/xHT8eLi4cJdKSGCuqooWp2YwRP5OgrQypbBlLG8Ubzw+h7s57QbrA2SegQcdGefD81ZvuI+aL0JlfFcPCA==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.3.0.tgz", + "integrity": "sha512-auhJAUlfC2TALo6I0s1vFoPvVFgWGx+uz/PnIojTTgkGwlK3Np8sGJ0ghfFhiuzJXTZoTycMLk8uLskdntPbDw==", "requires": { "@npmcli/git": "^3.0.0", "@npmcli/installed-package-contents": "^1.0.7", diff --git a/package.json b/package.json index 96b9321ec66fb..dcd813ca49e5a 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "npm-user-validate": "^1.0.1", "npmlog": "^6.0.2", "opener": "^1.5.2", - "pacote": "^13.2.0", + "pacote": "^13.3.0", "parse-conflict-json": "^2.0.2", "proc-log": "^2.0.1", "qrcode-terminal": "^0.12.0", From 305bc2e8fd9dc7e167651c519aa85e42abdabe5b Mon Sep 17 00:00:00 2001 From: nlf Date: Wed, 4 May 2022 09:30:39 -0700 Subject: [PATCH 122/406] chore: fix url in release-manager script (#4853) --- scripts/release-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release-manager.js b/scripts/release-manager.js index 8622ac9982c17..8313692adfdc4 100644 --- a/scripts/release-manager.js +++ b/scripts/release-manager.js @@ -169,7 +169,7 @@ const parseArgs = raw => { // look for that heading level with a match for the portion after section: '### .*cli.*', release: - 'https://raw.githubusercontent.com/wiki/npm/cli/Release-Process.md', + 'https://raw.githubusercontent.com/wiki/npm/cli/Release-Process-(v8).md', } const replacements = {} From ee28900ba7e5c614c9b5846781bd615dafa16d05 Mon Sep 17 00:00:00 2001 From: nlf Date: Wed, 4 May 2022 09:36:55 -0700 Subject: [PATCH 123/406] chore: changelog for v8.9.0 --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e3b4f6dbeb99..b6fb1962e84af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## v8.9.0 (2022-05-04) + +### Features + + * [`62af3a1`](https://github.com/npm/cli/commit/62af3a1dc003cf23c563d18437be81f61e65cb49) [#4835](https://github.com/npm/cli/pull/4835) feat: make npm owner workspace aware ([@wraithgar](https://github.com/wraithgar)) + +### Bug Fixes + + * [`d654e7e`](https://github.com/npm/cli/commit/d654e7e9146f123a9806cfd9a17150eb1f6075a4) [#4781](https://github.com/npm/cli/pull/4781) fix: start consolidating color output ([@wraithgar](https://github.com/wraithgar)) + * [`b9a966c`](https://github.com/npm/cli/commit/b9a966cf33cfa9b1e5f16c16219f63633bbe19d6) [#4843](https://github.com/npm/cli/pull/4843) fix(exec): ignore packageLockOnly flag ([@nlf](https://github.com/nlf)) + +### Documentation + + * [`8fd7eec`](https://github.com/npm/cli/commit/8fd7eec8ef76224dd8a9874a1044a0cc8f5e1c49) [#4845](https://github.com/npm/cli/pull/4845) docs: remove incorrect v6 auto prune info ([@wraithgar](https://github.com/wraithgar)) + * [`5f59f80`](https://github.com/npm/cli/commit/5f59f803d1c6cdc690d4d7016990ca0e20c6706f) [#4847](https://github.com/npm/cli/pull/4847) docs: show complex object interactions in npm pkg ([@wraithgar](https://github.com/wraithgar)) + +### Dependencies + + * [`62faf8a`](https://github.com/npm/cli/commit/62faf8adba19d6ef26238887a453d013fe58ae75) [#4837](https://github.com/npm/cli/pull/4837) deps: `pacote@13.2.0` + * [`4ff7d3d`](https://github.com/npm/cli/commit/4ff7d3d993533d6407fa69c5e6dd00f95090a280) [#4816](https://github.com/npm/cli/pull/4816) deps: `cacache@16.0.7` + * [`e2e9c81`](https://github.com/npm/cli/commit/e2e9c8152e2d2adcb7e2dfc90f61353d50e433ba) [#4852](https://github.com/npm/cli/pull/4852) deps: `pacote@13.3.0` + ## v8.8.0 (2022-04-27) ### Features From 8e7ea9b61afe37de6017ff77c142ef3abdff6bec Mon Sep 17 00:00:00 2001 From: nlf Date: Wed, 4 May 2022 09:37:54 -0700 Subject: [PATCH 124/406] 8.9.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 e9ce783635057..8542dee4f7f2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "npm", - "version": "8.8.0", + "version": "8.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "npm", - "version": "8.8.0", + "version": "8.9.0", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", diff --git a/package.json b/package.json index dcd813ca49e5a..d3e55ad623a43 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "8.8.0", + "version": "8.9.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ From 48d2db6037487fd782f67bbcd2cf12e009ece17b Mon Sep 17 00:00:00 2001 From: Gar Date: Sat, 7 May 2022 09:11:18 -0700 Subject: [PATCH 125/406] fix: remove test coverage map (#4862) Turns out there were three files that still had no test coverage because of the combination of the mocks in tests and the coverage map. Removing the map altogether exposed them. This PR removes the coverage map and fixes test to cover all lines that were being missed. While adding coverage to the `npm search` codebase multiple unneeded guards and at least one bug was found (it was impossible to exclude searches based on username). These were fixed. The `npm view` tests were also refactored to use the real npm object. Finally, a small inlining of lib/utils/file-exists.js was done. --- lib/commands/completion.js | 18 +- lib/commands/search.js | 47 +- lib/commands/view.js | 3 - lib/search/package-filter.js | 43 -- lib/utils/config/definitions.js | 2 +- lib/utils/file-exists.js | 10 - lib/utils/format-bytes.js | 1 + .../format-search-stream.js} | 66 +-- lib/utils/read-package-name.js | 9 - package.json | 9 +- .../test/lib/commands/search.js.test.cjs | 130 ++++- .../test/lib/commands/view.js.test.cjs | 386 +++++++-------- test/coverage-map.js | 26 - test/fixtures/libnpmsearch-stream-result.js | 27 +- test/fixtures/mock-registry.js | 13 + test/lib/commands/search.js | 302 +++++------- test/lib/commands/view.js | 457 +++++++----------- test/lib/utils/config/definitions.js | 11 +- test/lib/utils/file-exists.js | 30 -- 19 files changed, 729 insertions(+), 861 deletions(-) delete mode 100644 lib/search/package-filter.js delete mode 100644 lib/utils/file-exists.js rename lib/{search/format-package-stream.js => utils/format-search-stream.js} (70%) delete mode 100644 lib/utils/read-package-name.js delete mode 100644 test/coverage-map.js delete mode 100644 test/lib/utils/file-exists.js diff --git a/lib/commands/completion.js b/lib/commands/completion.js index 5b7e0d355c63c..c24fb050dcb34 100644 --- a/lib/commands/completion.js +++ b/lib/commands/completion.js @@ -29,18 +29,26 @@ // as an array. // +const fs = require('@npmcli/fs') +const nopt = require('nopt') + const { definitions, shorthands } = require('../utils/config/index.js') const { aliases, cmdList, plumbing } = require('../utils/cmd-list.js') const aliasNames = Object.keys(aliases) const fullList = cmdList.concat(aliasNames).filter(c => !plumbing.includes(c)) -const nopt = require('nopt') const configNames = Object.keys(definitions) const shorthandNames = Object.keys(shorthands) const allConfs = configNames.concat(shorthandNames) const { isWindowsShell } = require('../utils/is-windows.js') -const fileExists = require('../utils/file-exists.js') +const fileExists = async (file) => { + try { + const stat = await fs.stat(file) + return stat.isFile() + } catch { + return false + } +} -const { promisify } = require('util') const BaseCommand = require('../base-command.js') class Completion extends BaseCommand { @@ -189,12 +197,10 @@ class Completion extends BaseCommand { } const dumpScript = async () => { - const fs = require('fs') - const readFile = promisify(fs.readFile) const { resolve } = require('path') const p = resolve(__dirname, '..', 'utils', 'completion.sh') - const d = (await readFile(p, 'utf8')).replace(/^#!.*?\n/, '') + const d = (await fs.readFile(p, 'utf8')).replace(/^#!.*?\n/, '') await new Promise((res, rej) => { let done = false process.stdout.on('error', er => { diff --git a/lib/commands/search.js b/lib/commands/search.js index a06ba4031443b..8751e9e7d22fd 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -3,26 +3,33 @@ const Pipeline = require('minipass-pipeline') const libSearch = require('libnpmsearch') const log = require('../utils/log-shim.js') -const formatPackageStream = require('../search/format-package-stream.js') -const packageFilter = require('../search/package-filter.js') +const formatSearchStream = require('../utils/format-search-stream.js') + +function filter (data, include, exclude) { + const words = [data.name] + .concat(data.maintainers.map(m => `=${m.username}`)) + .concat(data.keywords || []) + .map(f => f && f.trim && f.trim()) + .filter(f => f) + .join(' ') + .toLowerCase() + + if (exclude.find(e => match(words, e))) { + return false + } -function prepareIncludes (args) { - return args - .map(s => s.toLowerCase()) - .filter(s => s) + return true } -function prepareExcludes (searchexclude) { - var exclude - if (typeof searchexclude === 'string') { - exclude = searchexclude.split(/\s+/) - } else { - exclude = [] +function match (words, pattern) { + if (pattern.startsWith('/')) { + if (pattern.endsWith('/')) { + pattern = pattern.slice(0, -1) + } + pattern = new RegExp(pattern.slice(1)) + return words.match(pattern) } - - return exclude - .map(s => s.toLowerCase()) - .filter(s => s) + return words.indexOf(pattern) !== -1 } const BaseCommand = require('../base-command.js') @@ -50,8 +57,8 @@ class Search extends BaseCommand { const opts = { ...this.npm.flatOptions, ...this.npm.flatOptions.search, - include: prepareIncludes(args), - exclude: prepareExcludes(this.npm.flatOptions.search.exclude), + include: args.map(s => s.toLowerCase()).filter(s => s), + exclude: this.npm.flatOptions.search.exclude.split(/\s+/), } if (opts.include.length === 0) { @@ -63,7 +70,7 @@ class Search extends BaseCommand { class FilterStream extends Minipass { write (pkg) { - if (packageFilter(pkg, opts.include, opts.exclude)) { + if (filter(pkg, opts.include, opts.exclude)) { super.write(pkg) } } @@ -73,7 +80,7 @@ class Search extends BaseCommand { // Grab a configured output stream that will spit out packages in the // desired format. - const outputStream = formatPackageStream({ + const outputStream = formatSearchStream({ args, // --searchinclude options are not highlighted ...opts, }) diff --git a/lib/commands/view.js b/lib/commands/view.js index 403d09d813dc7..d78ee77dc0a3d 100644 --- a/lib/commands/view.js +++ b/lib/commands/view.js @@ -57,9 +57,6 @@ class View extends BaseCommand { function getFields (d, f, pref) { f = f || [] - if (!d) { - return f - } pref = pref || [] Object.keys(d).forEach((k) => { if (k.charAt(0) === '_' || k.indexOf('.') !== -1) { diff --git a/lib/search/package-filter.js b/lib/search/package-filter.js deleted file mode 100644 index bb0ae679bdccd..0000000000000 --- a/lib/search/package-filter.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = filter -function filter (data, include, exclude, opts) { - return typeof data === 'object' && - filterWords(data, include, exclude, opts) -} - -function getWords (data, opts) { - return [data.name] - .concat((opts && opts.description) ? data.description : []) - .concat((data.maintainers || []).map(m => `=${m.name}`)) - .concat(data.versions && data.versions.length && data.url && ('<' + data.url + '>')) - .concat(data.keywords || []) - .map(f => f && f.trim && f.trim()) - .filter(f => f) - .join(' ') - .toLowerCase() -} - -function filterWords (data, include, exclude, opts) { - var words = getWords(data, opts) - for (var i = 0, l = include.length; i < l; i++) { - if (!match(words, include[i])) { - return false - } - } - - for (i = 0, l = exclude.length; i < l; i++) { - if (match(words, exclude[i])) { - return false - } - } - - return true -} - -function match (words, pattern) { - if (pattern.charAt(0) === '/') { - pattern = pattern.replace(/\/$/, '') - pattern = new RegExp(pattern.slice(1)) - return words.match(pattern) - } - return words.indexOf(pattern) !== -1 -} diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index 6f1b1a7244a50..a5eac8c826c84 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -1856,7 +1856,7 @@ define('searchexclude', { `, flatten (key, obj, flatOptions) { flatOptions.search = flatOptions.search || { limit: 20 } - flatOptions.search.exclude = obj[key] + flatOptions.search.exclude = obj[key].toLowerCase() }, }) diff --git a/lib/utils/file-exists.js b/lib/utils/file-exists.js deleted file mode 100644 index 605472536aab0..0000000000000 --- a/lib/utils/file-exists.js +++ /dev/null @@ -1,10 +0,0 @@ -const fs = require('fs') -const util = require('util') - -const stat = util.promisify(fs.stat) - -const fileExists = (file) => stat(file) - .then((stat) => stat.isFile()) - .catch(() => false) - -module.exports = fileExists diff --git a/lib/utils/format-bytes.js b/lib/utils/format-bytes.js index d7cf6d144e339..d293001df5524 100644 --- a/lib/utils/format-bytes.js +++ b/lib/utils/format-bytes.js @@ -23,6 +23,7 @@ const formatBytes = (bytes, space = true) => { return `${(bytes / 1000000).toFixed(1)}${spacer}MB` } + // GB return `${(bytes / 1000000000).toFixed(1)}${spacer}GB` } diff --git a/lib/search/format-package-stream.js b/lib/utils/format-search-stream.js similarity index 70% rename from lib/search/format-package-stream.js rename to lib/utils/format-search-stream.js index acead79e1a770..2a2dadd5c3434 100644 --- a/lib/search/format-package-stream.js +++ b/lib/utils/format-search-stream.js @@ -1,6 +1,3 @@ -// XXX these output classes should not live in here forever. it'd be good to -// split them out, perhaps to libnpmsearch - const Minipass = require('minipass') const columnify = require('columnify') @@ -18,32 +15,26 @@ const columnify = require('columnify') // The returned stream will format this package data // into a byte stream of formatted, displayable output. -module.exports = (opts = {}) => - opts.json ? new JSONOutputStream() : new TextOutputStream(opts) +module.exports = (opts) => { + return opts.json ? new JSONOutputStream() : new TextOutputStream(opts) +} class JSONOutputStream extends Minipass { - constructor () { - super() - this._didFirst = false - } + #didFirst = false write (obj) { - if (!this._didFirst) { + if (!this.#didFirst) { super.write('[\n') - this._didFirst = true + this.#didFirst = true } else { super.write('\n,\n') } - try { - return super.write(JSON.stringify(obj)) - } catch (er) { - return this.emit('error', er) - } + return super.write(JSON.stringify(obj)) } end () { - super.write(this._didFirst ? ']\n' : '\n[]\n') + super.write(this.#didFirst ? ']\n' : '\n[]\n') super.end() } } @@ -61,14 +52,11 @@ class TextOutputStream extends Minipass { } function prettify (data, num, opts) { - opts = opts || {} var truncate = !opts.long var pkg = normalizePackage(data, opts) - var columns = opts.description - ? ['name', 'description', 'author', 'date', 'version', 'keywords'] - : ['name', 'author', 'date', 'version', 'keywords'] + var columns = ['name', 'description', 'author', 'date', 'version', 'keywords'] if (opts.parseable) { return columns.map(function (col) { @@ -76,7 +64,10 @@ function prettify (data, num, opts) { }).join('\t') } - var output = columnify( + // stdout in tap is never a tty + /* istanbul ignore next */ + const maxWidth = process.stdout.isTTY ? process.stdout.getWindowSize()[0] : Infinity + let output = columnify( [pkg], { include: columns, @@ -92,8 +83,8 @@ function prettify (data, num, opts) { keywords: { maxWidth: Infinity }, }, } - ) - output = trimToMaxWidth(output) + ).split('\n').map(line => line.slice(0, maxWidth)).join('\n') + if (opts.color) { output = highlightSearchTerms(output, opts.args) } @@ -140,26 +131,6 @@ function colorize (line) { return line.split('\u0000').join(uncolor) } -function getMaxWidth () { - var cols - try { - var tty = require('tty') - var stdout = process.stdout - cols = !tty.isatty(stdout.fd) ? Infinity : process.stdout.getWindowSize()[0] - cols = (cols === 0) ? Infinity : cols - } catch (ex) { - cols = Infinity - } - return cols -} - -function trimToMaxWidth (str) { - var maxWidth = getMaxWidth() - return str.split('\n').map(function (line) { - return line.slice(0, maxWidth) - }).join('\n') -} - function highlightSearchTerms (str, terms) { terms.forEach(function (arg, i) { str = addColorMarker(str, arg, i) @@ -169,13 +140,10 @@ function highlightSearchTerms (str, terms) { } function normalizePackage (data, opts) { - opts = opts || {} return { name: data.name, - description: opts.description ? data.description : '', - author: (data.maintainers || []).map(function (m) { - return '=' + m.username - }).join(' '), + description: data.description, + author: data.maintainers.map((m) => `=${m.username}`).join(' '), keywords: Array.isArray(data.keywords) ? data.keywords.join(' ') : typeof data.keywords === 'string' diff --git a/lib/utils/read-package-name.js b/lib/utils/read-package-name.js deleted file mode 100644 index 7ed15987767bb..0000000000000 --- a/lib/utils/read-package-name.js +++ /dev/null @@ -1,9 +0,0 @@ -const { resolve } = require('path') -const readJson = require('read-package-json-fast') -async function readLocalPackageName (prefix) { - const filepath = resolve(prefix, 'package.json') - const json = await readJson(filepath) - return json.name -} - -module.exports = readLocalPackageName diff --git a/package.json b/package.json index d3e55ad623a43..687e9025fe7ac 100644 --- a/package.json +++ b/package.json @@ -230,8 +230,13 @@ ], "color": 1, "files": "test/{lib,bin,index.js}", - "coverage-map": "test/coverage-map.js", - "timeout": 600 + "timeout": 600, + "nyc-arg": [ + "--exclude", + "workspaces/**", + "--exclude", + "tap-snapshots/**" + ] }, "templateOSS": { "rootRepo": false, diff --git a/tap-snapshots/test/lib/commands/search.js.test.cjs b/tap-snapshots/test/lib/commands/search.js.test.cjs index 139fca25981ce..152e6605676e7 100644 --- a/tap-snapshots/test/lib/commands/search.js.test.cjs +++ b/tap-snapshots/test/lib/commands/search.js.test.cjs @@ -9,12 +9,130 @@ exports[`test/lib/commands/search.js TAP empty search results > should have expe No matches found for "foo" ` -exports[`test/lib/commands/search.js TAP search --searchexclude --searchopts > should have filtered expected search results 1`] = ` -NAME | AUTHOR | DATE | VERSION | KEYWORDS -foo | =foo | prehistoric | 1.0.0 | +exports[`test/lib/commands/search.js TAP search //--color > should have expected search results with color 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +libnpm | Collection of… | =nlf… | 2019-07-16 | 3.0.1 | npm api package manager lib +libnpmaccess | programmatic… | =nlf… | 2020-11-03 | 4.0.1 | libnpmaccess +@evocateur/libnpmaccess | programmatic… | =evocateur | 2019-07-16 | 3.1.2 | +@evocateur/libnpmpublish | Programmatic API… | =evocateur | 2019-07-16 | 1.2.2 | +libnpmorg | Programmatic api… | =nlf… | 2020-11-03 | 2.0.1 | libnpm npm package manager api orgs teams +libnpmsearch | Programmatic API… | =nlf… | 2020-12-08 | 3.1.0 | npm search api libnpm +libnpmteam | npm Team management… | =nlf… | 2020-11-03 | 2.0.2 | +libnpmhook | programmatic API… | =nlf… | 2020-11-03 | 6.0.1 | npm hooks registry npm api +libnpmpublish | Programmatic API… | =nlf… | 2020-11-03 | 4.0.0 | +libnpmfund | Programmatic API… | =nlf… | 2020-12-08 | 1.0.2 | npm npmcli libnpm cli git fund gitfund +@npmcli/map-workspaces | Retrieves a… | =nlf… | 2020-09-30 | 1.0.1 | npm npmcli libnpm cli workspaces map-workspaces +libnpmversion | library to do the… | =nlf… | 2020-11-04 | 1.0.7 | +@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | ` -exports[`test/lib/commands/search.js TAP search > should have expected search results 1`] = ` -NAME | AUTHOR | DATE | VERSION | KEYWORDS -libnpm | =nlf… | 2019-07-16 | 3.0.1 | npm api package manager liblibnpmaccess | =nlf… | 2020-11-03 | 4.0.1 | @evocateur/libnpmaccess | =evocateur | 2019-07-16 | 3.1.2 | @evocateur/libnpmpublish | =evocateur | 2019-07-16 | 1.2.2 | libnpmorg | =nlf… | 2020-11-03 | 2.0.1 | libnpm npm package manager api orgs teamslibnpmsearch | =nlf… | 2020-12-08 | 3.1.0 | npm search api libnpmlibnpmteam | =nlf… | 2020-11-03 | 2.0.2 | libnpmhook | =nlf… | 2020-11-03 | 6.0.1 | npm hooks registry npm apilibnpmpublish | =nlf… | 2020-11-03 | 4.0.0 | libnpmfund | =nlf… | 2020-12-08 | 1.0.2 | npm npmcli libnpm cli git fund gitfund@npmcli/map-workspaces | =nlf… | 2020-09-30 | 1.0.1 | npm npmcli libnpm cli workspaces map-workspaceslibnpmversion | =nlf… | 2020-11-04 | 1.0.7 | @types/libnpmsearch | =types | 2019-09-26 | 2.0.1 | +exports[`test/lib/commands/search.js TAP search --color > should have expected search results with color 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +libnpm | Collection of… | =nlf… | 2019-07-16 | 3.0.1 | npm api package manager lib +libnpmaccess | programmatic… | =nlf… | 2020-11-03 | 4.0.1 | libnpmaccess +@evocateur/libnpmaccess | programmatic… | =evocateur | 2019-07-16 | 3.1.2 |  +@evocateur/libnpmpublish | Programmatic API… | =evocateur | 2019-07-16 | 1.2.2 |  +libnpmorg | Programmatic api… | =nlf… | 2020-11-03 | 2.0.1 | libnpm npm package manager api orgs teams +libnpmsearch | Programmatic API… | =nlf… | 2020-12-08 | 3.1.0 | npm search api libnpm +libnpmteam | npm Team management… | =nlf… | 2020-11-03 | 2.0.2 |  +libnpmhook | programmatic API… | =nlf… | 2020-11-03 | 6.0.1 | npm hooks registry npm api +libnpmpublish | Programmatic API… | =nlf… | 2020-11-03 | 4.0.0 |  +libnpmfund | Programmatic API… | =nlf… | 2020-12-08 | 1.0.2 | npm npmcli libnpm cli git fund gitfund +@npmcli/map-workspaces | Retrieves a… | =nlf… | 2020-09-30 | 1.0.1 | npm npmcli libnpm cli workspaces map-workspaces +libnpmversion | library to do the… | =nlf… | 2020-11-04 | 1.0.7 |  +@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 |  +` + +exports[`test/lib/commands/search.js TAP search --parseable > should have expected search results as parseable 1`] = ` +libnpm Collection of programmatic APIs for the npm CLI =nlf =ruyadorno =darcyclarke =isaacs 2019-07-16 3.0.1 npm api package manager lib +libnpmaccess programmatic library for \`npm access\` commands =nlf =ruyadorno =darcyclarke =isaacs 2020-11-03 4.0.1 libnpmaccess +@evocateur/libnpmaccess programmatic library for \`npm access\` commands =evocateur 2019-07-16 3.1.2 +@evocateur/libnpmpublish Programmatic API for the bits behind npm publish and unpublish =evocateur 2019-07-16 1.2.2 +libnpmorg Programmatic api for \`npm org\` commands =nlf =ruyadorno =darcyclarke =isaacs 2020-11-03 2.0.1 libnpm npm package manager api orgs teams +libnpmsearch Programmatic API for searching in npm and compatible registries. =nlf =ruyadorno =darcyclarke =isaacs 2020-12-08 3.1.0 npm search api libnpm +libnpmteam npm Team management APIs =nlf =ruyadorno =darcyclarke =isaacs 2020-11-03 2.0.2 +libnpmhook programmatic API for managing npm registry hooks =nlf =ruyadorno =darcyclarke =isaacs 2020-11-03 6.0.1 npm hooks registry npm api +libnpmpublish Programmatic API for the bits behind npm publish and unpublish =nlf =ruyadorno =darcyclarke =isaacs 2020-11-03 4.0.0 +libnpmfund Programmatic API for npm fund =nlf =ruyadorno =darcyclarke =isaacs 2020-12-08 1.0.2 npm npmcli libnpm cli git fund gitfund +@npmcli/map-workspaces Retrieves a name:pathname Map for a given workspaces config =nlf =ruyadorno =darcyclarke =isaacs 2020-09-30 1.0.1 npm npmcli libnpm cli workspaces map-workspaces +libnpmversion library to do the things that 'npm version' does =nlf =ruyadorno =darcyclarke =isaacs 2020-11-04 1.0.7 +@types/libnpmsearch TypeScript definitions for libnpmsearch =types 2019-09-26 2.0.1 +` + +exports[`test/lib/commands/search.js TAP search > should have filtered expected search results 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +foo | | =foo | prehistoric | 1.0.0 | +libnpmversion | | =foo | prehistoric | 1.0.0 | +` + +exports[`test/lib/commands/search.js TAP search text > should have expected search results 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +libnpm | Collection of… | =nlf… | 2019-07-16 | 3.0.1 | npm api package manager lib +libnpmaccess | programmatic… | =nlf… | 2020-11-03 | 4.0.1 | libnpmaccess +@evocateur/libnpmaccess | programmatic… | =evocateur | 2019-07-16 | 3.1.2 | +@evocateur/libnpmpublish | Programmatic API… | =evocateur | 2019-07-16 | 1.2.2 | +libnpmorg | Programmatic api… | =nlf… | 2020-11-03 | 2.0.1 | libnpm npm package manager api orgs teams +libnpmsearch | Programmatic API… | =nlf… | 2020-12-08 | 3.1.0 | npm search api libnpm +libnpmteam | npm Team management… | =nlf… | 2020-11-03 | 2.0.2 | +libnpmhook | programmatic API… | =nlf… | 2020-11-03 | 6.0.1 | npm hooks registry npm api +libnpmpublish | Programmatic API… | =nlf… | 2020-11-03 | 4.0.0 | +libnpmfund | Programmatic API… | =nlf… | 2020-12-08 | 1.0.2 | npm npmcli libnpm cli git fund gitfund +@npmcli/map-workspaces | Retrieves a… | =nlf… | 2020-09-30 | 1.0.1 | npm npmcli libnpm cli workspaces map-workspaces +libnpmversion | library to do the… | =nlf… | 2020-11-04 | 1.0.7 | +@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | +` + +exports[`test/lib/commands/search.js TAP search exclude forward slash > results should not have libnpmversion 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +libnpm | Collection of… | =nlf… | 2019-07-16 | 3.0.1 | npm api package manager lib +libnpmaccess | programmatic… | =nlf… | 2020-11-03 | 4.0.1 | libnpmaccess +@evocateur/libnpmaccess | programmatic… | =evocateur | 2019-07-16 | 3.1.2 | +@evocateur/libnpmpublish | Programmatic API… | =evocateur | 2019-07-16 | 1.2.2 | +libnpmorg | Programmatic api… | =nlf… | 2020-11-03 | 2.0.1 | libnpm npm package manager api orgs teams +libnpmsearch | Programmatic API… | =nlf… | 2020-12-08 | 3.1.0 | npm search api libnpm +libnpmteam | npm Team management… | =nlf… | 2020-11-03 | 2.0.2 | +libnpmhook | programmatic API… | =nlf… | 2020-11-03 | 6.0.1 | npm hooks registry npm api +libnpmpublish | Programmatic API… | =nlf… | 2020-11-03 | 4.0.0 | +libnpmfund | Programmatic API… | =nlf… | 2020-12-08 | 1.0.2 | npm npmcli libnpm cli git fund gitfund +@npmcli/map-workspaces | Retrieves a… | =nlf… | 2020-09-30 | 1.0.1 | npm npmcli libnpm cli workspaces map-workspaces +@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | +` + +exports[`test/lib/commands/search.js TAP search exclude regex > results should not have libnpmversion 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +libnpm | Collection of… | =nlf… | 2019-07-16 | 3.0.1 | npm api package manager lib +libnpmaccess | programmatic… | =nlf… | 2020-11-03 | 4.0.1 | libnpmaccess +@evocateur/libnpmaccess | programmatic… | =evocateur | 2019-07-16 | 3.1.2 | +@evocateur/libnpmpublish | Programmatic API… | =evocateur | 2019-07-16 | 1.2.2 | +libnpmorg | Programmatic api… | =nlf… | 2020-11-03 | 2.0.1 | libnpm npm package manager api orgs teams +libnpmsearch | Programmatic API… | =nlf… | 2020-12-08 | 3.1.0 | npm search api libnpm +libnpmteam | npm Team management… | =nlf… | 2020-11-03 | 2.0.2 | +libnpmhook | programmatic API… | =nlf… | 2020-11-03 | 6.0.1 | npm hooks registry npm api +libnpmpublish | Programmatic API… | =nlf… | 2020-11-03 | 4.0.0 | +libnpmfund | Programmatic API… | =nlf… | 2020-12-08 | 1.0.2 | npm npmcli libnpm cli git fund gitfund +@npmcli/map-workspaces | Retrieves a… | =nlf… | 2020-09-30 | 1.0.1 | npm npmcli libnpm cli workspaces map-workspaces +@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | +` + +exports[`test/lib/commands/search.js TAP search exclude string > results should not have libnpmversion 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +libnpm | Collection of… | =nlf… | 2019-07-16 | 3.0.1 | npm api package manager lib +libnpmaccess | programmatic… | =nlf… | 2020-11-03 | 4.0.1 | libnpmaccess +@evocateur/libnpmaccess | programmatic… | =evocateur | 2019-07-16 | 3.1.2 | +@evocateur/libnpmpublish | Programmatic API… | =evocateur | 2019-07-16 | 1.2.2 | +libnpmorg | Programmatic api… | =nlf… | 2020-11-03 | 2.0.1 | libnpm npm package manager api orgs teams +libnpmsearch | Programmatic API… | =nlf… | 2020-12-08 | 3.1.0 | npm search api libnpm +libnpmteam | npm Team management… | =nlf… | 2020-11-03 | 2.0.2 | +libnpmhook | programmatic API… | =nlf… | 2020-11-03 | 6.0.1 | npm hooks registry npm api +libnpmpublish | Programmatic API… | =nlf… | 2020-11-03 | 4.0.0 | +libnpmfund | Programmatic API… | =nlf… | 2020-12-08 | 1.0.2 | npm npmcli libnpm cli git fund gitfund +@npmcli/map-workspaces | Retrieves a… | =nlf… | 2020-09-30 | 1.0.1 | npm npmcli libnpm cli workspaces map-workspaces +@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | +` + +exports[`test/lib/commands/search.js TAP search exclude username with upper case letters > results should not have nlf 1`] = ` +NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS +@evocateur/libnpmaccess | programmatic… | =evocateur | 2019-07-16 | 3.1.2 | +@evocateur/libnpmpublish | Programmatic API… | =evocateur | 2019-07-16 | 1.2.2 | +@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | ` diff --git a/tap-snapshots/test/lib/commands/view.js.test.cjs b/tap-snapshots/test/lib/commands/view.js.test.cjs index 5868e7b04babe..d5b7a3b4a7906 100644 --- a/tap-snapshots/test/lib/commands/view.js.test.cjs +++ b/tap-snapshots/test/lib/commands/view.js.test.cjs @@ -5,96 +5,102 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/commands/view.js TAP should log info by field name array field - 1 element > must match snapshot 1`] = ` +exports[`test/lib/commands/view.js TAP deprecated package with license, bugs, repository and other fields > must match snapshot 1`] = ` -claudia -` +green@1.0.0 | ACME | deps: 2 | versions: 2 +green is a very important color -exports[`test/lib/commands/view.js TAP should log info by field name array field - 2 elements > must match snapshot 1`] = ` +DEPRECATED!! - true -maintainers[0].name = 'claudia' -maintainers[1].name = 'isaacs' -` +keywords:,colors, green, crayola -exports[`test/lib/commands/view.js TAP should log info by field name maintainers with email > must match snapshot 1`] = ` +bin:,green -{ - "maintainers": [ - { - "name": "claudia", - "email": "c@yellow.com", - "twitter": "cyellow" - }, - { - "name": "isaacs", - "email": "i@yellow.com", - "twitter": "iyellow" - } - ], - "name": "yellow" -} -` +dist +.tarball:,http://hm.green.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1.0 GB + +dependencies: +red: 1.0.0 +yellow: 1.0.0 -exports[`test/lib/commands/view.js TAP should log info by field name maintainers with url > must match snapshot 1`] = ` +maintainers: +-,claudia <c@yellow.com> +-,isaacs <i@yellow.com> -[ - "claudia (http://c.pink.com)", - "isaacs (http://i.pink.com)" -] +dist-tags: +latest: 1.0.0 ` -exports[`test/lib/commands/view.js TAP should log info by field name nested field with brackets > must match snapshot 1`] = ` +exports[`test/lib/commands/view.js TAP deprecated package with unicode > must match snapshot 1`] = ` -"123" -` +green@1.0.0 | ACME | deps: 2 | versions: 2 +green is a very important color -exports[`test/lib/commands/view.js TAP should log info by field name readme > must match snapshot 1`] = ` +DEPRECATED ⚠️ - true -a very useful readme -` +keywords:,colors, green, crayola -exports[`test/lib/commands/view.js TAP should log info by field name several fields > must match snapshot 1`] = ` +bin:,green -{ - "name": "yellow", - "version": "1.0.0" -} -` +dist +.tarball:,http://hm.green.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1.0 GB + +dependencies: +red: 1.0.0 +yellow: 1.0.0 -exports[`test/lib/commands/view.js TAP should log info by field name several fields with several versions > must match snapshot 1`] = ` +maintainers: +-,claudia <c@yellow.com> +-,isaacs <i@yellow.com> -yellow@1.0.0 'claudia' -yellow@1.0.1 'claudia' -yellow@1.0.2 'claudia' +dist-tags: +latest: 1.0.0 ` -exports[`test/lib/commands/view.js TAP should log info of package in current working dir directory > must match snapshot 1`] = ` +exports[`test/lib/commands/view.js TAP package from git > must match snapshot 1`] = ` + +green@1.0.0 | ACME | deps: 2 | versions: 2 +green is a very important color + +DEPRECATED!! - true +keywords:,colors, green, crayola -blue@1.0.0 | Proprietary | deps: none | versions: 2 +bin:,green dist -.tarball:http://hm.blue.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.green.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1.0 GB + +dependencies: +red: 1.0.0 +yellow: 1.0.0 + +maintainers: +-,claudia <c@yellow.com> +-,isaacs <i@yellow.com> dist-tags: latest: 1.0.0 - -published {TIME} ago ` -exports[`test/lib/commands/view.js TAP should log info of package in current working dir non-specific version > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP package in cwd directory > 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 +.tarball:,http://hm.blue.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 @@ -102,16 +108,15 @@ dist-tags: published {TIME} ago ` -exports[`test/lib/commands/view.js TAP should log info of package in current working dir specific version > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP package in cwd non-specific version > 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 +.tarball:,http://hm.blue.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 @@ -119,38 +124,23 @@ dist-tags: published {TIME} ago ` -exports[`test/lib/commands/view.js TAP should log package info package from git > must match snapshot 1`] = ` - - -green@1.0.0 | ACME | deps: 2 | versions: 2 -green is a very important color - -DEPRECATED!! - true - -keywords:colors, green, crayola +exports[`test/lib/commands/view.js TAP package in cwd specific version > must match snapshot 1`] = ` -bin:green +blue@1.0.0 | Proprietary | deps: none | versions: 2 dist -.tarball:http://hm.green.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B - -dependencies: -red: 1.0.0 -yellow: 1.0.0 - -maintainers: --claudia <c@yellow.com> --isaacs <i@yellow.com> +.tarball:,http://hm.blue.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 -` -exports[`test/lib/commands/view.js TAP should log package info package with --json and semver range > must match snapshot 1`] = ` +published {TIME} ago +` +exports[`test/lib/commands/view.js TAP package with --json and semver range > must match snapshot 1`] = ` [ { "_npmUser": "claudia ", @@ -168,7 +158,7 @@ exports[`test/lib/commands/view.js TAP should log package info package with --js "tarball": "http://hm.cyan.com/1.0.0.tgz", "integrity": "---", "fileCount": 1, - "unpackedSize": 1 + "unpackedSize": 1000000 } }, { @@ -185,77 +175,44 @@ exports[`test/lib/commands/view.js TAP should log package info package with --js ] ` -exports[`test/lib/commands/view.js TAP should log package info package with homepage > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP package with homepage > must match snapshot 1`] = ` orange@1.0.0 | Proprietary | deps: none | versions: 2 http://hm.orange.com dist -.tarball:http://hm.orange.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B - -dist-tags: -latest: 1.0.0 -` - -exports[`test/lib/commands/view.js TAP should log package info package with license, bugs, repository and other fields > must match snapshot 1`] = ` - - -green@1.0.0 | ACME | deps: 2 | versions: 2 -green is a very important color - -DEPRECATED!! - true - -keywords:colors, green, crayola - -bin:green - -dist -.tarball:http://hm.green.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B - -dependencies: -red: 1.0.0 -yellow: 1.0.0 - -maintainers: --claudia <c@yellow.com> --isaacs <i@yellow.com> +.tarball:,http://hm.orange.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 ` -exports[`test/lib/commands/view.js TAP should log package info package with maintainers info as object > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP package with maintainers info as object > must match snapshot 1`] = ` pink@1.0.0 | Proprietary | deps: none | versions: 2 dist -.tarball:http://hm.pink.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.pink.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 ` -exports[`test/lib/commands/view.js TAP should log package info package with more than 25 deps > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP package with more than 25 deps > must match snapshot 1`] = ` black@1.0.0 | Proprietary | deps: 25 | versions: 2 dist -.tarball:http://hm.black.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.black.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dependencies: 0: 1.0.0 @@ -288,16 +245,15 @@ dist-tags: latest: 1.0.0 ` -exports[`test/lib/commands/view.js TAP should log package info package with no modified time > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP package with no modified time > must match snapshot 1`] = ` cyan@1.0.0 | Proprietary | deps: none | versions: 2 dist -.tarball:http://hm.cyan.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.cyan.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1.0 MB dist-tags: latest: 1.0.0 @@ -305,16 +261,15 @@ dist-tags: published by claudia <claudia@cyan.com> ` -exports[`test/lib/commands/view.js TAP should log package info package with no repo or homepage > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP package with no repo or homepage > 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 +.tarball:,http://hm.blue.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 @@ -322,16 +277,15 @@ dist-tags: published {TIME} ago ` -exports[`test/lib/commands/view.js TAP should log package info package with semver range > must match snapshot 1`] = ` - +exports[`test/lib/commands/view.js TAP 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 +.tarball:,http://hm.blue.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 @@ -341,10 +295,10 @@ published {TIME} ago blue@1.0.1 | Proprietary | deps: none | versions: 2 dist -.tarball:http://hm.blue.com/1.0.1.tgz -.shasum:124 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.blue.com/1.0.1.tgz +.shasum:,124 +.integrity:,--- +.unpackedSize:,1.0 kB dist-tags: latest: 1.0.0 @@ -352,8 +306,47 @@ dist-tags: published over a year from now ` -exports[`test/lib/commands/view.js TAP workspaces all workspaces --json > must match snapshot 1`] = ` +exports[`test/lib/commands/view.js TAP specific field names array field - 1 element > must match snapshot 1`] = ` +claudia +` + +exports[`test/lib/commands/view.js TAP specific field names array field - 2 elements > must match snapshot 1`] = ` +maintainers[0].name = 'claudia' +maintainers[1].name = 'isaacs' +` + +exports[`test/lib/commands/view.js TAP specific field names maintainers with email > must match snapshot 1`] = ` +maintainers = [ + { name: 'claudia', email: 'c@yellow.com', twitter: 'cyellow' }, + { name: 'isaacs', email: 'i@yellow.com', twitter: 'iyellow' } +] +name = 'yellow' +` + +exports[`test/lib/commands/view.js TAP specific field names maintainers with url > must match snapshot 1`] = ` +[ 'claudia (http://c.pink.com)', 'isaacs (http://i.pink.com)' ] +` + +exports[`test/lib/commands/view.js TAP specific field names nested field with brackets > must match snapshot 1`] = ` +123 +` + +exports[`test/lib/commands/view.js TAP specific field names readme > must match snapshot 1`] = ` +a very useful readme +` + +exports[`test/lib/commands/view.js TAP specific field names several fields > must match snapshot 1`] = ` +name = 'yellow' +version = '1.0.0' +` + +exports[`test/lib/commands/view.js TAP specific field names several fields with several versions > must match snapshot 1`] = ` +yellow@1.0.0 'claudia' +yellow@1.0.1 'claudia' +yellow@1.0.2 'claudia' +` +exports[`test/lib/commands/view.js TAP workspaces all workspaces --json > must match snapshot 1`] = ` { "green": { "_id": "green", @@ -406,7 +399,7 @@ exports[`test/lib/commands/view.js TAP workspaces all workspaces --json > must m "tarball": "http://hm.green.com/1.0.0.tgz", "integrity": "---", "fileCount": 1, - "unpackedSize": 1 + "unpackedSize": 1000000000 } }, "orange": { @@ -434,29 +427,28 @@ exports[`test/lib/commands/view.js TAP workspaces all workspaces --json > must m exports[`test/lib/commands/view.js TAP workspaces all workspaces > must match snapshot 1`] = ` - green@1.0.0 | ACME | deps: 2 | versions: 2 green is a very important color DEPRECATED!! - true -keywords:colors, green, crayola +keywords:,colors, green, crayola -bin:green +bin:,green dist -.tarball:http://hm.green.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.green.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1.0 GB dependencies: red: 1.0.0 yellow: 1.0.0 maintainers: --claudia <c@yellow.com> --isaacs <i@yellow.com> +-,claudia <c@yellow.com> +-,isaacs <i@yellow.com> dist-tags: latest: 1.0.0 @@ -465,10 +457,10 @@ dist-tags: http://hm.orange.com dist -.tarball:http://hm.orange.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.orange.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 @@ -479,13 +471,11 @@ exports[`test/lib/commands/view.js TAP workspaces all workspaces nonexistent fie ` exports[`test/lib/commands/view.js TAP workspaces all workspaces nonexistent field > must match snapshot 1`] = ` - green: orange: ` exports[`test/lib/commands/view.js TAP workspaces all workspaces single field --json > must match snapshot 1`] = ` - { "green": "green", "orange": "orange" @@ -493,7 +483,6 @@ exports[`test/lib/commands/view.js TAP workspaces all workspaces single field -- ` exports[`test/lib/commands/view.js TAP workspaces all workspaces single field > must match snapshot 1`] = ` - green: green orange: @@ -502,55 +491,56 @@ orange exports[`test/lib/commands/view.js TAP workspaces one specific workspace > must match snapshot 1`] = ` - green@1.0.0 | ACME | deps: 2 | versions: 2 green is a very important color DEPRECATED!! - true -keywords:colors, green, crayola +keywords:,colors, green, crayola -bin:green +bin:,green dist -.tarball:http://hm.green.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.green.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1.0 GB dependencies: red: 1.0.0 yellow: 1.0.0 maintainers: --claudia <c@yellow.com> --isaacs <i@yellow.com> +-,claudia <c@yellow.com> +-,isaacs <i@yellow.com> dist-tags: latest: 1.0.0 ` exports[`test/lib/commands/view.js TAP workspaces remote package name > must match snapshot 1`] = ` -Ignoring workspaces for specified package(s) -` - -exports[`test/lib/commands/view.js TAP workspaces remote package name > must match snapshot 2`] = ` - pink@1.0.0 | Proprietary | deps: none | versions: 2 dist -.tarball:http://hm.pink.com/1.0.0.tgz -.shasum:123 -.integrity:--- -.unpackedSize:1 B +.tarball:,http://hm.pink.com/1.0.0.tgz +.shasum:,123 +.integrity:,--- +.unpackedSize:,1 B dist-tags: latest: 1.0.0 ` -exports[`test/lib/commands/view.js TAP workspaces single workspace --json > must match snapshot 1`] = ` +exports[`test/lib/commands/view.js TAP workspaces remote package name > should have warning of ignoring workspaces 1`] = ` +Array [ + Array [ + "Ignoring workspaces for specified package(s)", + ], +] +` +exports[`test/lib/commands/view.js TAP workspaces single workspace --json > must match snapshot 1`] = ` { "green": { "_id": "green", @@ -603,7 +593,7 @@ exports[`test/lib/commands/view.js TAP workspaces single workspace --json > must "tarball": "http://hm.green.com/1.0.0.tgz", "integrity": "---", "fileCount": 1, - "unpackedSize": 1 + "unpackedSize": 1000000000 } } } diff --git a/test/coverage-map.js b/test/coverage-map.js deleted file mode 100644 index 9a289b6489e3e..0000000000000 --- a/test/coverage-map.js +++ /dev/null @@ -1,26 +0,0 @@ -const coverageMap = (filename) => { - const { basename } = require('path') - const testbase = basename(filename) - if (filename === 'test/index.js') { - return ['index.js'] - } - if (testbase === 'load-all-commands.js') { - const { cmdList } = require('../lib/utils/cmd-list.js') - return cmdList.map(cmd => `lib/${cmd}.js`) - .concat('lib/base-command.js') - } - if (/^test\/lib\/commands/.test(filename) || filename === 'test/lib/npm.js') { - return [ - filename.replace(/^test\//, ''), - 'lib/npm.js', - 'lib/base-command.js', - 'lib/exec/get-workspace-location-msg.js', - ] - } - if (/^test\/(lib|bin)\//.test(filename)) { - return filename.replace(/^test\//, '') - } - return [] -} - -module.exports = coverageMap diff --git a/test/fixtures/libnpmsearch-stream-result.js b/test/fixtures/libnpmsearch-stream-result.js index 4d3aca396fbca..b2ec20f59efeb 100644 --- a/test/fixtures/libnpmsearch-stream-result.js +++ b/test/fixtures/libnpmsearch-stream-result.js @@ -5,7 +5,7 @@ module.exports = [ version: '3.0.1', description: 'Collection of programmatic APIs for the npm CLI', keywords: ['npm', 'api', 'package manager', 'lib'], - date: new Date('2019-07-16T17:50:00.572Z'), + date: '2019-07-16T17:50:00.572Z', links: { npm: 'https://www.npmjs.com/package/libnpm', homepage: 'https://github.com/npm/libnpm#readme', @@ -26,7 +26,8 @@ module.exports = [ scope: 'unscoped', version: '4.0.1', description: 'programmatic library for `npm access` commands', - date: new Date('2020-11-03T19:19:00.526Z'), + keywords: 'libnpmaccess', + date: '2020-11-03T19:19:00.526Z', links: { npm: 'https://www.npmjs.com/package/libnpmaccess', homepage: 'https://npmjs.com/package/libnpmaccess', @@ -47,7 +48,7 @@ module.exports = [ scope: 'evocateur', version: '3.1.2', description: 'programmatic library for `npm access` commands', - date: new Date('2019-07-16T19:43:33.959Z'), + date: '2019-07-16T19:43:33.959Z', links: { npm: 'https://www.npmjs.com/package/%40evocateur%2Flibnpmaccess', homepage: 'https://npmjs.com/package/@evocateur/libnpmaccess', @@ -63,7 +64,7 @@ module.exports = [ scope: 'evocateur', version: '1.2.2', description: 'Programmatic API for the bits behind npm publish and unpublish', - date: new Date('2019-07-16T19:40:40.850Z'), + date: '2019-07-16T19:40:40.850Z', links: { npm: 'https://www.npmjs.com/package/%40evocateur%2Flibnpmpublish', homepage: 'https://npmjs.com/package/@evocateur/libnpmpublish', @@ -80,7 +81,7 @@ module.exports = [ version: '2.0.1', description: 'Programmatic api for `npm org` commands', keywords: ['libnpm', 'npm', 'package manager', 'api', 'orgs', 'teams'], - date: new Date('2020-11-03T19:21:57.757Z'), + date: '2020-11-03T19:21:57.757Z', links: { npm: 'https://www.npmjs.com/package/libnpmorg', homepage: 'https://npmjs.com/package/libnpmorg', @@ -102,7 +103,7 @@ module.exports = [ version: '3.1.0', description: 'Programmatic API for searching in npm and compatible registries.', keywords: ['npm', 'search', 'api', 'libnpm'], - date: new Date('2020-12-08T23:54:18.374Z'), + date: '2020-12-08T23:54:18.374Z', links: { npm: 'https://www.npmjs.com/package/libnpmsearch', homepage: 'https://npmjs.com/package/libnpmsearch', @@ -123,7 +124,7 @@ module.exports = [ scope: 'unscoped', version: '2.0.2', description: 'npm Team management APIs', - date: new Date('2020-11-03T19:24:42.380Z'), + date: '2020-11-03T19:24:42.380Z', links: { npm: 'https://www.npmjs.com/package/libnpmteam', homepage: 'https://npmjs.com/package/libnpmteam', @@ -145,7 +146,7 @@ module.exports = [ version: '6.0.1', description: 'programmatic API for managing npm registry hooks', keywords: ['npm', 'hooks', 'registry', 'npm api'], - date: new Date('2020-11-03T19:20:45.818Z'), + date: '2020-11-03T19:20:45.818Z', links: { npm: 'https://www.npmjs.com/package/libnpmhook', homepage: 'https://github.com/npm/libnpmhook#readme', @@ -166,7 +167,7 @@ module.exports = [ scope: 'unscoped', version: '4.0.0', description: 'Programmatic API for the bits behind npm publish and unpublish', - date: new Date('2020-11-03T19:13:43.780Z'), + date: '2020-11-03T19:13:43.780Z', links: { npm: 'https://www.npmjs.com/package/libnpmpublish', homepage: 'https://npmjs.com/package/libnpmpublish', @@ -193,7 +194,7 @@ module.exports = [ 'git', 'fund', 'gitfund', ], - date: new Date('2020-12-08T23:22:00.213Z'), + date: '2020-12-08T23:22:00.213Z', links: { npm: 'https://www.npmjs.com/package/libnpmfund', homepage: 'https://github.com/npm/libnpmfund#readme', @@ -222,7 +223,7 @@ module.exports = [ 'workspaces', 'map-workspaces', ], - date: new Date('2020-09-30T15:16:29.017Z'), + date: '2020-09-30T15:16:29.017Z', links: { npm: 'https://www.npmjs.com/package/%40npmcli%2Fmap-workspaces', homepage: 'https://github.com/npm/map-workspaces#readme', @@ -243,7 +244,7 @@ module.exports = [ scope: 'unscoped', version: '1.0.7', description: "library to do the things that 'npm version' does", - date: new Date('2020-11-04T00:21:41.069Z'), + date: '2020-11-04T00:21:41.069Z', links: { npm: 'https://www.npmjs.com/package/libnpmversion', homepage: 'https://github.com/npm/libnpmversion#readme', @@ -269,7 +270,7 @@ module.exports = [ scope: 'types', version: '2.0.1', description: 'TypeScript definitions for libnpmsearch', - date: new Date('2019-09-26T22:24:28.713Z'), + date: '2019-09-26T22:24:28.713Z', links: { npm: 'https://www.npmjs.com/package/%40types%2Flibnpmsearch' }, publisher: { username: 'types', email: 'ts-npm-types@microsoft.com' }, maintainers: [{ username: 'types', email: 'ts-npm-types@microsoft.com' }], diff --git a/test/fixtures/mock-registry.js b/test/fixtures/mock-registry.js index 5890fa7ee9366..01d43ba3d980b 100644 --- a/test/fixtures/mock-registry.js +++ b/test/fixtures/mock-registry.js @@ -46,6 +46,19 @@ class MockRegistry { this.#nock = nock } + search ({ responseCode = 200, results = [], error }) { + // the flags, score, and searchScore parts of the response are never used + // by npm, only package is used + const response = results.map(p => ({ package: p })) + this.nock = this.nock.get('/-/v1/search').query(true) + if (error) { + this.nock = this.nock.replyWithError(error) + } else { + this.nock = this.nock.reply(responseCode, { objects: response }) + } + return this.nock + } + whoami ({ username, body, responseCode = 200, times = 1 }) { if (username) { this.nock = this.nock.get('/-/whoami').times(times).reply(responseCode, { username }) diff --git a/test/lib/commands/search.js b/test/lib/commands/search.js index d2462b1aed4cc..f18fcc475a99c 100644 --- a/test/lib/commands/search.js +++ b/test/lib/commands/search.js @@ -1,169 +1,92 @@ const t = require('tap') -const Minipass = require('minipass') -const { fake: mockNpm } = require('../../fixtures/mock-npm') +const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') +const MockRegistry = require('../../fixtures/mock-registry.js') const libnpmsearchResultFixture = require('../../fixtures/libnpmsearch-stream-result.js') -let result = '' -const flatOptions = { - search: { - exclude: null, - limit: 20, - opts: '', - }, -} -const config = { - json: false, - parseable: false, -} -const npm = mockNpm({ - config, - flatOptions: { ...flatOptions }, - output: (...msg) => { - result += msg.join('\n') - }, -}) -const npmlog = { - silly () {}, - clearProgress () {}, -} -const libnpmsearch = { - stream () {}, -} -const mocks = { - npmlog, - libnpmsearch, -} - -t.afterEach(() => { - result = '' - config.json = false - config.parseable = false - npm.flatOptions = { ...flatOptions } -}) - -const Search = t.mock('../../../lib/commands/search.js', mocks) -const search = new Search(npm) - t.test('no args', async t => { + const { npm } = await loadMockNpm(t) await t.rejects( - search.exec([]), + npm.exec('search', []), /search must be called with arguments/, 'should throw usage instructions' ) }) -t.test('search ', async t => { - const src = new Minipass() - src.objectMode = true - const libnpmsearch = { - stream () { - return src - }, - } - - const Search = t.mock('../../../lib/commands/search.js', { - ...mocks, - libnpmsearch, +t.test('search text', async t => { + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - const search = new Search(npm) - for (const i of libnpmsearchResultFixture) { - src.write(i) - } - - src.end() - - await search.exec(['libnpm']) - t.matchSnapshot(result, 'should have expected search results') + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'should have expected search results') }) t.test('search --json', async 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/commands/search.js', { - ...mocks, - libnpmsearch, + const { npm, joinedOutput } = await loadMockNpm(t, { config: { json: true } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - const search = new Search(npm) - for (const i of libnpmsearchResultFixture) { - src.write(i) - } + registry.search({ results: libnpmsearchResultFixture }) - src.end() - await search.exec(['libnpm']) - - const parsedResult = JSON.parse(result) - parsedResult.forEach((entry) => { - entry.date = new Date(entry.date) - }) + await npm.exec('search', ['libnpm']) t.same( - parsedResult, + JSON.parse(joinedOutput()), libnpmsearchResultFixture, 'should have expected search results as json' ) +}) - config.json = false +t.test('search --parseable', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { parseable: true } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'should have expected search results as parseable') }) -t.test('search --json', async 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/commands/search.js', { - ...mocks, - libnpmsearch, +t.test('search --color', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { color: 'always' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - const search = new Search(npm) - src.end() - await search.exec(['foo']) + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'should have expected search results with color') +}) - t.equal(result, '\n[]\n', 'should have expected empty square brackets') +t.test('search //--color', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { color: 'always' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) - config.json = false + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['/libnpm/']) + t.matchSnapshot(joinedOutput(), 'should have expected search results with color') }) -t.test('search --searchexclude --searchopts', async t => { - npm.flatOptions.search = { - ...flatOptions.search, - exclude: '', - } - - const src = new Minipass() - src.objectMode = true - const libnpmsearch = { - stream () { - return src - }, - } - - const Search = t.mock('../../../lib/commands/search.js', { - ...mocks, - libnpmsearch, +t.test('search ', async t => { + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - const search = new Search(npm) - src.write({ + registry.search({ results: [{ name: 'foo', scope: 'unscoped', version: '1.0.0', @@ -175,8 +98,7 @@ t.test('search --searchexclude --searchopts', async t => { maintainers: [ { username: 'foo', email: 'foo@npmjs.com' }, ], - }) - src.write({ + }, { name: 'libnpmversion', scope: 'unscoped', version: '1.0.0', @@ -188,58 +110,100 @@ t.test('search --searchexclude --searchopts', async t => { maintainers: [ { username: 'foo', email: 'foo@npmjs.com' }, ], - }) + }] }) - src.end() - await search.exec(['foo']) + await npm.exec('search', ['foo']) - t.matchSnapshot(result, 'should have filtered expected search results') + t.matchSnapshot(joinedOutput(), 'should have filtered expected search results') }) t.test('empty search results', async t => { - const src = new Minipass() - src.objectMode = true - const libnpmsearch = { - stream () { - return src - }, - } - - const Search = t.mock('../../../lib/commands/search.js', { - ...mocks, - libnpmsearch, + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - const search = new Search(npm) - src.end() - await search.exec(['foo']) + registry.search({ results: [] }) + await npm.exec('search', ['foo']) - t.matchSnapshot(result, 'should have expected search results') + t.matchSnapshot(joinedOutput(), 'should have expected search results') }) -t.test('search api response error', async t => { - const src = new Minipass() - src.objectMode = true - const libnpmsearch = { - stream () { - return src - }, - } - - const Search = t.mock('../../../lib/commands/search.js', { - ...mocks, - libnpmsearch, +t.test('empty search results --json', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { json: true } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) - const search = new Search(npm) - setImmediate(() => { - src.emit('error', new Error('ERR')) - src.end() + registry.search({ results: [] }) + + await npm.exec('search', ['foo']) + t.equal(joinedOutput(), '\n[]\n', 'should have expected empty square brackets') +}) + +t.test('search api response error', async t => { + const { npm } = await loadMockNpm(t) + + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), }) + registry.search({ error: 'ERR' }) + await t.rejects( - search.exec(['foo']), + npm.exec('search', ['foo']), /ERR/, 'should throw response error' ) }) + +t.test('search exclude string', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { searchexclude: 'libnpmversion' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'results should not have libnpmversion') +}) + +t.test('search exclude username with upper case letters', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { searchexclude: 'NLF' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'results should not have nlf') +}) + +t.test('search exclude regex', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { searchexclude: '/version/' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'results should not have libnpmversion') +}) + +t.test('search exclude forward slash', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { searchexclude: '/version' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'results should not have libnpmversion') +}) diff --git a/test/lib/commands/view.js b/test/lib/commands/view.js index 82be1201ee169..da823db5d7507 100644 --- a/test/lib/commands/view.js +++ b/test/lib/commands/view.js @@ -1,4 +1,5 @@ const t = require('tap') +const { load: _loadMockNpm } = require('../../fixtures/mock-npm.js') t.cleanSnapshot = str => str .replace(/(published ).*?( ago)/g, '$1{TIME}$2') @@ -6,18 +7,6 @@ t.cleanSnapshot = str => str // run the same as tap does when running directly with node process.stdout.columns = undefined -const { fake: mockNpm } = require('../../fixtures/mock-npm') - -let logs -const cleanLogs = () => { - logs = '' - const fn = (...args) => { - logs += '\n' - args.map(el => logs += el) - } - console.log = fn -} - // 3 days. its never yesterday and never a week ago const yesterday = new Date(Date.now() - 1000 * 60 * 60 * 24 * 3) @@ -71,7 +60,7 @@ const packument = (nv, opts) => { tarball: 'http://hm.blue.com/1.0.1.tgz', integrity: '---', fileCount: 1, - unpackedSize: 1, + unpackedSize: 1000, }, }, }, @@ -94,7 +83,7 @@ const packument = (nv, opts) => { tarball: 'http://hm.cyan.com/1.0.0.tgz', integrity: '---', fileCount: 1, - unpackedSize: 1, + unpackedSize: 1000000, }, }, '1.0.1': {}, @@ -180,7 +169,7 @@ const packument = (nv, opts) => { tarball: 'http://hm.green.com/1.0.0.tgz', integrity: '---', fileCount: 1, - unpackedSize: 1, + unpackedSize: 1000000000, }, }, '1.0.1': {}, @@ -271,289 +260,212 @@ const packument = (nv, opts) => { return mocks[nv.name] } -t.beforeEach(cleanLogs) - -t.test('should log package info', async t => { - const View = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, - }) - const npm = mockNpm({ - config: { unicode: false }, - }) - const view = new View(npm) - - const ViewJson = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, +const loadMockNpm = async function (t, opts = {}) { + const consoleLogs = [] + const mockNpm = await _loadMockNpm(t, { + mocks: { + pacote: { + packument, + }, }, - }) - const jsonNpm = mockNpm({ - config: { - json: true, - tag: 'latest', + globals: { + 'console.log': (...args) => { + consoleLogs.push(args) + }, }, + ...opts, }) - const viewJson = new ViewJson(jsonNpm) + return { ...mockNpm, consoleLogs } +} - const ViewUnicode = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, - }) - const unicodeNpm = mockNpm({ - config: { unicode: true }, - }) - const viewUnicode = new ViewUnicode(unicodeNpm) +t.test('package from git', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['https://github.com/npm/green']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package from git', async t => { - await view.exec(['https://github.com/npm/green']) - t.matchSnapshot(logs) - }) +t.test('deprecated package with license, bugs, repository and other fields', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['green@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with license, bugs, repository and other fields', async t => { - await view.exec(['green@1.0.0']) - t.matchSnapshot(logs) - }) +t.test('deprecated package with unicode', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: true } }) + await npm.exec('view', ['green@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with more than 25 deps', async t => { - await view.exec(['black@1.0.0']) - t.matchSnapshot(logs) - }) +t.test('package with more than 25 deps', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['black@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with maintainers info as object', async t => { - await view.exec(['pink@1.0.0']) - t.matchSnapshot(logs) - }) +t.test('package with maintainers info as object', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['pink@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with homepage', async t => { - await view.exec(['orange@1.0.0']) - t.matchSnapshot(logs) - }) +t.test('package with homepage', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['orange@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with no versions', async t => { - await view.exec(['brown']) - t.equal(logs, '', 'no info to display') - }) +t.test('package with no versions', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['brown']) + t.equal(consoleLogs.join('\n'), '', 'no info to display') +}) - t.test('package with no repo or homepage', async t => { - await view.exec(['blue@1.0.0']) - t.matchSnapshot(logs) - }) +t.test('package with no repo or homepage', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['blue@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with semver range', async t => { - await view.exec(['blue@^1.0.0']) - t.matchSnapshot(logs) - }) +t.test('package with semver range', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['blue@^1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with no modified time', async t => { - await viewUnicode.exec(['cyan@1.0.0']) - t.matchSnapshot(logs) - }) +t.test('package with no modified time', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } }) + await npm.exec('view', ['cyan@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with --json and semver range', async t => { - await viewJson.exec(['cyan@^1.0.0']) - t.matchSnapshot(logs) - }) +t.test('package with --json and semver range', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { json: true } }) + await npm.exec('view', ['cyan@^1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) +}) - t.test('package with --json and no versions', async t => { - await viewJson.exec(['brown']) - t.equal(logs, '', 'no info to display') - }) +t.test('package with --json and no versions', async t => { + const { npm, consoleLogs } = await loadMockNpm(t, { config: { json: true } }) + await npm.exec('view', ['brown']) + t.equal(consoleLogs.join('\n'), '', 'no info to display') }) -t.test('should log info of package in current working dir', async t => { - const testDir = t.testdir({ +t.test('package in cwd', async t => { + const prefixDir = { 'package.json': JSON.stringify({ name: 'blue', version: '1.0.0', }, null, 2), - }) - - const View = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, - }) - const npm = mockNpm({ - prefix: testDir, - config: { - tag: '1.0.0', - }, - }) - const view = new View(npm) + } t.test('specific version', async t => { - await view.exec(['.@1.0.0']) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { prefixDir }) + await npm.exec('view', ['.@1.0.0']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('non-specific version', async t => { - await view.exec(['.']) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { prefixDir }) + await npm.exec('view', ['.']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('directory', async t => { - await view.exec(['./blue']) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { prefixDir }) + await npm.exec('view', ['./blue']) + t.matchSnapshot(consoleLogs.join('\n')) }) }) -t.test('should log info by field name', async t => { - const ViewJson = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, - }) - const jsonNpm = mockNpm({ - config: { - tag: 'latest', - json: true, - }, - }) - - const viewJson = new ViewJson(jsonNpm) - - const View = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, +t.test('specific field names', async t => { + const { npm, consoleLogs } = await loadMockNpm(t) + t.afterEach(() => { + consoleLogs.length = 0 }) - const npm = mockNpm() - const view = new View(npm) - t.test('readme', async t => { - await view.exec(['yellow@1.0.0', 'readme']) - t.matchSnapshot(logs) + await npm.exec('view', ['yellow@1.0.0', 'readme']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('several fields', async t => { - await viewJson.exec(['yellow@1.0.0', 'name', 'version', 'foo[bar]']) - t.matchSnapshot(logs) + await npm.exec('view', ['yellow@1.0.0', 'name', 'version', 'foo[bar]']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('several fields with several versions', async t => { - await view.exec(['yellow@1.x.x', 'author']) - t.matchSnapshot(logs) + await npm.exec('view', ['yellow@1.x.x', 'author']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('nested field with brackets', async t => { - await viewJson.exec(['orange@1.0.0', 'dist[shasum]']) - t.matchSnapshot(logs) + await npm.exec('view', ['orange@1.0.0', 'dist[shasum]']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('maintainers with email', async t => { - await viewJson.exec(['yellow@1.0.0', 'maintainers', 'name']) - t.matchSnapshot(logs) + await npm.exec('view', ['yellow@1.0.0', 'maintainers', 'name']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('maintainers with url', async t => { - await viewJson.exec(['pink@1.0.0', 'maintainers']) - t.matchSnapshot(logs) + await npm.exec('view', ['pink@1.0.0', 'maintainers']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('unknown nested field ', async t => { - await view.exec(['yellow@1.0.0', 'dist.foobar']) - t.equal(logs, '', 'no info to display') + await npm.exec('view', ['yellow@1.0.0', 'dist.foobar']) + t.equal(consoleLogs.join('\n'), '', 'no info to display') }) t.test('array field - 1 element', async t => { - await view.exec(['purple@1.0.0', 'maintainers.name']) - t.matchSnapshot(logs) + await npm.exec('view', ['purple@1.0.0', 'maintainers.name']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('array field - 2 elements', async t => { - await view.exec(['yellow@1.x.x', 'maintainers.name']) - t.matchSnapshot(logs) + await npm.exec('view', ['yellow@1.x.x', 'maintainers.name']) + t.matchSnapshot(consoleLogs.join('\n')) }) }) t.test('throw error if global mode', async t => { - const View = t.mock('../../../lib/commands/view.js') - const npm = mockNpm({ - config: { - global: true, - tag: 'latest', - }, - }) - const view = new View(npm) + const { npm } = await loadMockNpm(t, { config: { global: true } }) await t.rejects( - view.exec([]), + npm.exec('view', []), /Cannot use view command in global mode./ ) }) t.test('throw ENOENT error if package.json missing', async t => { - const testDir = t.testdir({}) - - const View = t.mock('../../../lib/commands/view.js') - const npm = mockNpm({ - prefix: testDir, - }) - const view = new View(npm) + const { npm } = await loadMockNpm(t) await t.rejects( - view.exec([]), + npm.exec('view', []), { code: 'ENOENT' } ) }) -t.test('throw EJSONPARSE error if package.json not json', async t => { - const testDir = t.testdir({ - 'package.json': 'not json, nope, not even a little bit!', - }) - - const View = t.mock('../../../lib/commands/view.js') - const npm = mockNpm({ - prefix: testDir, - }) - const view = new View(npm) - await t.rejects( - view.exec([]), - { code: 'EJSONPARSE' } - ) -}) - t.test('throw error if package.json has no name', async t => { - const testDir = t.testdir({ - 'package.json': '{}', - }) - - const View = t.mock('../../../lib/commands/view.js') - const npm = mockNpm({ - prefix: testDir, + const { npm } = await loadMockNpm(t, { + prefixDir: { + 'package.json': '{}', + }, }) - const view = new View(npm) await t.rejects( - view.exec([]), + npm.exec('view', []), /Invalid package.json, no "name" field/ ) }) t.test('throws when unpublished', async t => { - const View = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, - }) - const npm = mockNpm({ - config: { - tag: '1.0.1', - }, - }) - const view = new View(npm) + const { npm } = await loadMockNpm(t) await t.rejects( - view.exec(['red']), + npm.exec('view', ['red']), { code: 'E404', pkgid: 'red@1.0.1', message: 'Unpublished on 2012-12-20T00:00:00.000Z' } ) }) t.test('workspaces', async t => { - t.beforeEach(() => { - warnMsg = undefined - config.json = false - }) - const testDir = t.testdir({ + const prefixDir = { 'package.json': JSON.stringify({ name: 'workspaces-test-package', version: '1.2.3', @@ -571,106 +483,103 @@ t.test('workspaces', async t => { version: '1.2.3', }), }, - }) - const View = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, - 'proc-log': { - warn: (msg) => { - warnMsg = msg - }, - silly: () => {}, - }, - }) - const config = { - unicode: false, - tag: 'latest', } - let warnMsg - const npm = mockNpm({ - config, - localPrefix: testDir, - }) - const view = new View(npm) t.test('all workspaces', async t => { - await view.execWorkspaces([], []) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspaces: true }, + }) + await npm.exec('view', []) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('one specific workspace', async t => { - await view.execWorkspaces([], ['green']) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspace: ['green'] }, + }) + await npm.exec('view', []) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('all workspaces --json', async t => { - config.json = true - await view.execWorkspaces([], []) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspaces: true, json: true }, + }) + await npm.exec('view', []) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('all workspaces single field', async t => { - await view.execWorkspaces(['.', 'name'], []) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspaces: true }, + }) + await npm.exec('view', ['.', 'name']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('all workspaces nonexistent field', async t => { - await view.execWorkspaces(['.', 'foo'], []) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspaces: true }, + }) + await npm.exec('view', ['.', 'foo']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('all workspaces nonexistent field --json', async t => { - config.json = true - await view.execWorkspaces(['.', 'foo'], []) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspaces: true, json: true }, + }) + await npm.exec('view', ['.', 'foo']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('all workspaces single field --json', async t => { - config.json = true - await view.execWorkspaces(['.', 'name'], []) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspaces: true, json: true }, + }) + await npm.exec('view', ['.', 'name']) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('single workspace --json', async t => { - config.json = true - await view.execWorkspaces([], ['green']) - t.matchSnapshot(logs) + const { npm, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspace: ['green'], json: true }, + }) + await npm.exec('view', []) + t.matchSnapshot(consoleLogs.join('\n')) }) t.test('remote package name', async t => { - await view.execWorkspaces(['pink'], []) - t.matchSnapshot(warnMsg) - t.matchSnapshot(logs) + const { npm, logs, consoleLogs } = await loadMockNpm(t, { + prefixDir, + config: { unicode: false, workspaces: true }, + }) + await npm.exec('view', ['pink']) + t.matchSnapshot(consoleLogs.join('\n')) + t.matchSnapshot(logs.warn, 'should have warning of ignoring workspaces') }) }) t.test('completion', async t => { - const View = t.mock('../../../lib/commands/view.js', { - pacote: { - packument, - }, - }) - const npm = mockNpm({ - config: { - tag: '1.0.1', - }, - }) - const view = new View(npm) + const { npm } = await loadMockNpm(t) + const view = await npm.cmd('view') const res = await view.completion({ conf: { argv: { remain: ['npm', 'view', 'green@1.0.0'] } }, }) t.ok(res, 'returns back fields') }) -t.test('no registry completion', async t => { - const View = t.mock('../../../lib/commands/view.js') - const npm = mockNpm({ - config: { - tag: '1.0.1', - }, - }) - const view = new View(npm) +t.test('no package completion', async t => { + const { npm } = await loadMockNpm(t) + const view = await npm.cmd('view') const res = await view.completion({ conf: { argv: { remain: ['npm', 'view'] } } }) t.notOk(res, 'there is no package completion') t.end() diff --git a/test/lib/utils/config/definitions.js b/test/lib/utils/config/definitions.js index 088d0cdb6e128..200ee9e5536d1 100644 --- a/test/lib/utils/config/definitions.js +++ b/test/lib/utils/config/definitions.js @@ -457,6 +457,13 @@ t.test('retry options', t => { }) t.test('search options', t => { + const vals = { + description: 'test description', + exclude: 'test search exclude', + limit: 99, + staleneess: 99, + + } const obj = {} // : flat.search[